iRule procs (functions)

Problem this snippet solves:

If you have a large environment and lots of application services requiring lots of iRule logic it is likely you or someone at some point copies snippets of code from one iRule to another. Or may be you have a bit of logic you execute several times within an iRule so the code is again duplicated.


From a development point of view is this extremely bad practice but iRules (more the underlying TCL) has a solution procs.


You can write commonly shared iRule functionality into one or more iRules and call them from any other iRule.

How to use this snippet:

You can put a proc into any iRule, even one without a when event and use the call command to execute that proc.


As an example we are going to create an iRule named sharedLib with a proc:

  • getTime - this proc will return the GMT time in format HH:MM:SS.sss e.g. 15:23:03.342. Optional parameter of a time in milliseconds instead to current time

This will create a namespace within TCL of the iRule name, i.e. sharedLib, which we need to know to call the proc e.g. sharedLib::getTime


Then can create an iRule named logTimeDiff that calls the namespace and proc to log some times based on difference between TCP connection and HTTP requests.

Code :

ltm rule sharedLib {
    # Proc to return the current time including milliseconds
    #
    # @param timeInMilliseconds (optional) - time in milliseconds e.g. 1558615767836
    # @return string - GMT time in format HH:MM:SS.sss e.g. 15:23:03.342
    proc getTime {{timeInMilliseconds {}}} {
        if {($timeInMilliseconds eq "") || !([string is digit $timeInMilliseconds])} {
            set timeInMilliseconds [clock clicks -milliseconds]
        }
        set timeNoMilliseconds [expr {$timeInMilliseconds / 1000}]
        set justMilliseconds [expr {$timeInMilliseconds % 1000}]
        return "[clock format $timeNoMilliseconds -format "%H:%M:%S" -gmt true].[format {%03u} $justMilliseconds]"
    }
}

ltm rule logTimeDiff {
    when CLIENT_ACCEPTED {
        set tcpStart [clock clicks -milliseconds]
        log local0.info "TCP connection started at [call /Common/sharedLib::getTime $tcpStart] for IP [IP::client_addr]"
    }

    when HTTP_REQUEST {
        set httpStart  [clock clicks -milliseconds]
        set timeFromTcpStart [expr {$httpStart - $tcpStart}]
        log local0.info "HTTP Reqest at [call /Common/sharedLib::getTime $httpStart], time since TCP connect [call /Common/sharedLib::getTime $timeFromTcpStart]"
    }
}

Tested this on version:

12.1
Published May 23, 2019
Version 1.0
No CommentsBe the first to comment