Forum Discussion

Shrew's avatar
Shrew
Icon for Nimbostratus rankNimbostratus
Apr 18, 2023

iRule periodic logging

Hello,

I would like to use periodical logging using iRule.

Everything is working fine for me when just one session is opened using following simple iRule.

 

 

 

when CLIENT_ACCEPTED {

  after 10000 -periodic { log local0. "Time!!!" }

}

 

 

 

However when second session starts, second timer starts as well so I have double logging and so on with third session....

Is it possible somehow to have just one timer across all the sessions to use periodic logging just once?

5 Replies

  • No idea as I have not used those commands before, but I asked ChatGPT and this is what it came back with:

    The text you selected is an iRule that logs a message to the local0 facility every 10 seconds after a client connection is accepted. The message logged is "Time!!!". The iRule works fine when there is only one session. However, when multiple sessions are opened, multiple timers are started and logging occurs multiple times. It is not possible to have just one timer across all sessions to use periodic logging just once.

  • As far as i know, the only way to retrieve the same information across multiple iRule runs is using the "table" instruction to save it as a key:value pair in the session table ; then using "table lookup" to see if an entry already exists in the table for the given key during the next runs.

    https://clouddocs.f5.com/api/irules/table.html

    https://community.f5.com/t5/tag/series-the-table-command/tg-p?id=aBy1T000000k9qXSAQ

    This might be somewhat "overkill" for storing such an information however (: 

  • Hi Shew and welcome to Devcentral!

    iRules and their variables are scoped to a connection. When an iRule event is triggered, it is per connection unless the event uses something other than TCP as the underlying protocol. Events can set variables and subsequent events can read and update them but only within the scope of that connection. Once the connection is cleaned up by the platform so is the variable space it uses. Even if the backend connections are shared each variable space is unique to the incoming connection as this is where the connection starts. There is no persistant global variable space for iRules except except when defined in the RULE_INIT event. The key thing here is they dont share varable space. In order to preserve information outside a connection you need to use mechanisims that live outside the connection.

    Now what you want to do is trigger a timer and sure an iRule will do that but then so will every single connection. If you have 30 sessions all of which will start at different times they will trigger 10 seconds after when they started. As you can see, an ever shifting series of connections is not a good base for a ongong timer. There are ways to do it but the issue will be if the connections stop, the timer will stop. So let me ask you are question? What is the purpose of the timer. What are you wanting to know or to find out. What is the goal here and then we can more than likely come up with another way to achieve the outcome.

  • Shrew's avatar
    Shrew
    Icon for Nimbostratus rankNimbostratus

    Thank you all for the answers!

    Main goal of iRule is to monitor number of users logged into an appication and, if number exceed a limit, to block access for new users into application.

    iRule is working fine for me, but I have been requested to send periodically number of active users so we can set thresholds correctly and this was something I did not know how to do.

    I already solved problem thanks to CA_Valli idea altough I used tables in my iRule I did not think it can have such a simple solution (may not work correctly for low number of requests).

    if { [table lookup -notouch "timer_check"] != "Y" } {
            log local0. "Number of users: [table keys -subtable $tbl_conns -count]"
            table set "timer_check" "Y" 10
        }

    I set up value in table with timeout 10 and everytime value timeouted I send log message and set up value again. Worked correctly for me with about 50 requests per second, not tested for higher number yet.

     

    • Usually this information is fed into some monitoring system. Many of these poll for information. So you can setup a different kind of response on a reporting virtual server which the monitoring system can poll for the user information. I've used this to provide detailed staticstics about iRule solutions as a full HTML page or JSON output shown below.

       

      when HTTP_REQUEST {
        if {[HTTP::uri] starts_with "/monitor"} {
          response = "{ \"users\": [table keys -subtable $tbl_conns -count] }"
          HTTP::respond 200 content $response Content-Type "application/json; charset=UTF-8" Connection "Close"
        }
      }

       

      With the above attached to a virtual server 10.10.10.10:80 you can give the monitoring system http://10.10.10.10/monitor to get the JSON response below. Most monitoring systems can easily consume this.

       

      { "users": 10 }

       

      I hope that helps!