fluent-plugin-windows-eventlog 0.6.0 → 0.8.1

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: 7e3441c382ee3af99cf0a4b67e1d059903933ec07f837fbec8ae93b11a2b252c
4
- data.tar.gz: 2d8555cc1d825218f03deb00b4d83ac2690df8e138395cdef197319b299b2135
3
+ metadata.gz: bdf1842ac573845b2a01c853ab4dd7afb349c0e014d5538c24aff33f0c674499
4
+ data.tar.gz: 92003b55f2e2380b3d9d8ebbc3ea794c018cd75b51100562f932ef7fcd751728
5
5
  SHA512:
6
- metadata.gz: 26071af5dda0107d6269dd2a4ff641cbf914a4ff7071d725e4297001e9b1606470cb019e578900a57c7738d49d4f8093cdd8ba164db826dd246a88cef4f1b333
7
- data.tar.gz: 318b12aa2ef3d12547001ae1dc17a27fe28bf0622c6249f2ec396a5cf77a12ff4b8f54bb994a746eb517a99e4d1cd8b77325ad43e9704f4b01b205fb1019fd13
6
+ metadata.gz: d4f8f6b2198d8a8861b1c25a85a7a553b4757db942c03a8246e36f7d1e9a5d085328668a6b55ac32de6cad0491285d2e3009e49606eee0da03c1d7c2fab0dab8
7
+ data.tar.gz: 474b65132114f707e358d62984becd02f750f7913b2f248ff21db8ac27c668835a6541fa7f8fd3df5a944e241c255e8bdbd607cc0d143d687222bd0e6412e2f7
@@ -0,0 +1,34 @@
1
+ name: Unit Test
2
+ on:
3
+ - push
4
+ - pull_request
5
+ jobs:
6
+ test:
7
+ runs-on: ${{ matrix.os }}
8
+ continue-on-error: ${{ matrix.experimental }}
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby: [ '2.5', '2.6', '2.7', '3.0' ]
13
+ os:
14
+ - windows-latest
15
+ experimental: [false]
16
+ include:
17
+ - ruby: 'head'
18
+ os: windows-latest
19
+ experimental: true
20
+ name: Unit testing with Ruby ${{ matrix.ruby }} on ${{ matrix.os }}
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ - uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ - name: Install
27
+ run: |
28
+ ruby --version
29
+ gem --version
30
+ gem install bundler rake
31
+ ridk exec bundle install --jobs 4 --retry 3
32
+ - name: Unit Test
33
+ run: |
34
+ bundle exec rake test
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # Release v0.8.1 - 2021/09/16
2
+ * in_windows_eventlog2: Add trace logs for debugging
3
+ * in_windows_eventlog2: Support event query parameter on Windows EventLog channel subscriptions
4
+
5
+ # Release v0.8.0 - 2020/09/16
6
+ * in_windows_eventlog2: Support remoting access
7
+
8
+ # Release v.0.7.1.rc1 - 2020/06/23
9
+ * in_windows_eventlog2: Depends on nokogiri 1.11 series
10
+
11
+ # Release v0.7.0 - 2020/05/22
12
+ * in_windows_eventlog2: Support multilingual description
13
+
1
14
  # Release v0.6.0 - 2020/04/15
2
15
  * Make fluent-plugin-parser-winevt_xml plugin as optional dependency
3
16
  * in_windows_eventlog2: Render Ruby hash object directly by default
data/README.md CHANGED
@@ -142,23 +142,31 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
142
142
  render_as_xml false # default is false.
143
143
  rate_limit 200 # default is -1(Winevt::EventLog::Subscribe::RATE_INFINITE).
144
144
  # preserve_qualifiers_on_hash true # default is false.
145
+ # read_all_channels false # default is false.
146
+ # description_locale en_US # default is nil. It means that system locale is used for obtaining description.
147
+ # refresh_subscription_interval 10m # default is nil. It specifies refresh interval for channel subscriptions.
148
+ # event_query "Event/System[EventID!=1001]" # default is "*".
145
149
  <storage>
