Skip to main content

Loggly

Version: 1.1.0

This library wraps the Loggly cloud-based logging service.

The Loggly class automatically adds metadata to your log messages, and handles efficently sending log messages with the Loggly Bulk Endpoint.

By default, the Loggly class will send log messages every 15 seconds, or when it has accumulated 100 log messages (whichever occurs first). The value of these parameters can be changed using the timeout and limit constructor options (see below).

You can view the library’s source code on GitHub. Click here to see information on the available versions of this library.

To add this library to your project, add #require "Loggly.class.nut:1.1.0" to the top of your agent code

Class Usage

Constructor: Loggly(customerToken, [options])

To create a new Loggly object you will need your customer token. You may also supply an optional table with any of the following keys to further configure the Loggly object:

Key Default Notes
id {agentId} A unique ID for the device/agent
tags electricimp A comma separated list of tags for all log events
timeout 15 Time between sends (in seconds)
limit 100 Maximum number of logs that will be queued before sending
debug true Enables/disables also posting log messages with server.log()

 
for example:

#require "Loggly.class.nut:1.1.0"

// Bulk-send logs every minute
loggly <- Loggly("<CUSTOMER_TOKEN>", { "timeout" : 60, "limit" : 50 });

Tags

Tags are a method of adding organization to your log events to aid in segmentation and filtering.

Tags can be used to form Source Groups, which will help segment your data and narrow down search results. It’s also possible to search your log data for tags with a search query.

For more information about tags, visit Loggly’s Support Center.

Class Logging Methods

There are three methods (representing three log levels) that can be used to log messages: log(), warn() and err(). When any of the logging methods are called, the following metadata is added to the message:

{ "id" : string,       // the id set in the constructor
  "level" : string,    // The log level (specified by what logging method was invoked)
  "timestamp" : string // An ISO 8601 timestamp
}

All three of the logging methods can be invoked in the following ways:

log/warn/err(table)

When a table is passed into one of the logging methods, each key/value pair will be added to the log message. If desired, the metadata can be overriden by including keys already present in the metadata, ie. id, level and timestamp.

In the following example, we send a message collected from the device and override the timestamp metadata with a device-side timestamp:

// Log information sent from the device
device.on("data", function(data) {
    loggly.log({
        "timestamp" : Loggly.ISODateTime(data.ts),
        "ssid" : data.ssid,
        "rssi" : data.rssi,
        "msg" : data.msg
    });
});

log/warn/err(string[, ...])

A string, or a format string with parameters, can also be passed into the logging methods. When a string or format string is passed into the logging methods, it will be added to the log message with a key of msg.

// Log a string...
loggly.log("Hello World!");

// Log a format string...
loggly.log("%s %s", "Hello", "World!");

log/warn/err(object)

Any other data type passed into logging methods will be cast as a string with the Squirrel tostring() method and added to the log message with a key of msg.

loggly.log(123.456);

Other Class Methods

len()

Returns the number of logs that are currently queued to send.

See onError(), below, for example usage.

onError(callback)

The onError handler allows you to attach an error handler (the callback) to the Loggly class. The error handler will be invoked if the Loggly class ever encounters an error while sending the logs to Loggly. The Loggly class will automatically retry sending the logs until successful.

The onError callback takes a single parameter: an HTTP Response table containing the keys statuscode, body and headers (see http.sendasync() for more information).

loggly <- Loggly("<CUSTOMER_TOKEN>");

loggly.onError(function(resp) {
    server.log("Failed to send messages to Loggly - " + resp.body);
    server.log(loggly.len() + " messages queued for next send.");
});

flush([callback])

The flush() method will immediatly send any queued message to the Loggly service. An optional callback can be passed to the flush() method that will be invoked upon completion of the request. Typical usage of the Loggly class should not involve calling flush().

An optional callback can be passed to the flush() method that will be invoked upon completion of the request. The callback method takes two parameters: error (a string describing the error) and response (an HTTP Response table). If the request was successful, the error parameter will be null.

function flushAndRestart(attempt = 0) {
    // If we've tried and failed 5 times, give up and restart
    if (attempt >= 5) server.restart();

    // Otherwise, try flushing the messages
    loggly.flush(function(error, response) {
        if (error != null) {
            // If it failed, try again in 10 seconds
            imp.wakeup(10, function() { flushAndRestart(attempt+1); });
            return;
        }

        // If we sent the logs, restart
        server.restart();
    });
}

Typical usage of the Loggly class should not involve calling flush(). However, when server.onshutdown() is implemented, it would be a good idea to flush logs before calling server.restart() method to initiate the reboot.

server.onshutdown(function(shutdownReasonCode) {
    // Log a shutdown message
    loggly.log({
        "msg" : "Shutting Down",
        "reason" : shutdownReasonCode
    });

    // Flush the messages
    loggly.flush();

    // Other shutdown code...

    server.restart();
});

Static Methods

Loggly.ISODateTime([timestamp])

The Loggly class has a static method that can generate an ISO 8601 datetime object. The ISODateTime method has an optional parameter timestamp — a Unix timestamp generated with time().

If an ISO 8601 datetime object is included with the key timestamp, it will override the system timestamp generated by the Loggly class. This is particulairly useful when logging data from the device:

// Device code

// Reads data, sends it to the agent, then goes to sleep for 1 hour
function SenseSendAndSleep() {
    // Sense the data
    local data = senseData();

    // Add a timestamp
    data.ts <- time();

    // Send the data
    agent.send("data", data);

    // Go to sleep
    imp.onidle(function() { server.sleepfor(3600); });
}
// Agent Code

device.on("data", function(data) {
    // grab and delete the timestamp
    local ts = delete data.ts;

    // Add an ISO Datetime object with the key "timestamp"
    data.timestamp <- Loggly.ISODateTime(ts);

    // Logs the data
    loggly.log(data);
});

Release History

The Electric Imp Dev Center documents the latest version of the library. For past versions, please see the Electric Imp public GitHub repos listed below.

Version Source Code Notes
1.0.0 GitHub Initial release
1.0.1 GitHub Bug fixes
1.1.0 GitHub Add optional callback to method flush()

License

The Loggly library is licensed under the MIT License.