Parsing multiline data in Sentinel

Gaurav Ramteke 1 Reputation point
2022-08-08T06:38:27.657+00:00

Hi,

We are getting data into LogAnalytics in following format;
One RaW logs has multiple lines in the log file and they repeat for each operations performed in the same log file

Reverse date time = 487930544  
Sequence number = 2147488705  
Component = BSS  
Security event = FALSE  
Event number = 2177  
Event name = Export Configuration Completed  
Event class = Software  
Event severity = Info  
Alarm event = FALSE  
Server name = System Management  
Function Name =   
Hostname = servername  
Browser Hostname =   
Browser Address =   
Operator = software_owner  
Session ID = a/dXlasjndlnojqpjorn[wkeokjwpeownokansdlk  
Date time = 03/08/22 22:54:08  
Alarm status = None  
Alarm distribution status = test_DIST_N_A  
Alarm date time = 01/01/70 00:00:00  
Alarm operator =   
Configuration change = FALSE  
Display text = Export Successfully Completed for entities: Operator. Total number of occurrence  
Length = 95  
Record version = 0  
Merged text = Export Successfully Completed for entities: Operator. Total number of occurrences exported: 24  

In the similar manner the lines will repeat itself for each of the activity in the same file

  1. How do we collate the above lines as one entry for a log
  2. Break the lines before "Reverse date time"
  3. Parse it as a Key = Value pairs meaning Rows and Colums
Microsoft Security | Microsoft Sentinel
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Alistair Ross 7,466 Reputation points Microsoft Employee
    2022-08-08T09:49:56.533+00:00

    Hi @Gaurav Ramteke

    I have two ways I can achieve this (I am sure I can do a few more, with things building the dynamic type by replacing strings). Both my examples provide two sets of events within a single record, and therefore using an arbitrary "Event Id" to denote the difference records. You may have different ids you wish to use to identify unique records. I've changed the reverse date time and sequence numbers to identify different activities within the same record.

    First way is by parsing the keys value pairs using the parse operator. This makes the assumption that all the keys are static and will always be provided. It allows the data to be typed easily while parsing. the \n forces the parse to check at the start of a new line, though may not be needed.

    print source =   
       
       Reverse date time = 487930544  
           Sequence number = 2147488705  
           Component = BSS  
           Security event = FALSE  
           Event number = 2177  
           Event name = Export Configuration Completed  
           Event class = Software  
           Event severity = Info  
           Alarm event = FALSE  
           Server name = System Management  
           Function Name =   
           Hostname = servername  
           Browser Hostname =   
           Browser Address =   
           Operator = software_owner  
           Session ID = a/dXlasjndlnojqpjorn[wkeokjwpeownokansdlk  
           Date time = 03/08/22 22:54:08  
           Alarm status = None  
           Alarm distribution status = test_DIST_N_A  
           Alarm date time = 01/01/70 00:00:00  
           Alarm operator =   
           Configuration change = FALSE  
           Display text = Export Successfully Completed for entities: Operator. Total number of occurrence  
           Length = 95  
           Record version = 0  
           Merged text = Export Successfully Completed for entities: Operator. Total number of occurrences exported: 24  
           Reverse date time = 487930545  
           Sequence number = 2147488706  
           Component = BSS  
           Security event = FALSE  
           Event number = 2177  
           Event name = Export Configuration Completed  
           Event class = Software  
           Event severity = Info  
           Alarm event = FALSE  
           Server name = System Management  
           Function Name =   
           Hostname = servername  
           Browser Hostname =   
           Browser Address =   
           Operator = software_owner  
           Session ID = a/dXlasjndlnojqpjorn[wkeokjwpeownokansdlk  
           Date time = 03/08/22 22:54:08  
           Alarm status = None  
           Alarm distribution status = test_DIST_N_A  
           Alarm date time = 01/01/70 00:00:00  
           Alarm operator =   
           Configuration change = FALSE  
           Display text = Export Successfully Completed for entities: Operator. Total number of occurrence  
           Length = 95  
           Record version = 0  
           Merged text = Export Successfully Completed for entities: Operator. Total number of occurrences exported: 24  
    
    | extend source = split(source, "Reverse date time = ")  
    | mv-expand source to typeof(string)   
    | where isnotempty(source)  
    | extend source = strcat("Reverse date time = ", source)  
    | parse source with  "Reverse date time = " ['Reverse date time']:long   
    "\nSequence number = " ['Sequence number']:long  
     "\nComponent = " Component:string  
     "\nSecurity event = " ['Security event']:bool  
     "\nEvent number = " ['Event number']:int  
     "\nEvent name = " ['Event name']:string  
     "\nEvent class = " ['Event class']:string  
     "\nEvent severity = " ['Event severity']:string  
     "\nAlarm event = " ['Alarm event']:bool  
     "\nServer name = " ['Server name']:string  
     "\nFunction Name = " ['Function Name']:string  
     "\nHostname = " Hostname:string  
     "\nBrowser Hostname = " ['Browser Hostname']:string  
     "\nBrowser Address = " ['Browser Address']:string  
     "\nOperator = " Operator:string  
     "\nSession ID = " ['Session ID']:string  
     "\nDate time = " ['Date time']:datetime   
     "\nAlarm status = " ['Alarm status']:string  
     "\nAlarm distribution status = " ['Alarm distribution status']:string  
     "\nAlarm date time = " ['Alarm date time']:datetime   
     "\nAlarm operator = " ['Alarm operator']:string  
     "\nConfiguration change = " ['Configuration change']:bool  
     "\nDisplay text = " ['Display text']:string  
     "\nLength = " Length:int  
     "\nRecord version = " ['Record version']:int  
     "\nMerged text = " ['Merged text']:string  
    | project-away source  
    

  2. Alistair Ross 7,466 Reputation points Microsoft Employee
    2022-08-08T09:56:02.897+00:00

    The second method (assuming the first answer has made it out of review, otherwise this is the first) makes the assumption that the keys may change and therefore you need to convert it to a JSON object and then unpack the object.

    print EventId = 1, source =   
       
       Reverse date time = 487930544  
            Sequence number = 2147488705  
            Component = BSS  
            Security event = FALSE  
            Event number = 2177  
            Event name = Export Configuration Completed  
            Event class = Software  
            Event severity = Info  
            Alarm event = FALSE  
            Server name = System Management  
            Function Name =   
            Hostname = servername  
            Browser Hostname =   
            Browser Address =   
            Operator = software_owner  
            Session ID = a/dXlasjndlnojqpjorn[wkeokjwpeownokansdlk  
            Date time = 03/08/22 22:54:08  
            Alarm status = None  
            Alarm distribution status = test_DIST_N_A  
            Alarm date time = 01/01/70 00:00:00  
            Alarm operator =   
            Configuration change = FALSE  
            Display text = Export Successfully Completed for entities: Operator. Total number of occurrence  
            Length = 95  
            Record version = 0  
            Merged text = Export Successfully Completed for entities: Operator. Total number of occurrences exported: 24  
            Reverse date time = 487930545  
            Sequence number = 2147488706  
            Component = BSS  
            Security event = FALSE  
            Event number = 2177  
            Event name = Export Configuration Completed  
            Event class = Software  
            Event severity = Info  
            Alarm event = FALSE  
            Server name = System Management  
            Function Name =   
            Hostname = servername  
            Browser Hostname =   
            Browser Address =   
            Operator = software_owner  
            Session ID = a/dXlasjndlnojqpjorn[wkeokjwpeownokansdlk  
            Date time = 03/08/22 22:54:08  
            Alarm status = None  
            Alarm distribution status = test_DIST_N_A  
            Alarm date time = 01/01/70 00:00:00  
            Alarm operator =   
            Configuration change = FALSE  
            Display text = Export Successfully Completed for entities: Operator. Total number of occurrence  
            Length = 95  
            Record version = 0  
            Merged text = Export Successfully Completed for entities: Operator. Total number of occurrences exported: 24  
    
    | extend source = split(source, "Reverse date time = ")  
    | mv-expand with_itemindex=EventIdIndex source to typeof(string)   
    | where isnotempty(source)  
    | extend source = strcat("Reverse date time = ", source)  
    | extend source = split(source,"\n")  
    | mv-expand source to typeof(string)  
    | extend source = split(source," = ")  
    | extend source = pack(tostring(source[0]),source[1])  
    | summarize source = make_bag(source) by EventIdIndex, EventId  
    | evaluate bag_unpack(source)  
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.