146
150
  @type local # @type local is the default.
147
151
  persistent true # default is true. Set to false to use in-memory storage.
148
- path ./tmp/storage.json # This is required when persistent is true.
152
+ path ./tmp/storage.json # This is required when persistent is true. If migrating from eventlog v1 please ensure that you remove the old .pos folder
149
153
  # Or, please consider using <system> section's `root_dir` parameter.
150
154
  </storage>
151
- <parse>
152
- @type winevt_xml # @type winevt_xml is the default. winevt_xml and none parsers are supported for now.
155
+ # <parse> # Note: parsing is only available when render_as_xml true
156
+ # @type winevt_xml # @type winevt_xml is the default. winevt_xml and none parsers are supported for now.
153
157
  # When set up it as true, this plugin preserves "Qualifiers" and "EventID" keys.
154
158
  # When set up it as false, this plugin calculates actual "EventID" from "Qualifiers" and removing "Qualifiers".
155
159
  # With the following equation:
156
160
  # (EventID & 0xffff) | (Qualifiers & 0xffff) << 16
157
- preserve_qualifiers true
158
- </parse>
161
+ # preserve_qualifiers true # preserve_qualifiers_on_hash can be used as a setting outside <parse> if render_as_xml is false
162
+ # </parse>
159
163
  # <subscribe>
160
164
  # channles application, system
161
165
  # read_existing_events false # read_existing_events should be applied each of subscribe directive(s)
166
+ # remote_server 127.0.0.1 # Remote server ip/fqdn
167
+ # remote_domain WORKGROUP # Domain name
168
+ # remote_username fluentd # Remoting access account name
169
+ # remote_password changeme! # Remoting access account password
162
170
  # </subscribe>
163
171
  </source>
164
172
 
@@ -174,7 +182,7 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
174
182
 
175
183
  |name | description |
176
184
  |:----- |:----- |
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.|
185
+ |`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'} and other evtx, which is the brand new Windows XML Event Log (EVTX) format since Windows Vista, formatted channels. Theoritically, `in_windows_ventlog2` may read all of channels except for debug and analytical typed channels. If you want to read 'setup' or 'security' logs or some privileged channels, you must launch fluentd with administrator privileges.|
178
186
  |`keys` | (option) A subset of [keys](#read-keys) to read. Defaults to all keys.|
179
187
  |`read_interval` | (option) Read interval in seconds. 2 seconds as default.|
180
188
  |`from_encoding` | (option) Input character encoding. `nil` as default.|
@@ -187,6 +195,9 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
187
195
  |`rate_limit` | (option) Specify rate limit to consume EventLog. Default is `Winevt::EventLog::Subscribe::RATE_INFINITE`.|
188
196
  |`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
197
  |`read_all_channels`| (option) Read from all channels. Default is `false`|
