Logger Module

API Docs for: 1.0.1
Show:

Readme

The module has three independent functional areas. It provides

1) Convenience methods to log messages and granular control over which messages are being logged.

2) Collection of log messages into files.

3) Reporting error conditions (exceptions and crashes).

You can take advantage of any one of these features, together or independently from each other.

To access this module from JavaScript, you would do the following:

var Logger = require('com.logicallabs.logcollector');
var dummy = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'dummy');
Note the line starting with "var dummy". On iOS, that line ensures that the Ti.Filesystem module (a standard part of the Titanium SDK) will be linked into the app. This is only necessary if the application doesn't otherwise reference the Ti.Filesystem module. The Logger module uses the Ti.Filesystem module so that it can return the same type of File object as what you get from Ti.Filesystem.getFile(). However, the build process of the application itself is not aware of this, so if the app does not have any references to Ti.Filesystem then, in an effort to decrease the app's footprint, the Ti.Filesystem module will not be linked into the app. This will result in a failure when the app is built.

Usage -- Logging

The basic logging function is Logger.log. It can take 1, 2, or 3 arguments as follows:

Logger.log('Message');
Logger.log(Logger.INFO, 'Message');
Logger.log(Logger.DEBUG, 'Group1', 'Message');

Here Logger.INFO and Logger.DEBUG are what we refer to as log-levels. The module provides a global logLevel property that allows you to limit the messages that are actually printed to a specific log level and above:

Logger.logLevel = Logger.INFO;

This will make sure that only INFO level messages or higher will be printed, DEBUG level messages won't. The priority of the log levels, in decreasing order, are as follows:

Logger.ERROR
Logger.WARNING
Logger.INFO
Logger.DEBUG
Logger.TRACE

The DEBUG level has further 9 sub-levels, from Logger.DEBUG1 to Logger.DEBUG9.

The module also provides convenience functions that have an implied log level. For example,

Logger.log(Logger.DEBUG, 'Group1', 'Message');

can be written as:

Logger.debug('Group1', 'Message');

When the log function is invoked with 3 parameters, the 2nd parameter ('Group1' in the above example) is an arbitrary string that we call the "group" of the message. Assigning the messages to groups allows another way to control which messages are printed, via the Logger.enableGroups function:

Logger.enableGroups('Group1', 'Group3');

This line would ensure that messages in Group1 and Group3 are printed, but other groups aren't. (Messages that are not assigned to a group are always printed, regardless of which groups are enabled).

The log function has an alternative form that takes a single object as a parameter. This makes it possible to specify a group without a log level:

Logger.log({
    msg: 'Message',
    group: 'Group1'
});

Usage -- Log Collection

To initiate log collection, that is the capturing of console messages into files, call the startLogCollection function. This will start the collection of log messages into a file. Use the getLogFileInfo function to get the details of the available log files.

Log collection happens periodically, by default every 10 seconds. This means that the log messages won't appear immediately in the current log file.

The Android logging system keeps four buffers for log messages:

1) main - main log buffer

2) events - contains events-related messages

3) radio - contains radio/telephony related messages

4) system - contains system messages

The module collects messages from each of these buffers into separate files.

It is generally a good idea to suspend log collection when the app is sent to the background. Call the stopLogCollection or pauseLogCollection function from the pause event listener appropriate for the platform to achieve this. The difference between stopping and pausing log collection is that stop/start creates a new (set of) log file(s), while pause/resume will keep using the previous one.

On Android, Titanium doesn't generate application-level pause and resume events. To be notified when an application is paused and resumed, you must add event listeners to its individual activities. The sample app included with this module creates a heavyweight window, which creates its own activity.

Usage -- Reporting Error Conditions

We can distinguish four types of error conditions:

1) Fatal signals (hard crashes).

2) Uncaught exceptions.

3) Exceptions caught by the Titanium framework.

4) Exceptions caught in JavaScript.

The Android version of the module handles uncaught exceptions, exceptions caught by the Titanium framework, and exceptions caught in JavaScript.

To initiate exception monitoring, that is the capturing of information related to uncaught exceptions and exceptions caught by the Titanium framework into files, call the startErrorMonitoring function. This will cause the exception information to be written into a file as soon as the exception happens.

To capture information related to an exception caught in JavaScript, call the logException from the try block with the JavaScript exception object.

Issues and Limitations

Fatal signals (hard crashes) are currently not handled by the Android version of the module.

Change Log

Version 1.0.0

  • First release

Version 1.0.1

  • Minor changes to sample app

Author

Zsombor Papp, Logical Labs

titanium@logicallabs.com

License

Logical Labs Commercial License

Copyright (c) 2012-2013 by Logical Labs, LLC