# Logstash parse windows event nxlog

**URL:** <https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138>\
**Category:** Logstash\
**Created:** [April 25, 2022, 9:29am UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138 "2022-04-25T09:29:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chloe\_Boissavy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/chloe_boissavy/32/104593_2.png) [@Chloe\_Boissavy](https://discuss.elastic.co/u/Chloe_Boissavy)\
**Post date:** [April 25, 2022, 9:29am UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/1 "2022-04-25T09:29:42Z")

</div>

Hello,

I am using nxlog to send windows data at my ELK.  
I would like to parse the "message" part. An example below :

```auto
    "message": [
      "2022-04-25 10:54:13 - DESKTOP-QMCS5UA - Security - INFO - 4672 - Privilèges spéciaux attribués à la nouvelle ouverture de session. Sujet : ID de sécurité : S-1-5-18 Nom du compte : Système Domaine du compte : AUTORITE NT ID d’ouverture de session : 0x3E7 Privilèges : SeAssignPrimaryTokenPrivilege SeTcbPrivilege SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege SeSystemEnvironmentPrivilege SeImpersonatePrivilege SeDelegateSessionUserImpersonatePrivilege\r"
    ],

```

My nxlog configuration is that :

```auto
define ROOT C:\Program Files\nxlog
define CERTDIR %ROOT%\cert
define CONFDIR %ROOT%\conf
define LOGDIR %ROOT%\data
define LOGFILE %LOGDIR%\nxlog.log
define EVENT_SYS	1074, 41, 6006, 6008, 7036
define EVENT_SEC	4624, 4625, 4608, 4609, 4634, 4672, 4673, 4720, 4741, 4726, 4743, 4740, 4738, \
					4742, 4781, 4727, 4731, 4744, 4754, 4759, 4783, 4790, 4730, 4734, 4744, 4754, \
					4759, 4783, 4748, 4753, 4758, 4763, 4789, 4792, 4735, 4737, 4745, 4750, 4755, \
					4760, 4784, 4791, 4728, 4732, 4746, 4751, 4785, 4787, 4729, 4733, 4747, 4752, \
					4757, 4762, 4786, 4788, 4704, 4705
LogFile %LOGFILE%

Moduledir %ROOT%\modules
CacheDir %ROOT%\data
Pidfile %ROOT%\data\nxlog.pid
SpoolDir %ROOT%\data

<Extension _syslog>
    Module xm_syslog
</Extension>

<Extension _charconv>
    Module xm_charconv
    AutodetectCharsets iso8859-2, utf-8, utf-16, utf-32
</Extension>

<Extension _exec>
    Module xm_exec
</Extension>

<Extension _fileop>
    Module xm_fileop

    # Check the size of our log file hourly, rotate if larger than 5MB
    <Schedule>
        Every 1 hour
        Exec if (file_exists('%LOGFILE%') and \
                   (file_size('%LOGFILE%') >= 5M)) \
                    file_cycle('%LOGFILE%', 8);
    </Schedule>

    # Rotate our log file every week on Sunday at midnight
    <Schedule>
        When @weekly
        Exec if file_exists('%LOGFILE%') file_cycle('%LOGFILE%', 8);
    </Schedule>
</Extension>

# Snare compatible example configuration
# Collecting event log
 <Input in>
     Module im_msvistalog
	 <QueryXML>
		<QueryList>
			<Query Id='0'>
				<Select Path="Security">*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0)]]</Select>
				<Select Path="Application">*[System[(Level=1 or Level=2 or Level=3)]]</Select>
				<Select Path="System">*[System[(Level=1 or Level=2 or Level=3 or Level=4 or Level=0)]]</Select>
			</Query>
		</QueryList>
	</QueryXML>
	<Exec>
		$Sec = "Security";
		$Sys = "System";
		$Op = "Informations";
		if ($Channel == $Sys and $SeverityValue == 2 and ($EventID NOT IN (%EVENT_SYS%))) drop();
		if ($Channel == $Sec and $Opcode == $Op and ($EventID NOT IN (%EVENT_SEC%))) drop();
		if $Hostname =~ /(?x)^(\S+)\.(\S+)\.(\S+)/ {$Hostname = $1;}
		$Message_save = $Message;
		$Message_save =~ s/(\t|\R)/ /g;
		$raw_event = $EventTime + " - " + $Hostname + " - " + $Channel + " - " + $Severity + " - "+ $EventID + " - " + $Message_save;
	</Exec>
 </Input>

<Output out>
	Module om_tcp
	Host XX.XX.XX.XX
	Port XXXX
</Output>

# Connect input 'in' to output 'out'
 <Route 1>
     Path in => out
 </Route>

```

I can't change the nxlog configuration. I can just change logstash configuration.  
The logstash configuration is :

```auto
input{
 tcp{
   port => XXXX
   }
}
filter {
    mutate {
        gsub => ["message", "\t", ""]
    }
   kv{
       source => "message"
       value_split => ":"
       field_split => "\n"
   }
}
output {
    elasticsearch { hosts => ["XXXXXXX"]}
    stdout { codec => json }
}

```

But that doesn't work.

Can you help me ?

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 25, 2022, 6:03pm UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/2 "2022-04-25T18:03:31Z")

</div>

> [@Chloe\_Boissavy](#):
>
> ```auto
> "message": [
> "2022-04-25 10:54:13 - DESKTOP-QMCS5UA - Security - INFO - 4672 - Privilèges spéciaux attribués à la nouvelle ouverture de session. Sujet : ID de sécurité : S-1-5-18 Nom du compte : Système Domaine du compte : AUTORITE NT ID d’ouverture de session : 0x3E7 Privilèges : SeAssignPrimaryTokenPrivilege SeTcbPrivilege SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege SeSystemEnvironmentPrivilege SeImpersonatePrivilege SeDelegateSessionUserImpersonatePrivilege\r"
> ],
> 
> ```

Firstly, message is an array, so you should be configuring your kv filter with a source "[message][0]".

It is unclear why you would set field\_split to "\n". If your message really is delimited by newlines, as in

```
                     "event" => {
    "original" => "{ \"message\": [\"2022-04-25 10:54:13 - DESKTOP-QMCS5UA - Security - INFO - 4672 - Privilèges spéciaux attribués à la nouvelle ouverture de session. Sujet : \nID de sécurité : S-1-5-18 \nNom du compte : Système \nDomaine du compte : AUTORITE NT \nID d’ouverture de session : 0x3E7 \nPrivilèges : SeAssignPrimaryTokenPrivilege SeTcbPrivilege SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege SeSystemEnvironmentPrivilege SeImpersonatePrivilege SeDelegateSessionUserImpersonatePrivilege\\r\"] }"
},

```

then I would use

```
    mutate { gsub => ["message", "\n", ";"] }
    json { source => "message" }
    kv { source => "[message][0]" value_split => ":" field_split => ";" trim_value => "\s" }

```

which produces

```
             "2022-04-25 10" => "54:13 - DESKTOP-QMCS5UA - Security - INFO - 4672 - Privilèges spéciaux attribués à la nouvelle ouverture de session. Sujet :",
           "ID de sécurité " => "S-1-5-18",
"ID d’ouverture de session " => "0x3E7",
            "Nom du compte " => "Système",
               "Privilèges " => "SeAssignPrimaryTokenPrivilege SeTcbPrivilege SeSecurityPrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege SeBackupPrivilege SeRestorePrivilege SeDebugPrivilege SeAuditPrivilege SeSystemEnvironmentPrivilege SeImpersonatePrivilege SeDelegateSessionUserImpersonatePrivilege",
        "Domaine du compte " => "AUTORITE NT",

```

However, if it really is whitespace delimited as you show then I think a string in which both keys and values contain whitespace is too ambiguous for a kv filter to parse. Maybe grok?

---

<div class="post-metadata">

**Author:** ![Chloe\_Boissavy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/chloe_boissavy/32/104593_2.png) [@Chloe\_Boissavy](https://discuss.elastic.co/u/Chloe_Boissavy)\
**Post date:** [April 26, 2022, 10:50pm UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/3 "2022-04-26T22:50:09Z")

</div>

> [@Badger](#):
>
> ```auto
> mutate { gsub => ["message", "\n", ";"] }
> 
> ```

Hello,

Thanks for your answer.  
Indeed it's whitespace and not /n...  
I am not sure for how to use grok in my case.  
Moreover, I need to parse some event so it's not the same category for each.

I have try

```auto
filter{
 grok{
  match => ["message","%{LOGLEVEL:log_level}"]
 }
}

```

That's work I have the log level (INFO, Warning, ...) but I don't know how to continue that for each.

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 26, 2022, 11:13pm UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/4 "2022-04-26T23:13:50Z")

</div>

If you know what the field names are going to be then you could do something like [this](https://discuss.elastic.co/t/parse-mcafee-audit-log-file-with-logstash/302946/2). If the field names are unknown I do not think there is an unambiguous way to parse the message.

---

<div class="post-metadata">

**Author:** ![Chloe\_Boissavy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/chloe_boissavy/32/104593_2.png) [@Chloe\_Boissavy](https://discuss.elastic.co/u/Chloe_Boissavy)\
**Post date:** [April 29, 2022, 8:41am UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/5 "2022-04-29T08:41:46Z")

</div>

Hi Badger,

Thanks to your help.

I have tried this solution :

```auto
input {
 tcp {
  port => XXX
  }

filter {
 grok {
  break_on_match => false
  match => {
   "message" => [
    "Nom du compte%{SPACE}:%{SPACE}(?<Nom_Compte>)%{SPACE}"
    "Domaine du compte%{SPACE}:%{SPACE}(?<Domaine_Compte>)%{SPACE}"
    ]
   }
  }
 }

```

output {  
Elasticsearch { hosts =\> ["localhost:9200"] }  
}

But my event doesn't change in kibana. I have just grok error parse failure.

Do you know why ?  
Thanks a lot.

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 29, 2022, 5:21pm UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/6 "2022-04-29T17:21:10Z")

</div>

> [@Chloe\_Boissavy](#):
>
> `(?<Nom_Compte>)`

You have not included anything in the custom pattern. It does not match anything.

---

<div class="post-metadata">

**Author:** ![Chloe\_Boissavy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/chloe_boissavy/32/104593_2.png) [@Chloe\_Boissavy](https://discuss.elastic.co/u/Chloe_Boissavy)\
**Post date:** [May 4, 2022, 7:43am UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/7 "2022-05-04T07:43:51Z")

</div>

I don't understand.  
I need to specify each account name ?  
To me, (?\<Nom\_Compte\>) was here to specify any account name.

Thanks,

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [May 4, 2022, 2:52pm UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/8 "2022-05-04T14:52:15Z")

</div>

Read the [documentation](https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html#_custom_patterns) for custom patterns. \<Nom\_Compte\> names the pattern, but the pattern itself (everything between the `>` and the `)`) is empty. Perhaps (?\<Nom\_Compte\>[^]+) which will match one or more non-space characters.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [June 1, 2022, 2:52pm UTC](https://discuss.elastic.co/t/logstash-parse-windows-event-nxlog/303138/9 "2022-06-01T14:52:30Z")

</div>

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