Forum Discussion

winston_85158's avatar
winston_85158
Icon for Nimbostratus rankNimbostratus
Oct 16, 2014

Anyone using HSL with Graylog

Hi,

 

Is anyone using HSL in combination with Graylog (see http://www.graylog2.org/)? It is central logging server that is expecting UDP based messages in a JSON format (GELF).

 

I'm hoping for a working example ....

 

Regards,

 

Winston

 

8 Replies

  • AFAIK it should accept also standard syslog messages, not only GELF format. You should not have any strange problem to use it. What kind of example you need? graylog config or f5 hsl config?

     

  • make a tcpdump to see what irule send to graylog2, it could be a simple formatting mistake.

     

  • Try to add an \n at the end of the string to be sent. i.e.: .............me_env_var\":\"bar\"}\n"

     

  • I managed to get this working but forgot to share the result.

    The iRule below works and sends access log type of information to Graylog using HSL. Information is send in the GELF format (JSON string). The result is that one can create nice dashboards based on HTTP status codes, response times etc.

    when RULE_INIT {
      set static::graylog_pool udp_graylog]
    }
    
    when CLIENT_ACCEPTED {
      set hsl [HSL::open -proto UDP -pool $static::graylog_pool]
    }
    
    when HTTP_REQUEST {
      set startTime [clock clicks -milliseconds]
      set virtualHost [HTTP::host]
      set protocol [HTTP::header "X-Forwarded-Proto"]
      set xForwardedFor [HTTP::header "X-Forwarded-For"]
      set path [HTTP::path]
      set query [HTTP::query]
      set method [HTTP::method]
      set httpVersion [HTTP::version]
      set correlationId [HTTP::cookie "correlation_id"]
      set userAgent [regsub -all "\"" [HTTP::header "User-Agent"] "\\\""]
      if { [HTTP::header Content-Length] ne "" } then {
        set reqBytes [HTTP::header Content-Length]
      } else {
        set reqBytes 0
      }
      if { [HTTP::header "Referer"] ne "" } then {
        set referer [regsub -all "\"" [HTTP::header "Referer"] "\\\""]
      } else {
        set referer -
      }
    }
    
    when HTTP_RESPONSE {
      set endTime [clock clicks -milliseconds]
      set elapsed [expr {$endTime - $startTime}]
      set backend [IP::server_addr]:[TCP::server_port]
      set status [HTTP::status]
       if { [HTTP::header Content-Length] ne "" } then {
        set respBytes [HTTP::header Content-Length]
      } else {
        set respBytes 0
      }
      HSL::send $hsl "{\"version\": \"1.1\",\"host\":\"$virtualHost\",\"short_message\":\"$method $path $status\",\"level\":6,\"_facility\":\"F5_access_log\",\"_query\":\"$query\",\"_url\":\"$path\",\"_httpVersion\":\"$httpVersion\",\"_httpStatus\":$status,\"_method\":\"$method\",\"_protocol\":\"$protocol\",\"_referer\":\"$referer\",\"_userAgent\":\"$userAgent\",\"_x-forwarded-for\":\"$xForwardedFor\",\"_reqBytes\":$reqBytes,\"_respBytes\":$respBytes,\"_elapsed\":$elapsed,\"_correlationId\":\"$correlationId\"}"
    }
    
  • Do you have any good documented steps on how to setup the Graylog side? I am very new to this and curious to see where you started.

     

  • I use graylog extensively over the syslog format. I just use extractors to format the message fields during processing time. This lowers the CPU footprint on the BIG-IP side as well.

     

  • Hello winston, Do you have a few mins to chat about the data you are logging into Graylog? You can reach me at m.gadde@

     

  • Hi,

    Thank you for the example of GRAYLOG Json format.

    I just configured request logging instead of irule with HSL with following parameters:

    ltm profile request-log logging-GRAYLOG {
        app-service none
        defaults-from request-log
        response-log-pool POOL-GRAYLOG
        response-log-protocol mds-tcp
        response-log-template "{\"version\": \"1.1\", \"host\":\"$Host\", \"short_message\":\"$HTTP_REQUEST\", \"level\":6, \"facility\":\"F5_access_log\",  \"timestamp\": \"$TIME_UNIX\", \"_httpStatus\":\"$HTTP_STATUS\",  \"_userAgent\":\"${user-Agent}\", \"_clientIp\":\"$CLIENT_IP\", \"_user\":\"$User\", \"_respBytes\":\"$RESPONSE_SIZE\", \"_elapsed\":\"$RESPONSE_MSECS\"}"
        response-logging enabled
    }
    

    The log template is the following:

    {"version": "1.1", "host":"$Host", "short_message":"$HTTP_REQUEST", "level":6, "facility":"F5_access_log",  "timestamp": "$TIME_UNIX", "_httpStatus":"$HTTP_STATUS",  "_userAgent":"${user-Agent}", "_clientIp":"$CLIENT_IP", "_user":"$User", "_respBytes":"$RESPONSE_SIZE", "_elapsed":"$RESPONSE_MSECS"}
    

    User value is from following irule:

    when CLIENT_ACCEPTED {
        set APMusername ""
    }
    
    when ACCESS_ACL_ALLOWED {
        if {$APMusername equals ""} {
            set APMusername [ACCESS::session data get session.logon.last.username]
        }
        HTTP::header insert "USER" $APMusername
    }
    
    when HTTP_REQUEST_RELEASE {
        catch {HTTP::header remove "USER"}
    }
    

    with this log template, I was able to parse JSON content and filter requests by key value.