iRules LX Logger Class

In version 13.1, the ILXLogger class was added to expand the ability to log from iRules LX. The API details have been added to to the wiki but in this article, I’ll add context and an example to boot. Let’s get to it!

The first step is to create a log publisher. For test purposes any destination for the publisher will do, so I’ll just choose local syslog for reach of the three publishers I’ll create here for the three tiers of logging you can do within iRules LX: the global level, the plugin level, and the extension level.

In the GUI, you can apply the plugin and extension publishers as shown in the two images below:

The log publishers can also be created via tmsh with the

sys log-config publisher
command. One you have a log publisher defined, you can also use tmsh to apply the publishers to any/all levels of your iRules LX environments.

# Global
tmsh modify ilx global-settings log-publisher ilx_global

# Plugin
tmsh modify ilx plugin a_plugin log-publisher ilx_plugin

# Extension
tmsh modify ilx plugin b_plugin extensions { b_extension { log-publisher ilx_extension } }

This works similar to profile parent/child inheritance, with some caveats.

Scenario #1

  • The global publisher is ilx_global
  • The plugin publisher is ilx_plugin
  • The extension publisher is ilx_extension

Result: Calling

logger.send()
will send to the ilx_extension publisher.

Scenario #2

  • The global publisher is ilx_global
  • The plugin publisher is ilx_plugin
  • The extension publisher is none

Result: Calling

logger.send()
will send to the ilx_plugin publisher.

Scenario #3

  • The global publisher is ilx_global
  • The plugin publisher is none
  • The extension publisher is ilx_extension

Result: Calling

logger.send()
will send to the ilx_extension publisher.

Scenario #4

  • The global publisher is ilx_global
  • The plugin publisher is none
  • The extension publisher is none

Result: Calling

logger.send()
will send to the ilx_global publisher.

Scenario #5

  • The global publisher is none
  • The plugin publisher is none
  • The extension publisher is none

Result: Calling

logger.send()
will cause an error as there is no configured publisher.

Note: You can alternatively use console.log() to send log data. If a global publisher is configured it will log there and if not it will log to /var/log/ltm by default.

Example

This is a bare bones example from Q&A posted by F5’s own Satoshi Toyosawa. I created an iRules LX Workspace (my workspace), an iRule (ilxtest), a plugin (ILXLOggerTestRpcPlugin), and an extension (ILXLoggerTestRpcExt). Configuration details for each:

The Workspace

ilx workspace myworkspace {
    extensions {
        ILXLoggerTestRpcExt {
            files {
                index.js { }
                node_modules { }
                package.json { }
            }
        }
    }
    node-version 6.9.1
    partition none
    rules {
        ilxtest { }
    }
    staged-directory /var/ilx/workspaces/Common/myworkspace
    version 14.0.0
}

The iRule

when HTTP_REQUEST {
  log local0. "I WANT THE TRUTH!"
  set RPC_HANDLE [ILX::init ILXLoggerTestRpcPlugin "ILXLoggerTestRpcExt"]
  ILX::call $RPC_HANDLE func
}

The Plugin

ilx plugin ILXLoggerTestRpcPlugin {
    extensions {
        ILXLoggerTestRpcExt {
            log-publisher ilx_extension
        }
    }
    from-workspace myworkspace
    log-publisher ilx_plugin
    node-version 6.9.1
    staged-directory /var/ilx/workspaces/Common/myworkspace
}

The Extension (all defaults except the updated index.js contents shown below)

var f5 = require('f5-nodejs');
var ilx = new f5.ILXServer();
var logger = new f5.ILXLogger();

ilx.addMethod('func', function(req, res) {
  logger.send('YOU CAN\'T HANDLE THE TRUTH!');
  res.reply('done');
});
ilx.listen();

Applying this iRules LX package against one of my test virtual servers with an HTTP profile, I anticipate Lt. Daniel Kaffee and Col. Nathan R. Jessup (From A Few Good Men) going at it in the log file:

Aug 30 19:33:20 ltm3 info sdmd[25253]: 018e0017:6: pid[35416]  plugin[/Common/ILXLoggerTestRpcPlugin.ILXLoggerTestRpcExt] YOU CAN'T HANDLE THE TRUTH!
Aug 30 19:33:20 ltm3 info tmm1[29992]: Rule /Common/ILXLoggerTestRpcPlugin/ilxtest : I WANT THE TRUTH!

Interesting that the node process dumps the log statement faster than Tcl, though that is not consistent and not guaranteed, as another run shows a different (and more appropriate according to the movie dialog) order:

Aug 30 22:47:35 ltm3 info tmm1[29992]: Rule /Common/ILXLoggerTestRpcPlugin/ilxtest : I WANT THE TRUTH!
Aug 30 22:47:35 ltm3 info sdmd[25253]: 018e0017:6: pid[35416]  plugin[/Common/ILXLoggerTestRpcPlugin.ILXLoggerTestRpcExt] YOU CAN'T HANDLE THE TRUTH!

This is by no means a thorough detour into the possibilities of your log publisher options with iRules LX on version 13.1+, but hopefully this gets you started with greater logging flexibility and if you are new to iRules LX, some sample code to play with. Happy coding!

Updated Jun 06, 2023
Version 2.0
  • Really good post and good to know HSL logging supported in iRules LX, thanks Jason, I’m curious though. HSL was built in TMM because it’s better at shifting packets in TMM than in the Linux kernel. As iRules LX runs in the control plane, are the HSL messages sent back over the RPC channel to TMM? Is there any significant overhead and how are messages handled that maybe processed asynchronously by node.js? Do they have a sequence number or something, otherwise messages risk arriving out of order. (Sorry for the long winded question... it’s friday night and clearly I should have better things to be doing!!)

     

  • HSL is definitely the way to go regardless of which tier you configure your log publisher on. My understanding is the logs are sent directly to host from the node process, not back to TMM.