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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b22aa563236f503aa9b606c6848b223995eab6174cf5ab244ef9cf535afcb8c9
4
- data.tar.gz: 90dfddd1015ff28d730d11168fe60466e6a9c69b9c436601fb25eff867c935b0
3
+ metadata.gz: f42851f147127453f0392e3e14ab31ed86983508c75453d9b41d2674441d8abc
4
+ data.tar.gz: fbfe63f1ee0034df3fd4346376b728b6728105b76130c82902768e67b4b5c1fe
5
5
  SHA512:
6
- metadata.gz: 57f27df3303f3424057f4fce75d7a12c804cc7bd5ecc2c8cf9579512dd9dc29c944ebea038541bbdac508028c9da669a246ac754c572fac19e3028ecabefab8c
7
- data.tar.gz: 78d02ada2bbc70fc91df533fdcd7f47a4d680707c06f1a26eaa014a2c57435c90d2e47c3d82b3c43d81229ffabc3e2f7791d397bf168d11911b20a8d4a451250
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.4.5"
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.6.1"
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
@@ -49,6 +49,7 @@ module Fluent::Plugin
49
49
  end
50
50
 
51
51
  def configure(conf)
52
+ log.warn "in_windows_eventlog is deprecated. It will be removed in the future version."
52
53
  super
53
54
  @chs = @channels.map {|ch| ch.strip.downcase }.uniq
54
55
  if @chs.empty?
@@ -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: ['application']
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 = @channels.map {|ch| ch.strip.downcase }.uniq
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
- bookmarkXml = @bookmarks_storage.get(ch) || ""
91
- subscribe = Winevt::EventLog::Subscribe.new
92
- bookmark = unless bookmarkXml.empty?
93
- Winevt::EventLog::Bookmark.new(bookmarkXml)
94
- else
95
- nil
96
- end
97
- subscribe.tail = @tailing
98
- begin
99
- subscribe.subscribe(ch, "*", bookmark)
100
- rescue Winevt::EventLog::Query::Error => e
101
- raise Fluent::ConfigError, "Invalid Bookmark XML is loaded. #{e}"
102
- end
103
- subscribe.render_as_xml = @render_as_xml
104
- subscribe.rate_limit = @rate_limit
105
- timer_execute("in_windows_eventlog_#{escape_channel(ch)}".to_sym, @read_interval) do
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
@@ -25,6 +25,7 @@ end
25
25
  require 'fluent/test/driver/input'
26
26
  require 'fluent/plugin/in_windows_eventlog'
27
27
  require 'fluent/plugin/in_windows_eventlog2'
28
+ require 'fluent/plugin/bookmark_sax_parser'
28
29
 
29
30
  class Test::Unit::TestCase
30
31
  end
@@ -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 ['application'], d.instance.channels
27
- assert_false d.instance.read_from_head
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.5
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-01-28 00:00:00.000000000 Z
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.6.1
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.6.1
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