198
+ |`description_locale`| (option) Specify description locale. Default is `nil`. See also: [Supported locales](https://github.com/fluent-plugins-nursery/winevt_c#multilingual-description) |
199
+ |`refresh_subscription_interval`|(option) It specifies refresh interval for channel subscriptions. Default is `nil`.|
200
+ |`event_query`|(option) It specifies query for deny/allow/filter events with XPath 1.0 or structured XML query. Default is `"*"` (retrieving all events).|
190
201
  |`<subscribe>` | Setting for subscribe channels. |
191
202
 
192
203
  ##### subscribe section
@@ -195,6 +206,10 @@ fluentd Input plugin for the Windows Event Log using newer Windows Event Logging
195
206
  |:----- |:----- |
196
207
  |`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
208
  |`read_existing_events` | (option) Read the entries which already exist before fluentd is started. Defaults to `false`. |
209
+ |`remote_server` | (option) Remoting access server ip address/fqdn. Defaults to `nil`. |
210
+ |`remote_domain` | (option) Remoting access server joining domain name. Defaults to `nil`. |
211
+ |`remote_username` | (option) Remoting access access account's username. Defaults to `nil`. |
212
+ |`remote_password` | (option) Remoting access access account's password. Defaults to `nil`. |
198
213
 
199
214
 
200
215
  **Motivation:** subscribe directive is designed for applying `read_existing_events` each of channels which is specified in subscribe section(s).
@@ -231,6 +246,33 @@ This configuration can be handled as:
231
246
  * "Application" and "Security" channels just tailing
232
247
  * "HardwareEvent" channel read existing events before launching Fluentd
233
248
 
249
+ ###### Remoting access
250
+
251
+ `<subscribe>` section supports remoting access parameters:
252
+
253
+ * `remote_server`
254
+ * `remote_domain`
255
+ * `remote_username`
256
+ * `remote_password`
257
+
258
+ These parameters are only in `<subscribe>` directive.
259
+
260
+ Note that before using this feature, remoting access users should belong to "Event Log Readers" group:
261
+
262
+ ```console
263
+ > net localgroup "Event Log Readers" <domain\username> /add
264
+ ```
265
+
266
+ And then, users also should set up their remote box's Firewall configuration:
267
+
268
+ ```console
269
+ > netsh advfirewall firewall set rule group="Remote Event Log Management" new enable=yes
270
+ ```
271
+
272
+ As a security best practices, remoting access account _should not be administrator account_.
273
+
274
+ For graphical instructions, please refer to [Preconfigure a Machine to Collect Remote Windows Events | Sumo Logic](https://help.sumologic.com/03Send-Data/Sources/01Sources-for-Installed-Collectors/Remote-Windows-Event-Log-Source/Preconfigure-a-Machine-to-Collect-Remote-Windows-Events) document for example.
275
+
234
276
  ##### Available keys
235
277
 
236
278
  This plugin reads the following fields from Windows Event Log entries. Use the `keys` configuration option to select a subset. No other customization is allowed for now.
@@ -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.6.0"
7
+ spec.version = "0.8.1"
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.}
@@ -19,10 +19,10 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler"
21
21
  spec.add_development_dependency "rake"
22
- spec.add_development_dependency "test-unit", "~> 3.2.0"
22
+ spec.add_development_dependency "test-unit", "~> 3.4.0"
23
23
  spec.add_development_dependency "nokogiri", [">= 1.10", "< 1.12"]
24
24
  spec.add_development_dependency "fluent-plugin-parser-winevt_xml", ">= 0.1.2"
25
25
  spec.add_runtime_dependency "fluentd", [">= 0.14.12", "< 2"]
26
26
  spec.add_runtime_dependency "win32-eventlog"
27
- spec.add_runtime_dependency "winevt_c", ">= 0.7.1"
27
+ spec.add_runtime_dependency "winevt_c", ">= 0.9.1"
28
28
  end
@@ -7,6 +7,8 @@ module Fluent::Plugin
7
7
  class WindowsEventLog2Input < Input
8
8
  Fluent::Plugin.register_input('windows_eventlog2', self)
9
9
 
10
+ class ReconnectError < Fluent::UnrecoverableError; end
11
+
10
12
  helpers :timer, :storage, :parser
11
13
 
12
14
  DEFAULT_STORAGE_TYPE = 'local'
@@ -42,10 +44,17 @@ module Fluent::Plugin
42
44
  config_param :rate_limit, :integer, default: Winevt::EventLog::Subscribe::RATE_INFINITE
43
45
  config_param :preserve_qualifiers_on_hash, :bool, default: false
44
46
  config_param :read_all_channels, :bool, default: false
47
+ config_param :description_locale, :string, default: nil
48
+ config_param :refresh_subscription_interval, :time, default: nil
49
+ config_param :event_query, :string, default: "*"
45
50
 
46
51
  config_section :subscribe, param_name: :subscribe_configs, required: false, multi: true do
47
52
  config_param :channels, :array
48
53
  config_param :read_existing_events, :bool, default: false
54
+ config_param :remote_server, :string, default: nil
55
+ config_param :remote_domain, :string, default: nil
56
+ config_param :remote_username, :string, default: nil
57
+ config_param :remote_password, :string, default: nil, secret: true
49
58
  end
50
59
 
51
60
  config_section :storage do
@@ -67,9 +76,12 @@ module Fluent::Plugin
67
76
 
68
77
  def configure(conf)
69
78
  super
79
+ @session = nil
70
80
  @chs = []
81
+ @subscriptions = {}
71
82
  @all_chs = Winevt::EventLog::Channel.new
72
83
  @all_chs.force_enumerate = false
84
+ @timers = {}
73
85
 
74
86
  if @read_all_channels
75
87
  @all_chs.each do |ch|
@@ -80,14 +92,22 @@ module Fluent::Plugin
80
92
 
81
93
  @read_existing_events = @read_from_head || @read_existing_events
82
94
  if @channels.empty? && @subscribe_configs.empty? && !@read_all_channels
83
- @chs.push(['application', @read_existing_events])
95
+ @chs.push(['application', @read_existing_events, nil])
84
96
  else
85
97
  @channels.map {|ch| ch.strip.downcase }.uniq.each do |uch|
86
- @chs.push([uch, @read_existing_events])
98
+ @chs.push([uch, @read_existing_events, nil])
87
99
  end
88
100
  @subscribe_configs.each do |subscribe|
101
+ if subscribe.remote_server
102
+ @session = Winevt::EventLog::Session.new(subscribe.remote_server,
103
+ subscribe.remote_domain,
104
+ subscribe.remote_username,
105
+ subscribe.remote_password)
106
+
107
+ log.debug("connect to remote box (server: #{subscribe.remote_server}) domain: #{subscribe.remote_domain} username: #{subscribe.remote_username})")
108
+ end
89
109
  subscribe.channels.map {|ch| ch.strip.downcase }.uniq.each do |uch|
90
- @chs.push([uch, subscribe.read_existing_events])
110
+ @chs.push([uch, subscribe.read_existing_events, @session])
91
111
  end
92
112
  end
93
113
  end
@@ -122,17 +142,87 @@ module Fluent::Plugin
122
142
  @keynames.delete('Qualifiers')
123
143
  end
124
144
  @keynames.delete('EventData') if @parse_description
145
+
146
+ locale = Winevt::EventLog::Locale.new
147
+ if @description_locale && unsupported_locale?(locale, @description_locale)
148
+ raise Fluent::ConfigError, "'#{@description_locale}' is not supported. Supported locales are: #{locale.each.map{|code, _desc| code}.join(" ")}"
149
+ end
150
+ end
151
+
152
+ def unsupported_locale?(locale, description_locale)
153
+ locale.each.select {|c, _d| c.downcase == description_locale.downcase}.empty?
125
154
  end
126
155
 
127
156
  def start
128
157
  super
129
158
 
130
- @chs.each do |ch, read_existing_events|
131
- subscribe_channel(ch, read_existing_events)
159
+ refresh_subscriptions
160
+ if @refresh_subscription_interval
161
+ timer_execute(:in_windows_eventlog_refresh_subscription_timer, @refresh_subscription_interval, &method(:refresh_subscriptions))
132
162
  end
133
163
  end
134
164
 
135
- def subscribe_channel(ch, read_existing_events)
165
+ def shutdown
166
+ super
167
+
168
+ @subscriptions.keys.each do |ch|
169
+ subscription = @subscriptions.delete(ch)
170
+ if subscription
171
+ subscription.cancel
172
+ log.debug "channel (#{ch}) subscription is canceled."
173
+ end
174
+ end
175
+ end
176
+
177
+ def retry_on_error(channel, times: 15)
178
+ try = 0
179
+ begin
180
+ log.debug "Retry to subscribe for #{channel}...." if try > 1
181
+ try += 1
182
+ yield
183
+ log.info "Retry to subscribe for #{channel} succeeded." if try > 1
184
+ try = 0
185
+ rescue Winevt::EventLog::Subscribe::RemoteHandlerError => e
186
+ raise ReconnectError, "Retrying limit is exceeded." if try > times
187
+ log.warn "#{e.message}. Remaining retry count(s): #{times - try}"
188
+ sleep 2**try
189
+ retry
190
+ end
191
+ end
192
+
193
+ def refresh_subscriptions
194
+ clear_subscritpions
195
+
196
+ @chs.each do |ch, read_existing_events, session|
197
+ retry_on_error(ch) do
198
+ ch, subscribe = subscription(ch, read_existing_events, session)
199
+ @subscriptions[ch] = subscribe
200
+ end
201
+ end
202
+ subscribe_channels(@subscriptions)
203
+ end
204
+
205
+ def clear_subscritpions
206
+ @subscriptions.keys.each do |ch|
207
+ subscription = @subscriptions.delete(ch)
208
+ if subscription
209
+ if subscription.cancel
210
+ log.debug "channel (#{ch}) subscription is cancelled."
211
+ subscription.close
212
+ log.debug "channel (#{ch}) subscription handles are closed forcibly."
213
+ end
214
+ end
215
+ end
216
+ @timers.keys.each do |ch|
217
+ timer = @timers.delete(ch)
218
+ if timer
219
+ event_loop_detach(timer)
220
+ log.debug "channel (#{ch}) subscription watcher is detached."
221
+ end
222
+ end
223
+ end
224
+
225
+ def subscription(ch, read_existing_events, remote_session)
136
226
  bookmarkXml = @bookmarks_storage.get(ch) || ""
137
227
  bookmark = nil
138
228
  if bookmark_validator(bookmarkXml, ch)
@@ -141,8 +231,8 @@ module Fluent::Plugin
141
231
  subscribe = Winevt::EventLog::Subscribe.new
142
232
  subscribe.read_existing_events = read_existing_events
143
233
  begin
144
- subscribe.subscribe(ch, "*", bookmark)
145
- if !@render_as_xml && @preserve_qualifiers_on_hash && subscribe.respond_to?(:preserve_qualifiers=)
234
+ subscribe.subscribe(ch, event_query, bookmark, remote_session)
235
+ if !@render_as_xml && @preserve_qualifiers_on_hash
146
236
  subscribe.preserve_qualifiers = @preserve_qualifiers_on_hash
147
237
  end
148
238
  rescue Winevt::EventLog::Query::Error => e
@@ -150,8 +240,17 @@ module Fluent::Plugin
150
240
  end
151
241
  subscribe.render_as_xml = @render_as_xml
152
242
  subscribe.rate_limit = @rate_limit
153
- timer_execute("in_windows_eventlog_#{escape_channel(ch)}".to_sym, @read_interval) do
154
- on_notify(ch, subscribe)
243
+ subscribe.locale = @description_locale if @description_locale
244
+ [ch, subscribe]
245
+ end
246
+
247
+ def subscribe_channels(subscriptions)
248
+ subscriptions.each do |ch, subscribe|
249
+ log.trace "Subscribing Windows EventLog at #{ch} channel"
250
+ @timers[ch] = timer_execute("in_windows_eventlog_#{escape_channel(ch)}".to_sym, @read_interval) do
251
+ on_notify(ch, subscribe)
252
+ end
253
+ log.debug "channel (#{ch}) subscription is subscribed."
155
254
  end
156
255
  end
157
256
 
@@ -211,12 +310,13 @@ module Fluent::Plugin
211
310
  end
212
311
  end
213
312
  end
313
+ router.emit_stream(@tag, es)
314
+ @bookmarks_storage.put(ch, subscribe.bookmark)
315
+ log.trace "Collecting Windows EventLog from #{ch} channel. Collected size: #{es.size}"
214
316
  rescue Winevt::EventLog::Query::Error => e
215
- log.warn "Invalid XML data", error: e
317
+ log.warn "Invalid XML data on #{ch}.", error: e
216
318
  log.warn_backtrace
217
319
  end
218
- router.emit_stream(@tag, es)
219
- @bookmarks_storage.put(ch, subscribe.bookmark)
220
320
  end
221
321
 
222
322
  def on_notify_hash(ch, subscribe)
@@ -241,12 +341,13 @@ module Fluent::Plugin
241
341
  parse_desc(h) if @parse_description
242
342
  es.add(Fluent::Engine.now, h)
243
343
  end
344
+ router.emit_stream(@tag, es)
345
+ @bookmarks_storage.put(ch, subscribe.bookmark)
346
+ log.trace "Collecting Windows EventLog from #{ch} channel. Collected size: #{es.size}"
244
347
  rescue Winevt::EventLog::Query::Error => e
245
- log.warn "Invalid Hash data", error: e
348
+ log.warn "Invalid Hash data on #{ch}.", error: e
246
349
  log.warn_backtrace
247
350
  end
248
- router.emit_stream(@tag, es)
249
- @bookmarks_storage.put(ch, subscribe.bookmark)
250
351
  end
251
352
 
252
353
  #### These lines copied from in_windows_eventlog plugin:
@@ -2,6 +2,17 @@ require 'helper'
2
2
  require 'fileutils'
3
3
  require 'generate-windows-event'
4
4
 
5
+ # Monkey patch for testing
6
+ class Winevt::EventLog::Session
7
+ def ==(obj)
8
+ self.server == obj.server &&
9
+ self.domain == obj.domain &&
10
+ self.username == obj.username &&
11
+ self.password == obj.password &&
12
+ self.flags == obj.flags
13
+ end
14
+ end
15
+
5
16
  class WindowsEventLog2InputTest < Test::Unit::TestCase
6
17
 
7
18
  def setup
@@ -34,9 +45,21 @@ class WindowsEventLog2InputTest < Test::Unit::TestCase
34
45
  assert_equal [], d.instance.channels
35
46
  assert_false d.instance.read_existing_events
36
47
  assert_false d.instance.render_as_xml
48
+ assert_nil d.instance.refresh_subscription_interval
37
49
  end
38
50
 
39
51
  sub_test_case "configure" do
52
+ test "refresh subscription interval" do
53
+ d = create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog",
54
+ "refresh_subscription_interval" => "2m"}, [
55
+ config_element("storage", "", {
56
+ '@type' => 'local',
57
+ 'persistent' => false
58
+ })
59
+ ])
60
+ assert_equal 120, d.instance.refresh_subscription_interval
61
+ end
62
+
40
63
  test "subscribe directive" do
41
64
  d = create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog"}, [
42
65
  config_element("storage", "", {
@@ -51,7 +74,36 @@ class WindowsEventLog2InputTest < Test::Unit::TestCase
51
74
  'read_existing_events' => true
52
75
  }),
53
76
  ])
54
- expected = [["system", false], ["windows powershell", false], ["security", true]]
77
+ expected = [["system", false, nil], ["windows powershell", false, nil], ["security", true, nil]]
78
+ assert_equal expected, d.instance.instance_variable_get(:@chs)
79
+ end
80
+
81
+ test "subscribe directive with remote server session" do
82
+ d = create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog"}, [
83
+ config_element("storage", "", {
84
+ '@type' => 'local',
85
+ 'persistent' => false
86
+ }),
87
+ config_element("subscribe", "", {
88
+ 'channels' => ['System', 'Windows PowerShell'],
89
+ 'remote_server' => '127.0.0.1',
90
+ }),
91
+ config_element("subscribe", "", {
92
+ 'channels' => ['Security'],
93
+ 'read_existing_events' => true,
94
+ 'remote_server' => '192.168.0.1',
95
+ 'remote_username' => 'fluentd',
96
+ 'remote_password' => 'changeme!'
97
+ }),
98
+ ])
99
+ localhost_session = Winevt::EventLog::Session.new("127.0.0.1")
100
+ remote_session = Winevt::EventLog::Session.new("192.168.0.1",
101
+ nil,
102
+ "fluentd",
103
+ "changeme!")
104
+ expected = [["system", false, localhost_session],
105
+ ["windows powershell", false, localhost_session],
106
+ ["security", true, remote_session]]
55
107
  assert_equal expected, d.instance.instance_variable_get(:@chs)
56
108
  end
57
109
 
@@ -71,7 +123,7 @@ class WindowsEventLog2InputTest < Test::Unit::TestCase
71
123
  'read_existing_events' => true
72
124
  }),
73
125
  ])
74
- expected = [["system", false], ["windows powershell", false], ["security", true]]
126
+ expected = [["system", false, nil], ["windows powershell", false, nil], ["security", true, nil]]
75
127
  assert_equal 1, d.instance.instance_variable_get(:@chs).select {|ch, flag| ch == "system"}.size
76
128
  assert_equal expected, d.instance.instance_variable_get(:@chs)
77
129
  end
@@ -93,7 +145,7 @@ class WindowsEventLog2InputTest < Test::Unit::TestCase
93
145
  'read_existing_events' => true
94
146
  }),
95
147
  ])
96
- expected = [["system", false], ["windows powershell", false], ["system", true], ["windows powershell", true], ["security", true]]
148
+ expected = [["system", false, nil], ["windows powershell", false, nil], ["system", true, nil], ["windows powershell", true, nil], ["security", true, nil]]
97
149
  assert_equal 2, d.instance.instance_variable_get(:@chs).select {|ch, flag| ch == "system"}.size
98
150
  assert_equal expected, d.instance.instance_variable_get(:@chs)
99
151
  end
@@ -111,6 +163,37 @@ class WindowsEventLog2InputTest < Test::Unit::TestCase
111
163
  ])
112
164
  end
113
165
  end
166
+
167
+ test "invalid description locale" do
168
+ assert_raise(Fluent::ConfigError) do
169
+ create_driver config_element("ROOT", "", {"tag" => "fluent.eventlog",
170
+ "description_locale" => "ex_EX"
171
+ }, [
172
+ config_element("storage", "", {
173
+ '@type' => 'local',
174
+ 'persistent' => false
175
+ })
176
+ ])
177
+ end
178
+ end
179
+ end
180
+
181
+ data("Japanese" => ["ja_JP", false],
182
+ "English (United States)" => ["en_US", false],
183
+ "English (UK)" => ["en_GB", false],
184
+ "Dutch" => ["nl_NL", false],
185
+ "French" => ["fr_FR", false],
186
+ "German" => ["de_DE", false],
187
+ "Russian" => ["ru_RU", false],
188
+ "Spanish" => ["es_ES", false],
189
+ "Invalid" => ["ex_EX", true],
190
+ )
191
+ def test_unsupported_locale_p(data)
192
+ description_locale, expected = data
193
+ d = create_driver CONFIG
194
+ locale = Winevt::EventLog::Locale.new
195
+ result = d.instance.unsupported_locale?(locale, description_locale)
196
+ assert_equal expected, result
114
197
  end
115
198
 
116
199
  data("application" => ["Application", "Application"],
@@ -219,6 +302,33 @@ DESC
219
302
  assert_equal("fluent-plugins", record["ProviderName"])
220
303
  end
221
304
 
305
+ CONFIG_WITH_QUERY = config_element("ROOT", "", {"tag" => "fluent.eventlog",
306
+ "event_query" => "Event/System[EventID=65500]"}, [
307
+ config_element("storage", "", {
308
+ '@type' => 'local',
309
+ 'persistent' => false
310
+ })
311
+ ])
312
+ def test_write_with_event_query
313
+ d = create_driver(CONFIG_WITH_QUERY)
314
+
315
+ service = Fluent::Plugin::EventService.new
316
+
317
+ d.run(expect_emits: 1) do
318
+ service.run
319
+ end
320
+
321
+ assert(d.events.length >= 1)
322
+ event = d.events.last
323
+ record = event.last
324
+
325
+ assert_equal("Application", record["Channel"])
326
+ assert_equal("65500", record["EventID"])
327
+ assert_equal("4", record["Level"])
328
+ assert_equal("fluent-plugins", record["ProviderName"])
329
+ end
330
+
331
+
222
332
  CONFIG_KEYS = config_element("ROOT", "", {
223
333
  "tag" => "fluent.eventlog",
224
334
  "keys" => ["EventID", "Level", "Channel", "ProviderName"]
@@ -238,7 +348,7 @@ DESC
238
348
  end
239
349
 
240
350
  assert(d.events.length >= 1)
241
- event = d.events.last
351
+ event = d.events.select {|e| e.last["EventID"] == "65500" }.last
242
352
  record = event.last
243
353
 
244
354
  expected = {"EventID" => "65500",
@@ -249,6 +359,36 @@ DESC
249
359
  assert_equal(expected, record)
250
360
  end
251
361
 
362
+ REMOTING_ACCESS_CONFIG = config_element("ROOT", "", {"tag" => "fluent.eventlog"}, [
363
+ config_element("storage", "", {
364
+ '@type' => 'local',
365
+ 'persistent' => false
366
+ }),
367
+ config_element("subscribe", "", {
368
+ 'channels' => ['Application'],
369
+ 'remote_server' => '127.0.0.1',
370
+ }),
371
+ ])
372
+
373
+ def test_write_with_remoting_access
374
+ d = create_driver(REMOTING_ACCESS_CONFIG)
375
+
376
+ service = Fluent::Plugin::EventService.new
377
+
378
+ d.run(expect_emits: 1) do
379
+ service.run
380
+ end
381
+
382
+ assert(d.events.length >= 1)
383
+ event = d.events.select {|e| e.last["EventID"] == "65500" }.last
384
+ record = event.last
385
+
386
+ assert_equal("Application", record["Channel"])
387
+ assert_equal("65500", record["EventID"])
388
+ assert_equal("4", record["Level"])
389
+ assert_equal("fluent-plugins", record["ProviderName"])
390
+ end
391
+
252
392
  class HashRendered < self
253
393
  def test_write
254
394
  d = create_driver(config_element("ROOT", "", {"tag" => "fluent.eventlog",
@@ -355,8 +495,9 @@ DESC
355
495
  service.run
356
496
  end
357
497
 
358
- assert(d2.events.length == 1) # should be tailing after previous context.
359
- event2 = d2.events.last
498
+ events = d2.events.select {|e| e.last["EventID"] == "65500" }
499
+ assert(events.length == 1) # should be tailing after previous context.
500
+ event2 = events.last
360
501
  record2 = event2.last
361
502
 
362
503
  curr_id = record2["EventRecordID"].to_i
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-windows-eventlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - okahashi117
8
8
  - Hiroshi Hatake
9
9
  - Masahiro Nakagawa
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-04-15 00:00:00.000000000 Z
13
+ date: 2021-09-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -46,14 +46,14 @@ dependencies:
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: 3.2.0
49
+ version: 3.4.0
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: 3.2.0
56
+ version: 3.4.0
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: nokogiri
59
59
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: 0.7.1
131
+ version: 0.9.1
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: 0.7.1
138
+ version: 0.9.1
139
139
  description: Fluentd Input plugin to read windows event log.
140
140
  email:
141
141
  - naruki_okahashi@jbat.co.jp
@@ -145,6 +145,7 @@ executables: []
145
145
  extensions: []
146
146
  extra_rdoc_files: []
147
147
  files:
148
+ - ".github/workflows/unit-test.yml"
148
149
  - ".gitignore"
149
150
  - CHANGELOG.md
150
151
  - Gemfile
@@ -166,7 +167,7 @@ homepage: https://github.com/fluent/fluent-plugin-windows-eventlog
166
167
  licenses:
167
168
  - Apache-2.0
168
169
  metadata: {}
169
- post_install_message:
170
+ post_install_message:
170
171
  rdoc_options: []
171
172
  require_paths:
172
173
  - lib
@@ -181,9 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
182
  - !ruby/object:Gem::Version
182
183
  version: '0'
183
184
  requirements: []
184
- rubyforge_project:
185
- rubygems_version: 2.7.6.2
186
- signing_key:
185
+ rubygems_version: 3.1.4
186
+ signing_key:
187
187
  specification_version: 4
188
188
  summary: Fluentd Input plugin to read windows event log.
189
189
  test_files: