fluent-plugin-windows-eventlog 0.4.5 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +62 -2
- data/fluent-plugin-winevtlog.gemspec +2 -2
- data/lib/fluent/plugin/bookmark_sax_parser.rb +30 -0
- data/lib/fluent/plugin/in_windows_eventlog.rb +1 -0
- data/lib/fluent/plugin/in_windows_eventlog2.rb +87 -25
- data/test/helper.rb +1 -0
- data/test/plugin/test_bookmark_sax_parser.rb +41 -0
- data/test/plugin/test_in_windows_eventlog2.rb +165 -2
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f42851f147127453f0392e3e14ab31ed86983508c75453d9b41d2674441d8abc
|
4
|
+
data.tar.gz: fbfe63f1ee0034df3fd4346376b728b6728105b76130c82902768e67b4b5c1fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8326aa48c8661fcc9165e708db19ea3a4dd5ff0ec1407c35b7a6ef4db29fda70816eaba2c0a7b2e4e8c1255d47626b1330d8e1725c869e1ed7c5601e1681070
|
7
|
+
data.tar.gz: 22d9526b59591eca30044c625107a8aecc51c5e9b85448607450fec333e7630c44dccf4cc737539b5131d78bff1c2225f6ab0eb0f618832ffb06bc0b70c9ecd0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
# Release v0.5.3 - 2020/03/17
|
2
|
+
* in_windows_eventlog2: Add Qualifiers key handling options
|
3
|
+
|
4
|
+
# Release v0.5.2 - 2020/02/28
|
5
|
+
* in_windows_eventlog2: Add parameter to read from all channels shortcut
|
6
|
+
|
7
|
+
# Release v0.5.1 - 2020/02/26
|
8
|
+
* in_windows_eventlog2: Add empty bookmark checking mechanism
|
9
|
+
|
10
|
+
# Release v0.5.0 - 2020/02/17
|
11
|
+
* in_windows_eventlog2: Support subscribe directive to handle read_existing_events paratemer each of channels.
|
12
|
+
* in_windows_eventlog2: Depends on winevt_c v0.7.0 or later.
|
13
|
+
|
14
|
+
# Release v0.4.6 - 2020/02/15
|
15
|
+
* Fix winevt_c dependency to prevent fetching winevt_c v0.7.0 or later.
|
16
|
+
|
1
17
|
# Release v0.4.5 - 2020/01/28
|
2
18
|
* in_windows_eventlog2: Handle empty key case in parsing description method.
|
3
19
|
|
data/README.md
CHANGED
@@ -135,11 +135,13 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
|
|
135
135
|
<source>
|
136
136
|
@type windows_eventlog2
|
137
137
|
@id windows_eventlog2
|
138
|
-
channels application,system
|
138
|
+
channels application,system # Also be able to use `<subscribe>` directive.
|
139
|
+
read_existing_events false
|
139
140
|
read_interval 2
|
140
141
|
tag winevt.raw
|
141
142
|
render_as_xml false # default is true.
|
142
143
|
rate_limit 200 # default is -1(Winevt::EventLog::Subscribe::RATE_INFINITE).
|
144
|
+
# preserve_qualifiers_on_hash true # default is false.
|
143
145
|
<storage>
|
144
146
|
@type local # @type local is the default.
|
145
147
|
persistent true # default is true. Set to false to use in-memory storage.
|
@@ -148,7 +150,16 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
|
|
148
150
|
</storage>
|
149
151
|
<parse>
|
150
152
|
@type winevt_xml # @type winevt_xml is the default. winevt_xml and none parsers are supported for now.
|
153
|
+
# When set up it as true, this plugin preserves "Qualifiers" and "EventID" keys.
|
154
|
+
# When set up it as false, this plugin calculates actual "EventID" from "Qualifiers" and removing "Qualifiers".
|
155
|
+
# With the following equation:
|
156
|
+
# (EventID & 0xffff) | (Qualifiers & 0xffff) << 16
|
157
|
+
preserve_qualifiers true
|
151
158
|
</parse>
|
159
|
+
# <subscribe>
|
160
|
+
# channles application, system
|
161
|
+
# read_existing_events false # read_existing_events should be applied each of subscribe directive(s)
|
162
|
+
# </subscribe>
|
152
163
|
</source>
|
153
164
|
|
154
165
|
**NOTE:** in_windows_eventlog2 always handles EventLog records as UTF-8 characters. Users don't have to specify encoding related parameters and they are not provided.
|
@@ -163,13 +174,62 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
|
|
163
174
|
|
164
175
|
|name | description |
|
165
176
|
|:----- |:----- |
|
166
|
-
|`channels` | (option) 'application' as default. One or more of {'application', 'system', 'setup', 'security'}. If you want to read 'setup' or 'security' logs, you must launch fluentd with administrator privileges.|
|
177
|
+
|`channels` | (option) No default value just empty array, but 'application' is used as default due to backward compatibility. One or more of {'application', 'system', 'setup', 'security'}. If you want to read 'setup' or 'security' logs, you must launch fluentd with administrator privileges.|
|
167
178
|
|`keys` | (option) A subset of [keys](#read-keys) to read. Defaults to all keys.|
|
168
179
|
|`read_interval` | (option) Read interval in seconds. 2 seconds as default.|
|
169
180
|
|`from_encoding` | (option) Input character encoding. `nil` as default.|
|
170
181
|
|`<storage>` | Setting for `storage` plugin for recording read position like `in_tail`'s `pos_file`.|
|
171
182
|
|`<parse>` | Setting for `parser` plugin for parsing raw XML EventLog records. |
|
172
183
|
|`parse_description`| (option) parse `description` field and set parsed result into the record. `Description` and `EventData` fields are removed|
|
184
|
+
|`read_from_head` | **Deprecated** (option) Start to read the entries from the oldest, not from when fluentd is started. Defaults to `false`.|
|
185
|
+
|`read_existing_events` | (option) Read the entries which already exist before fluentd is started. Defaults to `false`.|
|
186
|
+
|`render_as_xml` | (option) Render Windows EventLog as XML or Ruby Hash object directly. Defaults to `true`.|
|
187
|
+
|`rate_limit` | (option) Specify rate limit to consume EventLog. Default is `Winevt::EventLog::Subscribe::RATE_INFINITE`.|
|
188
|
+
|`preserve_qualifiers_on_hash` | (option) When set up it as true, this plugin preserves "Qualifiers" and "EventID" keys. When set up it as false, this plugin calculates actual "EventID" from "Qualifiers" and removing "Qualifiers". Default is `false`.|
|
189
|
+
|`read_all_channels`| (option) Read from all channels. Default is `false`|
|
190
|
+
|`<subscribe>` | Setting for subscribe channels. |
|
191
|
+
|
192
|
+
##### subscribe section
|
193
|
+
|
194
|
+
|name | description |
|
195
|
+
|:----- |:----- |
|
196
|
+
|`channels` | One or more of {'application', 'system', 'setup', 'security'}. If you want to read 'setup' or 'security' logs, you must launch fluentd with administrator privileges. |
|
197
|
+
|`read_existing_events` | (option) Read the entries which already exist before fluentd is started. Defaults to `false`. |
|
198
|
+
|
199
|
+
|
200
|
+
**Motivation:** subscribe directive is designed for applying `read_existing_events` each of channels which is specified in subscribe section(s).
|
201
|
+
|
202
|
+
e.g) The previous configuration can handle `read_existing_events` but this parameter only specifies `read_existing_events` or not for channels which are specified in `channels`.
|
203
|
+
|
204
|
+
```aconf
|
205
|
+
channels ["Application", "Security", "HardwareEvents"]
|
206
|
+
read_existing_events true
|
207
|
+
```
|
208
|
+
|
209
|
+
is interpreted as "Application", "Security", and "HardwareEvents" should be read existing events.
|
210
|
+
|
211
|
+
But some users want to configure to:
|
212
|
+
|
213
|
+
* "Application" and "Security" channels just tailing
|
214
|
+
* "HardwareEvent" channel read existing events before launching Fluentd
|
215
|
+
|
216
|
+
With `<subscribe>` directive, this requirements can be represendted as:
|
217
|
+
|
218
|
+
```aconf
|
219
|
+
<subscribe>
|
220
|
+
channles ["Application", "Security"]
|
221
|
+
# read_existing_events false
|
222
|
+
</subscribe>
|
223
|
+
<subscribe>
|
224
|
+
channles ["HardwareEvent"]
|
225
|
+
read_existing_events true
|
226
|
+
</subscribe>
|
227
|
+
```
|
228
|
+
|
229
|
+
This configuration can be handled as:
|
230
|
+
|
231
|
+
* "Application" and "Security" channels just tailing
|
232
|
+
* "HardwareEvent" channel read existing events before launching Fluentd
|
173
233
|
|
174
234
|
##### Available keys
|
175
235
|
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "fluent-plugin-windows-eventlog"
|
7
|
-
spec.version = "0.
|
7
|
+
spec.version = "0.5.3"
|
8
8
|
spec.authors = ["okahashi117", "Hiroshi Hatake", "Masahiro Nakagawa"]
|
9
9
|
spec.email = ["naruki_okahashi@jbat.co.jp", "cosmo0920.oucc@gmail.com", "repeatedly@gmail.com"]
|
10
10
|
spec.summary = %q{Fluentd Input plugin to read windows event log.}
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "test-unit", "~> 3.2.0"
|
23
23
|
spec.add_runtime_dependency "fluentd", [">= 0.14.12", "< 2"]
|
24
24
|
spec.add_runtime_dependency "win32-eventlog"
|
25
|
-
spec.add_runtime_dependency "winevt_c", ">= 0.
|
25
|
+
spec.add_runtime_dependency "winevt_c", ">= 0.7.1"
|
26
26
|
spec.add_runtime_dependency "nokogiri", "~> 1.10"
|
27
27
|
spec.add_runtime_dependency "fluent-plugin-parser-winevt_xml", ">= 0.1.2"
|
28
28
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
class WinevtBookmarkDocument < Nokogiri::XML::SAX::Document
|
4
|
+
attr_reader :result
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@result = {}
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_document
|
12
|
+
end
|
13
|
+
|
14
|
+
def start_element(name, attributes = [])
|
15
|
+
if name == "Bookmark"
|
16
|
+
@result[:channel] = attributes[0][1] rescue nil
|
17
|
+
@result[:record_id] = attributes[1][1].to_i rescue nil
|
18
|
+
@result[:is_current] = attributes[2][1].downcase == "true" rescue nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def characters(string)
|
23
|
+
end
|
24
|
+
|
25
|
+
def end_element(name, attributes = [])
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_document
|
29
|
+
end
|
30
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'winevt'
|
2
2
|
require 'fluent/plugin/input'
|
3
3
|
require 'fluent/plugin'
|
4
|
+
require_relative 'bookmark_sax_parser'
|
4
5
|
|
5
6
|
module Fluent::Plugin
|
6
7
|
class WindowsEventLog2Input < Input
|
@@ -32,12 +33,20 @@ module Fluent::Plugin
|
|
32
33
|
|
33
34
|
config_param :tag, :string
|
34
35
|
config_param :read_interval, :time, default: 2
|
35
|
-
config_param :channels, :array, default: [
|
36
|
+
config_param :channels, :array, default: []
|
36
37
|
config_param :keys, :array, default: []
|
37
|
-
config_param :read_from_head, :bool, default: false
|
38
|
+
config_param :read_from_head, :bool, default: false, deprecated: "Use `read_existing_events' instead."
|
39
|
+
config_param :read_existing_events, :bool, default: false
|
38
40
|
config_param :parse_description, :bool, default: false
|
39
41
|
config_param :render_as_xml, :bool, default: true
|
40
42
|
config_param :rate_limit, :integer, default: Winevt::EventLog::Subscribe::RATE_INFINITE
|
43
|
+
config_param :preserve_qualifiers_on_hash, :bool, default: false
|
44
|
+
config_param :read_all_channels, :bool, default: false
|
45
|
+
|
46
|
+
config_section :subscribe, param_name: :subscribe_configs, required: false, multi: true do
|
47
|
+
config_param :channels, :array
|
48
|
+
config_param :read_existing_events, :bool, default: false
|
49
|
+
end
|
41
50
|
|
42
51
|
config_section :storage do
|
43
52
|
config_set_default :usage, "bookmarks"
|
@@ -58,18 +67,40 @@ module Fluent::Plugin
|
|
58
67
|
|
59
68
|
def configure(conf)
|
60
69
|
super
|
61
|
-
@chs =
|
70
|
+
@chs = []
|
71
|
+
@all_chs = Winevt::EventLog::Channel.new
|
72
|
+
@all_chs.force_enumerate = false
|
73
|
+
|
74
|
+
if @read_all_channels
|
75
|
+
@all_chs.each do |ch|
|
76
|
+
uch = ch.strip.downcase
|
77
|
+
@chs.push([uch, @read_existing_events])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@read_existing_events = @read_from_head || @read_existing_events
|
82
|
+
if @channels.empty? && @subscribe_configs.empty? && !@read_all_channels
|
83
|
+
@chs.push(['application', @read_existing_events])
|
84
|
+
else
|
85
|
+
@channels.map {|ch| ch.strip.downcase }.uniq.each do |uch|
|
86
|
+
@chs.push([uch, @read_existing_events])
|
87
|
+
end
|
88
|
+
@subscribe_configs.each do |subscribe|
|
89
|
+
subscribe.channels.map {|ch| ch.strip.downcase }.uniq.each do |uch|
|
90
|
+
@chs.push([uch, subscribe.read_existing_events])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
@chs.uniq!
|
62
95
|
@keynames = @keys.map {|k| k.strip }.uniq
|
63
96
|
if @keynames.empty?
|
64
97
|
@keynames = KEY_MAP.keys
|
65
98
|
end
|
66
|
-
@keynames.delete('Qualifiers') unless @render_as_xml
|
67
|
-
@keynames.delete('EventData') if @parse_description
|
68
99
|
|
69
100
|
@tag = tag
|
70
|
-
@tailing = @read_from_head ? false : true
|
71
101
|
@bookmarks_storage = storage_create(usage: "bookmarks")
|
72
102
|
@winevt_xml = false
|
103
|
+
@parser = nil
|
73
104
|
if @render_as_xml
|
74
105
|
@parser = parser_create
|
75
106
|
@winevt_xml = @parser.respond_to?(:winevt_xml?) && @parser.winevt_xml?
|
@@ -81,35 +112,66 @@ module Fluent::Plugin
|
|
81
112
|
alias_method :on_notify, :on_notify_hash
|
82
113
|
end
|
83
114
|
end
|
115
|
+
|
116
|
+
if @render_as_xml && @preserve_qualifiers_on_hash
|
117
|
+
raise Fluent::ConfigError, "preserve_qualifiers_on_hash must be used with Hash object rendering(render_as_xml as false)."
|
118
|
+
end
|
119
|
+
if !@render_as_xml && !@preserve_qualifiers_on_hash
|
120
|
+
@keynames.delete('Qualifiers')
|
121
|
+
elsif @parser.respond_to?(:preserve_qualifiers?) && !@parser.preserve_qualifiers?
|
122
|
+
@keynames.delete('Qualifiers')
|
123
|
+
end
|
124
|
+
@keynames.delete('EventData') if @parse_description
|
84
125
|
end
|
85
126
|
|
86
127
|
def start
|
87
128
|
super
|
88
129
|
|
89
|
-
@chs.each do |ch|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
subscribe.
|
104
|
-
subscribe.
|
105
|
-
|
106
|
-
on_notify(ch, subscribe)
|
130
|
+
@chs.each do |ch, read_existing_events|
|
131
|
+
subscribe_channel(ch, read_existing_events)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def subscribe_channel(ch, read_existing_events)
|
136
|
+
bookmarkXml = @bookmarks_storage.get(ch) || ""
|
137
|
+
bookmark = nil
|
138
|
+
if bookmark_validator(bookmarkXml, ch)
|
139
|
+
bookmark = Winevt::EventLog::Bookmark.new(bookmarkXml)
|
140
|
+
end
|
141
|
+
subscribe = Winevt::EventLog::Subscribe.new
|
142
|
+
subscribe.read_existing_events = read_existing_events
|
143
|
+
begin
|
144
|
+
subscribe.subscribe(ch, "*", bookmark)
|
145
|
+
if !@render_as_xml && @preserve_qualifiers_on_hash && subscribe.respond_to?(:preserve_qualifiers=)
|
146
|
+
subscribe.preserve_qualifiers = @preserve_qualifiers_on_hash
|
107
147
|
end
|
148
|
+
rescue Winevt::EventLog::Query::Error => e
|
149
|
+
raise Fluent::ConfigError, "Invalid Bookmark XML is loaded. #{e}"
|
150
|
+
end
|
151
|
+
subscribe.render_as_xml = @render_as_xml
|
152
|
+
subscribe.rate_limit = @rate_limit
|
153
|
+
timer_execute("in_windows_eventlog_#{escape_channel(ch)}".to_sym, @read_interval) do
|
154
|
+
on_notify(ch, subscribe)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def bookmark_validator(bookmarkXml, channel)
|
159
|
+
return false if bookmarkXml.empty?
|
160
|
+
|
161
|
+
evtxml = WinevtBookmarkDocument.new
|
162
|
+
parser = Nokogiri::XML::SAX::Parser.new(evtxml)
|
163
|
+
parser.parse(bookmarkXml)
|
164
|
+
result = evtxml.result
|
165
|
+
if !result.empty? && (result[:channel].downcase == channel.downcase) && result[:is_current]
|
166
|
+
true
|
167
|
+
else
|
168
|
+
log.warn "This stored bookmark is incomplete for using. Referring `read_existing_events` parameter to subscribe: #{bookmarkXml}, channel: #{channel}"
|
169
|
+
false
|
108
170
|
end
|
109
171
|
end
|
110
172
|
|
111
173
|
def escape_channel(ch)
|
112
|
-
ch.gsub(/[^a-zA-Z0-9]/, '_')
|
174
|
+
ch.gsub(/[^a-zA-Z0-9\s]/, '_')
|
113
175
|
end
|
114
176
|
|
115
177
|
def on_notify(ch, subscribe)
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
class BookmarkSAXParserTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@evtxml = WinevtBookmarkDocument.new
|
7
|
+
@parser = Nokogiri::XML::SAX::Parser.new(@evtxml)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_parse
|
11
|
+
bookmark_str = <<EOS
|
12
|
+
<BookmarkList>
|
13
|
+
<Bookmark Channel='Application' RecordId='161332' IsCurrent='true'/>
|
14
|
+
</BookmarkList>
|
15
|
+
EOS
|
16
|
+
@parser.parse(bookmark_str)
|
17
|
+
expected = {channel: "Application", record_id: 161332, is_current: true}
|
18
|
+
assert_equal expected, @evtxml.result
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_parse_2
|
22
|
+
bookmark_str = <<EOS
|
23
|
+
<BookmarkList>
|
24
|
+
<Bookmark Channel='Security' RecordId='25464' IsCurrent='true'/>
|
25
|
+
</BookmarkList>
|
26
|
+
EOS
|
27
|
+
@parser.parse(bookmark_str)
|
28
|
+
expected = {channel: "Security", record_id: 25464, is_current: true}
|
29
|
+
assert_equal expected, @evtxml.result
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_parse_empty_bookmark_list
|
33
|
+
bookmark_str = <<EOS
|
34
|
+
<BookmarkList>
|
35
|
+
</BookmarkList>
|
36
|
+
EOS
|
37
|
+
@parser.parse(bookmark_str)
|
38
|
+
expected = {}
|
39
|
+
assert_equal expected, @evtxml.result
|
40
|
+
end
|
41
|
+
end
|
@@ -23,11 +23,98 @@ class WindowsEventLog2InputTest < Test::Unit::TestCase
|
|
23
23
|
d = create_driver CONFIG
|
24
24
|
assert_equal 'fluent.eventlog', d.instance.tag
|
25
25
|
assert_equal 2, d.instance.read_interval
|
26
|
-
assert_equal [
|
27
|
-
assert_false d.instance.
|
26
|
+
assert_equal [], d.instance.channels
|
27
|
+
assert_false d.instance.read_existing_events
|
28
28
|
assert_true d.instance.render_as_xml
|
29
29
|
end
|
30
30
|
|
31
|
+
sub_test_case "configure" do
|
32
|
+
test "subscribe directive" do
|
33
|
+
d = create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog"}, [
|
34
|
+
config_element("storage", "", {
|
35
|
+
'@type' => 'local',
|
36
|
+
'persistent' => false
|
37
|
+
}),
|
38
|
+
config_element("subscribe", "", {
|
39
|
+
'channels' => ['System', 'Windows PowerShell'],
|
40
|
+
}),
|
41
|
+
config_element("subscribe", "", {
|
42
|
+
'channels' => ['Security'],
|
43
|
+
'read_existing_events' => true
|
44
|
+
}),
|
45
|
+
])
|
46
|
+
expected = [["system", false], ["windows powershell", false], ["security", true]]
|
47
|
+
assert_equal expected, d.instance.instance_variable_get(:@chs)
|
48
|
+
end
|
49
|
+
|
50
|
+
test "duplicated subscribe" do
|
51
|
+
d = create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog",
|
52
|
+
"channels" => ["System", "Windows PowerShell"]
|
53
|
+
}, [
|
54
|
+
config_element("storage", "", {
|
55
|
+
'@type' => 'local',
|
56
|
+
'persistent' => false
|
57
|
+
}),
|
58
|
+
config_element("subscribe", "", {
|
59
|
+
'channels' => ['System', 'Windows PowerShell'],
|
60
|
+
}),
|
61
|
+
config_element("subscribe", "", {
|
62
|
+
'channels' => ['Security'],
|
63
|
+
'read_existing_events' => true
|
64
|
+
}),
|
65
|
+
])
|
66
|
+
expected = [["system", false], ["windows powershell", false], ["security", true]]
|
67
|
+
assert_equal 1, d.instance.instance_variable_get(:@chs).select {|ch, flag| ch == "system"}.size
|
68
|
+
assert_equal expected, d.instance.instance_variable_get(:@chs)
|
69
|
+
end
|
70
|
+
|
71
|
+
test "non duplicated subscribe" do
|
72
|
+
d = create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog",
|
73
|
+
"channels" => ["System", "Windows PowerShell"]
|
74
|
+
}, [
|
75
|
+
config_element("storage", "", {
|
76
|
+
'@type' => 'local',
|
77
|
+
'persistent' => false
|
78
|
+
}),
|
79
|
+
config_element("subscribe", "", {
|
80
|
+
'channels' => ['System', 'Windows PowerShell'],
|
81
|
+
'read_existing_events' => true
|
82
|
+
}),
|
83
|
+
config_element("subscribe", "", {
|
84
|
+
'channels' => ['Security'],
|
85
|
+
'read_existing_events' => true
|
86
|
+
}),
|
87
|
+
])
|
88
|
+
expected = [["system", false], ["windows powershell", false], ["system", true], ["windows powershell", true], ["security", true]]
|
89
|
+
assert_equal 2, d.instance.instance_variable_get(:@chs).select {|ch, flag| ch == "system"}.size
|
90
|
+
assert_equal expected, d.instance.instance_variable_get(:@chs)
|
91
|
+
end
|
92
|
+
|
93
|
+
test "invalid combination for preserving qualifiers" do
|
94
|
+
assert_raise(Fluent::ConfigError) do
|
95
|
+
create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog",
|
96
|
+
"render_as_xml" => true,
|
97
|
+
"preserve_qualifiers_on_hash" => true,
|
98
|
+
}, [
|
99
|
+
config_element("storage", "", {
|
100
|
+
'@type' => 'local',
|
101
|
+
'persistent' => false
|
102
|
+
}),
|
103
|
+
])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
data("application" => ["Application", "Application"],
|
109
|
+
"windows powershell" => ["Windows PowerShell", "Windows PowerShell"],
|
110
|
+
"escaped" => ["Should_Be_Escaped_", "Should+Be;Escaped/"]
|
111
|
+
)
|
112
|
+
def test_escape_channel(data)
|
113
|
+
expected, actual = data
|
114
|
+
d = create_driver CONFIG
|
115
|
+
assert_equal expected, d.instance.escape_channel(actual)
|
116
|
+
end
|
117
|
+
|
31
118
|
def test_parse_desc
|
32
119
|
d = create_driver
|
33
120
|
desc =<<-DESC
|
@@ -180,6 +267,37 @@ DESC
|
|
180
267
|
assert_equal("4", record["Level"])
|
181
268
|
assert_equal("fluent-plugins", record["ProviderName"])
|
182
269
|
end
|
270
|
+
|
271
|
+
def test_write_with_preserving_qualifiers
|
272
|
+
require 'winevt'
|
273
|
+
|
274
|
+
d = create_driver(config_element("ROOT", "", {"tag" => "fluent.eventlog",
|
275
|
+
"render_as_xml" => false,
|
276
|
+
'preserve_qualifiers_on_hash' => true
|
277
|
+
}, [
|
278
|
+
config_element("storage", "", {
|
279
|
+
'@type' => 'local',
|
280
|
+
'persistent' => false
|
281
|
+
}),
|
282
|
+
]))
|
283
|
+
|
284
|
+
service = Fluent::Plugin::EventService.new
|
285
|
+
subscribe = Winevt::EventLog::Subscribe.new
|
286
|
+
|
287
|
+
omit "@parser.preserve_qualifiers does not respond" unless subscribe.respond_to?(:preserve_qualifiers?)
|
288
|
+
|
289
|
+
d.run(expect_emits: 1) do
|
290
|
+
service.run
|
291
|
+
end
|
292
|
+
|
293
|
+
assert(d.events.length >= 1)
|
294
|
+
event = d.events.last
|
295
|
+
record = event.last
|
296
|
+
|
297
|
+
assert_true(record.has_key?("Description"))
|
298
|
+
assert_true(record.has_key?("EventData"))
|
299
|
+
assert_true(record.has_key?("Qualifiers"))
|
300
|
+
end
|
183
301
|
end
|
184
302
|
|
185
303
|
class PersistBookMark < self
|
@@ -188,6 +306,7 @@ DESC
|
|
188
306
|
config_element("storage", "", {
|
189
307
|
'@type' => 'local',
|
190
308
|
'@id' => 'test-02',
|
309
|
+
'@log_level' => "info",
|
191
310
|
'path' => File.join(TEST_PLUGIN_STORAGE_PATH,
|
192
311
|
'json', 'test-02.json'),
|
193
312
|
'persistent' => true,
|
@@ -251,6 +370,21 @@ EOS
|
|
251
370
|
assert_raise(Fluent::ConfigError) do
|
252
371
|
d2.instance.start
|
253
372
|
end
|
373
|
+
assert_equal 0, d2.logs.grep(/This stored bookmark is incomplete for using. Referring `read_existing_events` parameter to subscribe:/).length
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_start_with_empty_bookmark
|
377
|
+
invalid_storage_contents = <<-EOS
|
378
|
+
<BookmarkList>\r\n</BookmarkList>
|
379
|
+
EOS
|
380
|
+
d = create_driver(CONFIG2)
|
381
|
+
storage = d.instance.instance_variable_get(:@bookmarks_storage)
|
382
|
+
storage.put('application', invalid_storage_contents)
|
383
|
+
assert File.exist?(File.join(TEST_PLUGIN_STORAGE_PATH, 'json', 'test-02.json'))
|
384
|
+
|
385
|
+
d2 = create_driver(CONFIG2)
|
386
|
+
d2.instance.start
|
387
|
+
assert_equal 1, d2.logs.grep(/This stored bookmark is incomplete for using. Referring `read_existing_events` parameter to subscribe:/).length
|
254
388
|
end
|
255
389
|
end
|
256
390
|
|
@@ -283,4 +417,33 @@ EOS
|
|
283
417
|
assert_true(record.has_key?("Description"))
|
284
418
|
assert_true(record.has_key?("EventData"))
|
285
419
|
end
|
420
|
+
|
421
|
+
def test_write_with_winevt_xml_parser_without_qualifiers
|
422
|
+
d = create_driver(config_element("ROOT", "", {"tag" => "fluent.eventlog"}, [
|
423
|
+
config_element("storage", "", {
|
424
|
+
'@type' => 'local',
|
425
|
+
'persistent' => false
|
426
|
+
}),
|
427
|
+
config_element("parse", "", {
|
428
|
+
'@type' => 'winevt_xml',
|
429
|
+
'preserve_qualifiers' => false
|
430
|
+
}),
|
431
|
+
]))
|
432
|
+
|
433
|
+
service = Fluent::Plugin::EventService.new
|
434
|
+
|
435
|
+
omit "@parser.preserve_qualifiers does not respond" unless d.instance.instance_variable_get(:@parser).respond_to?(:preserve_qualifiers?)
|
436
|
+
|
437
|
+
d.run(expect_emits: 1) do
|
438
|
+
service.run
|
439
|
+
end
|
440
|
+
|
441
|
+
assert(d.events.length >= 1)
|
442
|
+
event = d.events.last
|
443
|
+
record = event.last
|
444
|
+
|
445
|
+
assert_true(record.has_key?("Description"))
|
446
|
+
assert_true(record.has_key?("EventData"))
|
447
|
+
assert_false(record.has_key?("Qualifiers"))
|
448
|
+
end
|
286
449
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-windows-eventlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- okahashi117
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-03-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -94,14 +94,14 @@ dependencies:
|
|
94
94
|
requirements:
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: 0.
|
97
|
+
version: 0.7.1
|
98
98
|
type: :runtime
|
99
99
|
prerelease: false
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0.
|
104
|
+
version: 0.7.1
|
105
105
|
- !ruby/object:Gem::Dependency
|
106
106
|
name: nokogiri
|
107
107
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,11 +147,13 @@ files:
|
|
147
147
|
- Rakefile
|
148
148
|
- appveyor.yml
|
149
149
|
- fluent-plugin-winevtlog.gemspec
|
150
|
+
- lib/fluent/plugin/bookmark_sax_parser.rb
|
150
151
|
- lib/fluent/plugin/in_windows_eventlog.rb
|
151
152
|
- lib/fluent/plugin/in_windows_eventlog2.rb
|
152
153
|
- test/data/eventid_6416
|
153
154
|
- test/generate-windows-event.rb
|
154
155
|
- test/helper.rb
|
156
|
+
- test/plugin/test_bookmark_sax_parser.rb
|
155
157
|
- test/plugin/test_in_windows_eventlog2.rb
|
156
158
|
- test/plugin/test_in_winevtlog.rb
|
157
159
|
homepage: https://github.com/fluent/fluent-plugin-windows-eventlog
|
@@ -182,5 +184,6 @@ test_files:
|
|
182
184
|
- test/data/eventid_6416
|
183
185
|
- test/generate-windows-event.rb
|
184
186
|
- test/helper.rb
|
187
|
+
- test/plugin/test_bookmark_sax_parser.rb
|
185
188
|
- test/plugin/test_in_windows_eventlog2.rb
|
186
189
|
- test/plugin/test_in_winevtlog.rb
|