Monkey C In Application Logging
During the development of a Garmin IQ application in Monkey C we struggled to reconcile the applications behaviour in the watch emulator with the behaviour on an actual watch. What we needed was an on-watch logging mechanism essentially the same as System.println(). My co-author quickly knocked up this simple solution which we used extensively. It occurs to me that its not an obvious solution and others might benefit from seeing the possibility and the illustration..
Here ClientId.webLogUrl is sourced from a class of static constants. You can source that any way you like. To use this class follow this example:
This Monkey C code extract will create a single line text log at a URL where this PHP is implemented:
The log can then be views by the URL "https://domain.name/path/log". To reset the logs to zero length issue a single GET request to a URL with this PHP script.
The above example code shows a basic logging mechanism to see what is going on inside an application, but it can fail when called too frequently. The Communications.makeWebRequest() method takes a responseCallback parameter. When the logs are not sent, this can be because the responseCodeis not the desired 200 value for HTTP 200 OK. The value that I frequently saw was -101 for BLE_QUEUE_FULL indicating that too many requests had been queued. The solution to this is to group up the logs to be sent. The revised code to do that is given on GitHub.
The usage now changes as the same object must be used for all logs rather than creating a local logger and disposing. This will mean passing the same WebLog instance to all objects wanting to use it, and can get convoluted. The revised code will automatically flush the logs after a specified number of calls. That leaves any residual logs buffered and waiting for be 'flushed out' before quitting, e.g. in the Application.AppBase.onStop() method.
In this example, the first two debug messages are buffered and sent on the second call. The third call is buffered and not sent until the flush() method is called.Set the number of calls to buffer with the setCallsBuffer() method.
Conclusions
There are inevitable cautions to be expressed here about using such a logging facility to extract and send personal information. The source code is provided to the purposes of debugging, typically on one's own watch. Leaving this logging code in the published application would be cause for suspicion by users. Suspicion that can be mitigated by publishing the code under an Open Source licence agreement. But that is not itself proof the published application is from the indicated source code. Make sure all WebLog class usage is removed from the final implementation.