@@ -108,4 +108,83 @@ components: sources: windows_event_log: {
108108 }
109109 }
110110 }
111+
112+ how_it_works : {
113+ read_existing_events : {
114+ title : " Reading existing events "
115+ body : """
116+ With the default `read_existing_events = false`, the source has been observed to
117+ subscribe to all channels without error but never deliver an event and never
118+ write a checkpoint file, while new events were demonstrably being written to
119+ those channels. Nothing in Vector's own log points to the problem. See
120+ [issue #26117](\(urls .vector_issues )/26117).
121+
122+ Setting `read_existing_events = true` avoids this. The read position is
123+ persisted per channel in the data directory, so the existing backlog is read
124+ once on the first start and not again after a restart.
125+ """
126+ }
127+ query_complexity : {
128+ title : " Query complexity limit "
129+ body : """
130+ Windows rejects structured XPath queries whose boolean operators are nested too
131+ deeply. Such a query fails when the subscription is created, with
132+ `ERROR_EVT_INVALID_QUERY` (`0x80073A99`), the channel is skipped, and the source
133+ does not start. A flat `or` chain nests one level per operand: on Windows 11, a
134+ chain of 23 terms is accepted and a chain of 24 is rejected. A term may itself be
135+ a parenthesized group: a range such as `(EventID>=4720 and EventID<=4733)` adds
136+ one term to the chain plus one level for its `and`, so 22 ranges fit where 23
137+ single IDs do. Grouping only helps while the total nesting stays shallow; four
138+ groups of 20 IDs are accepted, five are not.
139+
140+ `only_event_ids` is currently translated into a flat chain with one `EventID=`
141+ comparison per listed ID, so a list of more than 23 IDs runs into this limit even
142+ though the configuration validates. Use `event_query` with ranges instead:
143+
144+ ```toml
145+ event_query = "*[System[(EventID=4624 or EventID=4625 or (EventID>=4720 and EventID<=4733))]]"
146+ ```
147+ """
148+ }
149+ one_source_per_channel : {
150+ title : " One source per channel "
151+ body : """
152+ Each channel is an exclusive resource within a configuration. Two
153+ `windows_event_log` sources that list the same channel fail at startup with
154+ ``Resource `disk buffer "Security"` is claimed by multiple components``. Splitting
155+ a channel across two sources, for example to work around the query complexity
156+ limit, is therefore not possible; combine the conditions into a single
157+ `event_query` instead.
158+ """
159+ }
160+ gelf_encoding : {
161+ title : " Encoding events as GELF "
162+ body : """
163+ Several fields of this source do not fit the GELF encoder, which rejects nested
164+ values and reserves the `level` and `version` fields:
165+
166+ * `event_data` and `user_data` are objects.
167+ * `string_inserts` and `keyword_names` are arrays.
168+ * `level` is a string (`"Error"`), while GELF expects a numeric syslog severity.
169+ * `version` is the event's integer version, while GELF reserves `version` for its
170+ own protocol version.
171+
172+ Such events fail to serialize at the sink and are dropped. A `remap` transform in
173+ front of the sink can make them valid:
174+
175+ ```coffee
176+ . = flatten!(., "_")
177+ . = map_values(.) -> |v| { if is_array(v) { encode_json(v) } else { v } }
178+ .win_level = del(.level)
179+ lvl = to_int(.level_value) ?? 4
180+ .level = if lvl == 1 { 2 } else if lvl == 2 { 3 } else if lvl == 3 { 4 } else { 6 }
181+ if exists(.version) { .win_version = del(.version) }
182+ ```
183+
184+ The values of `keyword_names` are rendered in the display language of the host
185+ (for example `Classic` or `Klassisch`), so filters should not depend on them. The
186+ `level` field is not localized.
187+ """
188+ }
189+ }
111190}
0 commit comments