Pipeline Rules w/ Regex

Good Afternoon:

I am attempting to enrich my linux logs that are sent to graylog via filebeat by way of sidecar. I configured rsyslog to also provide log level and facility as shown here:

6,3,Sep 21 15:48:26,pve,dotnet[3739400]:,Executed command: "AgentPackageHeartbeat" "eyJDb21tYW5kTmFtZSI6ImhlYXJ0YmVhdCJ9", commandId: 00000000-0000-0001-0003-000000000000

I would like to create a pipeline rule (or rules) that extracts the first character - the log level - and the third - the facility - and stores them as log_level and facility, respectively. From there, I would use the contents of these fields against a look up so that, for instance, I would end up with:

log_level
6
log_name
INFO
facility_number
3
facility_name
system_daemons

Here was my first attempt that did jack poop:

 rule "Extract Log Level"
when
  to_string($message.log_file_path) == "/var/log/syslog"
  OR to_string($message.log_file_path) == "/var/log/auth.log"
  OR to_string($message.log_file_path) == "/var/log/kern.log" 
  OR to_string($message.log_file_path) == "/var/log/mail.log"
  OR to_string($message.log_file_path) == "/var/log/cron.log"
then
  let LogLevel = regex(
  pattern: "(?<=^.{0}).{1}",
  value: to_string($message.message)
  );
end

And, honestly, I just frankensteined that from google-foo. I have little to no understanding of regex and pipelines.

So, as a secondary request, any recommendations to learn regex and pipeline logic? I prefer books (like Packt) to videos.

Thank you!

Hey @accidentaladmin

Filebeat should create those fields for you, also GELF works very well on separting those fields. That is unless its a unique message.

As for regx if your message looks something like this

devid="FGT60D343434344" logid="0001000014" type="traffic" subtype="local" level="notice" loglevel="6"

Then somehing like this should work.

rule "Extract  fields"
when
  has_field("message") 
then
  let log = regex("(loglevel=\\s*(\\S+))", to_string($message.message));
  set_field("log_level", log["0"]);
  debug (log); <------ For debug purposes only
end

As for create multiple fields I would suggest using Key_value if possible.
Example of mine for Fortinet Firewall

rule "forti_keys_to_fields"
when
    starts_with ((to_string($message.message)) , "type", true )
then
     // use $ tail -f /var/log/graylog-server/server.log to watch for the results of the below debug message
    debug(concat("++++++++++ Full Message: ", to_string($message.message))); 

    // extract all key-value from "message" and prefix it with auditd_
    set_fields(
        fields: key_value(
                    value: to_string($message.message),
                    trim_value_chars: "\"",
                    trim_key_chars:"",
                    delimiters:"|",
                    kv_delimiters:"="
                ),
        prefix: "forti_"
        );
end

hope that helps

1 Like

I quite agree; I am not sure why the syslog didn’t include Level and Facility. This is on a ProxMox rig which is based on Debian 12. Journald was enabled instead of syslog. I had to enable via rsyslog with the following config:

#################
#### MODULES ####
#################
module(load="imuxsock") # provides support for local system logging
module(load="imklog")   # provides kernel logging support
#module(load="immark")  # provides --MARK-- message capability

module(load="imjournal")
module(load="mmjsonparse")                                                                                                                                                                                                                                                                                                    

# provides UDP syslog reception                                                                                                                                
#module(load="imudp")                                                                                                                                          
#input(type="imudp" port="514")                                                                                                                                                                                                                                                                                               
# provides TCP syslog reception                                                                                                                                
#module(load="imtcp")                                                                                                                                          
#input(type="imtcp" port="514")                                                                                                                                                                                                                                                                                                                                                                                                                                                              

###########################                                                                                                                                    
#### GLOBAL DIRECTIVES ####                                                                                                                                    
###########################                                                                                                                                                                                                                                                                                                   

$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat                                                                                                       
$template precise,"%syslogpriority%,%syslogfacility%,%timegenerated%,%HOSTNAME%,%syslogtag%,%msg%\n"
$ActionFileDefaultTemplate precise                   

I’m at a loss

Oddly, my logs look like this:

6,3,Sep 21 15:48:26,pve,dotnet[3739400]:,Executed command: "AgentPackageHeartbeat" "eyJDb21tYW5kTmFtZSI6ImhlYXJ0YmVhdCJ9", commandId: 00000000-0000-0001-0003-000000000000

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.