Formatted Logging For W3c

Problem this snippet solves:

Build a customized, compliant log message with this iRule that builds "properly" formatted log entries.

The first example uses High Speed Logging to send the message remotely while the second example uses the log command to log to the local filesystem.

Code :

# iRule Source for remote logging using HSL

# From: W3C Extended Log File Examples (IIS 6.0)
# http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/ffdd7079-47be-4277-921f-7a3a6e610dcb.mspx?mfr=true
#Fields: date time c-ip cs-username s-ip cs-method cs-uri-stem cs-uri-query sc-status sc-bytes cs-bytes time-taken cs-version cs(User-Agent) cs(Cookie) cs(Referrer) 
when CLIENT_ACCEPTED {

# Open a new high speed logging connection to the syslog pool named syslog_server_pool
set hsl [HSL::open -proto UDP -pool syslog_server_pool]
}
when HTTP_REQUEST priority 999 {
# Save request variables that are not accessible in HTTP_RESPONSE, like the URI, request method, etc
set req_start [clock clicks -milliseconds]
set cs_username [HTTP::username]
set cs_uri_stem [HTTP::path]
set cs_uri_query [HTTP::query]
set cs_bytes [HTTP::header Content-Length]
set ua [HTTP::header User-Agent]
set cookies [HTTP::header values Cookie]
set referer [HTTP::header Referer]
}
when HTTP_RESPONSE {

# Send the syslog message with a syslog facility of 134 (local0.info)
# See the HSL wiki page for details on the facilties:
# https://devcentral.f5.com/s/wiki/iRules.HSL__send.ashx
#
# Replace null values with a hyphen:
#Use string map to replace a "tab space tab" with "tab hyphen tab"
HSL::send $hsl "[string map [list "\t \t" "\t-\t"]\
"<134>\t\
[info hostname]\t\
[IP::local_addr]\t\
[clock format [clock seconds] -format "%d/%m/%Y %H:%M:%S %z"]\t\
[IP::client_addr]\t\
$cs_username\t\
[clientside {IP::local_addr}]\t\
$cs_uri_stem\t\
$cs_uri_query\t\
[HTTP::status]\t\
[HTTP::header Content-Length]\t\
[expr {[clock clicks -milliseconds] - $req_start}]\t\
[HTTP::version]\t\
\"$ua\"\t\
$cookies\t\
$referer\
"]\n"

}

# iRule Source for local logging

when HTTP_REQUEST {
   #
   # Save Request Side Information
   #
   set http_request "\"[HTTP::method] [HTTP::uri] HTTP/[HTTP::version]\""
   set http_request_time [clock clicks -milliseconds]
   set http_user_agent "\"[HTTP::header User-Agent]]\""
   set http_host [HTTP::host]
   set http_username [HTTP::username]
   set client_ip [IP::remote_addr]
   set client_port [TCP::remote_port]
   set http_request_uri [HTTP::uri]
   set referer [HTTP::header value referer]
}
when HTTP_RESPONSE {
   set response_time [expr [clock clicks -milliseconds] - $http_request_time]
   set virtual [virtual]
   set content_length 0
   if { [HTTP::header exists "Content-Length"] } {
      set content_length [HTTP::header "Content-Length"]
   }
   set lb_server "[LB::server addr]:[LB::server port]"
   if { [string compare "$lb_server" ""] == 0 } {
      set lb_server ""
   }
   set status_code [HTTP::status]
   set content_type [HTTP::header "Content-type"]
   set log_msg ""
   append log_msg "virtual=$virtual "
   append log_msg "client_ip=$client_ip "
   append log_msg "client_port=$client_port "
   append log_msg "lb_server=$lb_server "
   append log_msg "host=$http_host "
   append log_msg "username=$http_username "
   #append log_msg "$http_request_uri "
   append log_msg "request=$http_request "
   append log_msg "server_status=$status_code "
   #append log_msg "content_type=$content_type "
   append log_msg "content_length=$content_length "
   append log_msg "resp_time=$response_time "
   append log_msg "user_agent=$http_user_agent "
   append log_msg "referer=$referer"
#   log  local0. $log_msg
   log local0. $log_msg
}
Published Mar 17, 2015
Version 1.0
  • AndOs's avatar
    AndOs
    Icon for Cirrostratus rankCirrostratus
    There seems to be a slight typo in the second example. In event HTTP_REQUEST set http_user_agent "\"[HTTP::header User-Agent]]\"" should be set http_user_agent "\"[HTTP::header User-Agent]\""
  • Joe_M's avatar
    Joe_M
    Icon for Nimbostratus rankNimbostratus

    This iRule will run into this bug on certain code versions. See this SOL to work around the bug. https://support.f5.com/kb/en-us/solutions/public/14000/500/sol14505.html