Skip to content

Commit 57cd20a

Browse files
simnvanuar45
andauthored
Windows eventlog input plugin (based on influxdata#7020) (influxdata#8000)
Co-authored-by: Anuar Serdaliyev <[email protected]>
1 parent 382dac7 commit 57cd20a

10 files changed

+1484
-0
lines changed

plugins/inputs/all/all.go

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ import (
177177
_ "github.com/influxdata/telegraf/plugins/inputs/varnish"
178178
_ "github.com/influxdata/telegraf/plugins/inputs/vsphere"
179179
_ "github.com/influxdata/telegraf/plugins/inputs/webhooks"
180+
_ "github.com/influxdata/telegraf/plugins/inputs/win_eventlog"
180181
_ "github.com/influxdata/telegraf/plugins/inputs/win_perf_counters"
181182
_ "github.com/influxdata/telegraf/plugins/inputs/win_services"
182183
_ "github.com/influxdata/telegraf/plugins/inputs/wireguard"

plugins/inputs/win_eventlog/README.md

+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Windows Eventlog Input Plugin
2+
3+
## Collect Windows Event Log messages
4+
5+
Supports Windows Vista and higher.
6+
7+
Telegraf should have Administrator permissions to subscribe for some of the Windows Events Channels, like System Log.
8+
9+
### Configuration
10+
11+
```toml
12+
## Telegraf should have Administrator permissions to subscribe for some Windows Events channels
13+
## (System log, for example)
14+
15+
## LCID (Locale ID) for event rendering
16+
## 1033 to force English language
17+
## 0 to use default Windows locale
18+
# locale = 0
19+
20+
## Name of eventlog, used only if xpath_query is empty
21+
## Example: "Application"
22+
# eventlog_name = ""
23+
24+
## xpath_query can be in defined short form like "Event/System[EventID=999]"
25+
## or you can form a XML Query. Refer to the Consuming Events article:
26+
## https://docs.microsoft.com/en-us/windows/win32/wes/consuming-events
27+
## XML query is the recommended form, because it is most flexible
28+
## You can create or debug XML Query by creating Custom View in Windows Event Viewer
29+
## and then copying resulting XML here
30+
xpath_query = '''
31+
<QueryList>
32+
<Query Id="0" Path="Security">
33+
<Select Path="Security">*</Select>
34+
<Suppress Path="Security">*[System[( (EventID &gt;= 5152 and EventID &lt;= 5158) or EventID=5379 or EventID=4672)]]</Suppress>
35+
</Query>
36+
<Query Id="1" Path="Application">
37+
<Select Path="Application">*[System[(Level &lt; 4)]]</Select>
38+
</Query>
39+
<Query Id="2" Path="Windows PowerShell">
40+
<Select Path="Windows PowerShell">*[System[(Level &lt; 4)]]</Select>
41+
</Query>
42+
<Query Id="3" Path="System">
43+
<Select Path="System">*</Select>
44+
</Query>
45+
<Query Id="4" Path="Setup">
46+
<Select Path="Setup">*</Select>
47+
</Query>
48+
</QueryList>
49+
'''
50+
51+
## System field names:
52+
## "Source", "EventID", "Version", "Level", "Task", "Opcode", "Keywords", "TimeCreated",
53+
## "EventRecordID", "ActivityID", "RelatedActivityID", "ProcessID", "ThreadID", "ProcessName",
54+
## "Channel", "Computer", "UserID", "UserName", "Message", "LevelText", "TaskText", "OpcodeText"
55+
56+
## In addition to System, Data fields can be unrolled from additional XML nodes in event.
57+
## Human-readable representation of those nodes is formatted into event Message field,
58+
## but XML is more machine-parsable
59+
60+
# Process UserData XML to fields, if this node exists in Event XML
61+
process_userdata = true
62+
63+
# Process EventData XML to fields, if this node exists in Event XML
64+
process_eventdata = true
65+
66+
## Separator character to use for unrolled XML Data field names
67+
separator = "_"
68+
69+
## Get only first line of Message field. For most events first line is usually more than enough
70+
only_first_line_of_message = true
71+
72+
## Fields to include as tags. Globbing supported ("Level*" for both "Level" and "LevelText")
73+
event_tags = ["Source", "EventID", "Level", "LevelText", "Task", "TaskText", "Opcode", "OpcodeText", "Keywords", "Channel", "Computer"]
74+
75+
## Default list of fields to send. All fields are sent by default. Globbing supported
76+
event_fields = ["*"]
77+
78+
## Fields to exclude. Also applied to data fields. Globbing supported
79+
exclude_fields = ["Binary", "Data_Address*"]
80+
81+
## Skip those tags or fields if their value is empty or equals to zero. Globbing supported
82+
exclude_empty = ["*ActivityID", "UserID"]
83+
```
84+
85+
### Filtering
86+
87+
There are three types of filtering: **Event Log** name, **XPath Query** and **XML Query**.
88+
89+
**Event Log** name filtering is simple:
90+
91+
```toml
92+
eventlog_name = "Application"
93+
xpath_query = '''
94+
```
95+
96+
For **XPath Query** filtering set the `xpath_query` value, and `eventlog_name` will be ignored:
97+
98+
```toml
99+
eventlog_name = ""
100+
xpath_query = "Event/System[EventID=999]"
101+
```
102+
103+
**XML Query** is the most flexible: you can Select or Suppress any values, and give ranges for other values. XML query is the recommended form, because it is most flexible. You can create or debug XML Query by creating Custom View in Windows Event Viewer and then copying resulting XML in config file.
104+
105+
XML Query documentation:
106+
107+
<https://docs.microsoft.com/en-us/windows/win32/wes/consuming-events>
108+
109+
### Metrics
110+
111+
You can send any field, *System*, *Computed* or *XML* as tag field. List of those fields is in the `event_tags` config array. Globbing is supported in this array, i.e. `Level*` for all fields beginning with `Level`, or `L?vel` for all fields where the name is `Level`, `L3vel`, `L@vel` and so on. Tag fields are converted to strings automatically.
112+
113+
By default, all other fields are sent, but you can limit that either by listing it in `event_fields` config array with globbing, or by adding some field name masks in the `exclude_fields` config array.
114+
115+
You can limit sending fields with empty values by adding masks of names of such fields in the `exclude_empty` config array. Value considered empty, if the System field of type `int` or `uint32` is equal to zero, or if any field of type `string` is an empty string.
116+
117+
List of System fields:
118+
119+
- Source (string)
120+
- EventID (int)
121+
- Version (int)
122+
- Level (int)
123+
- LevelText (string)
124+
- Opcode (int)
125+
- OpcodeText (string)
126+
- Task (int)
127+
- TaskText (string)
128+
- Keywords (string): comma-separated in case of multiple values
129+
- TimeCreated (string)
130+
- EventRecordID (string)
131+
- ActivityID (string)
132+
- RelatedActivityID (string)
133+
- ProcessID (int)
134+
- ThreadID (int)
135+
- ProcessName (string): derived from ProcessID
136+
- Channel (string)
137+
- Computer (string): useful if consumed from Forwarded Events
138+
- UserID (string): SID
139+
- UserName (string): derived from UserID, presented in form of DOMAIN\Username
140+
- Message (string)
141+
142+
### Computed fields
143+
144+
Fields `Level`, `Opcode` and `Task` are converted to text and saved as computed `*Text` fields.
145+
146+
`Keywords` field is converted from hex uint64 value by the `_EvtFormatMessage` WINAPI function. There can be more than one value, in that case they will be comma-separated. If keywords can't be converted (bad device driver or forwarded from another computer with unknown Event Channel), hex uint64 is saved as is.
147+
148+
`ProcessName` field is found by looking up ProcessID. Can be empty if telegraf doesn't have enough permissions.
149+
150+
`Username` field is found by looking up SID from UserID.
151+
152+
`Message` field is rendered from the event data, and can be several kilobytes of text with line breaks. For most events the first line of this text is more then enough, and additional info is more useful to be parsed as XML fields. So, for brevity, plugin takes only the first line. You can set `only_first_line_of_message` parameter to `false` to take full message text.
153+
154+
### Additional Fields
155+
156+
The content of **Event Data** and **User Data** XML Nodes can be added as additional fields, and is added by default. You can disable that by setting `process_userdata` or `process_eventdata` parameters to `false`.
157+
158+
For the fields from additional XML Nodes the `Name` attribute is taken as the name, and inner text is the value. Type of those fields is always string.
159+
160+
Name of the field is formed from XML Path by adding _ inbetween levels. For example, if UserData XML looks like this:
161+
162+
```xml
163+
<UserData>
164+
<CbsPackageChangeState xmlns="http://manifests.microsoft.com/win/2004/08/windows/setup_provider">
165+
<PackageIdentifier>KB4566782</PackageIdentifier>
166+
<IntendedPackageState>5112</IntendedPackageState>
167+
<IntendedPackageStateTextized>Installed</IntendedPackageStateTextized>
168+
<ErrorCode>0x0</ErrorCode>
169+
<Client>UpdateAgentLCU</Client>
170+
</CbsPackageChangeState>
171+
</UserData>
172+
```
173+
174+
It will be converted to following fields:
175+
176+
```text
177+
CbsPackageChangeState_PackageIdentifier = "KB4566782"
178+
CbsPackageChangeState_IntendedPackageState = "5112"
179+
CbsPackageChangeState_IntendedPackageStateTextized = "Installed"
180+
CbsPackageChangeState_ErrorCode = "0x0"
181+
CbsPackageChangeState_Client = "UpdateAgentLCU"
182+
```
183+
184+
If there are more than one field with the same name, all those fields are given suffix with number: `_1`, `_2` and so on.
185+
186+
### Localization
187+
188+
Human readable Event Description is in the Message field. But it is better to be skipped in favour of the Event XML values, because they are more machine-readable.
189+
190+
Keywords, LevelText, TaskText, OpcodeText and Message are saved with the current Windows locale by default. You can override this, for example, to English locale by setting `locale` config parameter to `1033`. Unfortunately, **Event Data** and **User Data** XML Nodes are in default Windows locale only.
191+
192+
Locale should be present on the computer. English locale is usually available on all localized versions of modern Windows. List of locales:
193+
194+
<https://docs.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a>
195+
196+
### Example Output
197+
198+
Some values are changed for anonymity.
199+
200+
```text
201+
win_eventlog,Channel=System,Computer=PC,EventID=105,Keywords=0x8000000000000000,Level=4,LevelText=Information,Opcode=10,OpcodeText=General,Source=WudfUsbccidDriver,Task=1,TaskText=Driver,host=PC ProcessName="WUDFHost.exe",UserName="NT AUTHORITY\\LOCAL SERVICE",Data_dwMaxCCIDMessageLength="271",Data_bPINSupport="0x0",Data_bMaxCCIDBusySlots="1",EventRecordID=1914688i,UserID="S-1-5-19",Version=0i,Data_bClassGetEnvelope="0x0",Data_wLcdLayout="0x0",Data_bClassGetResponse="0x0",TimeCreated="2020-08-21T08:43:26.7481077Z",Message="The Smartcard reader reported the following class descriptor (part 2)." 1597999410000000000
202+
203+
win_eventlog,Channel=Security,Computer=PC,EventID=4798,Keywords=Audit\ Success,Level=0,LevelText=Information,Opcode=0,OpcodeText=Info,Source=Microsoft-Windows-Security-Auditing,Task=13824,TaskText=User\ Account\ Management,host=PC Data_TargetDomainName="PC",Data_SubjectUserName="User",Data_CallerProcessId="0x3d5c",Data_SubjectLogonId="0x46d14f8d",Version=0i,EventRecordID=223157i,Message="A user's local group membership was enumerated.",Data_TargetUserName="User",Data_TargetSid="S-1-5-21-.-.-.-1001",Data_SubjectUserSid="S-1-5-21-.-.-.-1001",Data_CallerProcessName="C:\\Windows\\explorer.exe",ActivityID="{0d4cc11d-7099-0002-4dc1-4c0d9970d601}",UserID="",Data_SubjectDomainName="PC",TimeCreated="2020-08-21T08:43:27.3036771Z",ProcessName="lsass.exe" 1597999410000000000
204+
205+
win_eventlog,Channel=Microsoft-Windows-Dhcp-Client/Admin,Computer=PC,EventID=1002,Keywords=0x4000000000000001,Level=2,LevelText=Error,Opcode=76,OpcodeText=IpLeaseDenied,Source=Microsoft-Windows-Dhcp-Client,Task=3,TaskText=Address\ Configuration\ State\ Event,host=PC Version=0i,Message="The IP address lease 10.20.30.40 for the Network Card with network address 0xaabbccddeeff has been denied by the DHCP server 10.20.30.1 (The DHCP Server sent a DHCPNACK message).",UserID="S-1-5-19",Data_HWLength="6",Data_HWAddress="545595B7EA01",TimeCreated="2020-08-21T08:43:42.8265853Z",EventRecordID=34i,ProcessName="svchost.exe",UserName="NT AUTHORITY\\LOCAL SERVICE" 1597999430000000000
206+
207+
win_eventlog,Channel=System,Computer=PC,EventID=10016,Keywords=Classic,Level=3,LevelText=Warning,Opcode=0,OpcodeText=Info,Source=Microsoft-Windows-DistributedCOM,Task=0,host=PC Data_param3="Активация",Data_param6="PC",Data_param8="S-1-5-21-2007059868-50816014-3139024325-1001",Version=0i,UserName="PC\\User",Data_param1="по умолчанию для компьютера",Data_param2="Локально",Data_param7="User",Data_param9="LocalHost (с использованием LRPC)",Data_param10="Microsoft.Windows.ShellExperienceHost_10.0.19041.423_neutral_neutral_cw5n1h2txyewy",ActivityID="{839cac9e-73a1-4559-a847-62f3a5e73e44}",ProcessName="svchost.exe",Message="The по умолчанию для компьютера permission settings do not grant Локально Активация permission for the COM Server application with CLSID ",Data_param5="{316CDED5-E4AE-4B15-9113-7055D84DCC97}",Data_param11="S-1-15-2-.-.-.-.-.-.-2861478708",TimeCreated="2020-08-21T08:43:45.5233759Z",EventRecordID=1914689i,UserID="S-1-5-21-.-.-.-1001",Data_param4="{C2F03A33-21F5-47FA-B4BB-156362A2F239}" 1597999430000000000
208+
209+
```

plugins/inputs/win_eventlog/event.go

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//+build windows
2+
3+
//revive:disable-next-line:var-naming
4+
// Package win_eventlog Input plugin to collect Windows Event Log messages
5+
package win_eventlog
6+
7+
// Event is the event entry representation
8+
// Only the most common elements are processed, human-readable data is rendered in Message
9+
// More info on schema, if there will be need to add more:
10+
// https://docs.microsoft.com/en-us/windows/win32/wes/eventschema-elements
11+
type Event struct {
12+
Source Provider `xml:"System>Provider"`
13+
EventID int `xml:"System>EventID"`
14+
Version int `xml:"System>Version"`
15+
Level int `xml:"System>Level"`
16+
Task int `xml:"System>Task"`
17+
Opcode int `xml:"System>Opcode"`
18+
Keywords string `xml:"System>Keywords"`
19+
TimeCreated TimeCreated `xml:"System>TimeCreated"`
20+
EventRecordID int `xml:"System>EventRecordID"`
21+
Correlation Correlation `xml:"System>Correlation"`
22+
Execution Execution `xml:"System>Execution"`
23+
Channel string `xml:"System>Channel"`
24+
Computer string `xml:"System>Computer"`
25+
Security Security `xml:"System>Security"`
26+
UserData UserData `xml:"UserData"`
27+
EventData EventData `xml:"EventData"`
28+
Message string
29+
LevelText string
30+
TaskText string
31+
OpcodeText string
32+
}
33+
34+
// UserData Application-provided XML data
35+
type UserData struct {
36+
InnerXML []byte `xml:",innerxml"`
37+
}
38+
39+
// EventData Application-provided XML data
40+
type EventData struct {
41+
InnerXML []byte `xml:",innerxml"`
42+
}
43+
44+
// Provider is the Event provider information
45+
type Provider struct {
46+
Name string `xml:"Name,attr"`
47+
}
48+
49+
// Correlation is used for the event grouping
50+
type Correlation struct {
51+
ActivityID string `xml:"ActivityID,attr"`
52+
RelatedActivityID string `xml:"RelatedActivityID,attr"`
53+
}
54+
55+
// Execution Info for Event
56+
type Execution struct {
57+
ProcessID uint32 `xml:"ProcessID,attr"`
58+
ThreadID uint32 `xml:"ThreadID,attr"`
59+
ProcessName string
60+
}
61+
62+
// Security Data for Event
63+
type Security struct {
64+
UserID string `xml:"UserID,attr"`
65+
}
66+
67+
// TimeCreated field for Event
68+
type TimeCreated struct {
69+
SystemTime string `xml:"SystemTime,attr"`
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//+build windows
2+
3+
//revive:disable-next-line:var-naming
4+
// Package win_eventlog Input plugin to collect Windows Event Log messages
5+
package win_eventlog
6+
7+
import "syscall"
8+
9+
// Event log error codes.
10+
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
11+
const (
12+
//revive:disable:var-naming
13+
ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122
14+
ERROR_NO_MORE_ITEMS syscall.Errno = 259
15+
ERROR_INVALID_OPERATION syscall.Errno = 4317
16+
//revive:enable:var-naming
17+
)
18+
19+
// EvtSubscribeFlag defines the possible values that specify when to start subscribing to events.
20+
type EvtSubscribeFlag uint32
21+
22+
// EVT_SUBSCRIBE_FLAGS enumeration
23+
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa385588(v=vs.85).aspx
24+
const (
25+
EvtSubscribeToFutureEvents EvtSubscribeFlag = 1
26+
)
27+
28+
// EvtRenderFlag uint32
29+
type EvtRenderFlag uint32
30+
31+
// EVT_RENDER_FLAGS enumeration
32+
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa385563(v=vs.85).aspx
33+
const (
34+
//revive:disable:var-naming
35+
// Render the event as an XML string. For details on the contents of the
36+
// XML string, see the Event schema.
37+
EvtRenderEventXml EvtRenderFlag = 1
38+
//revive:enable:var-naming
39+
)

0 commit comments

Comments
 (0)