fluent-plugin-windows-eventlog 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -1
- data/fluent-plugin-winevtlog.gemspec +3 -3
- data/lib/fluent/plugin/in_windows_eventlog.rb +51 -196
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4ec43a83a8b3f54edc73e2f26ee4ec43005ba73
|
4
|
+
data.tar.gz: 1f225569741fe7768cf373c8d287f9ff1c11cdab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 343bbf9e3c173ca9707821599602fa767e3d693756c823bcafb5eeea2f87d073eefc3bae34eafaa55a15745f6875cd7c670fcd0c6ac6b096d82a9f842adec025
|
7
|
+
data.tar.gz: 1c30bc7385783027f6d2e3c509e3b811aede90c42cd27bc9da9b786f4de960262892a8a56c3d3b59cd42cc707af303fd499a59f7283ad41de960415a8aa41564
|
data/README.md
CHANGED
@@ -14,11 +14,18 @@ You must use fluentd 'Windows' brach to use me, and it doesn't work on Linux of
|
|
14
14
|
#### fluentd Input plugin for Windows Event Log
|
15
15
|
|
16
16
|
<source>
|
17
|
-
type windows_eventlog
|
17
|
+
@type windows_eventlog
|
18
18
|
channels application,system
|
19
19
|
pos_file c:\temp\mypos
|
20
20
|
read_interval 2
|
21
21
|
tag winevt.raw
|
22
|
+
@id windows_eventlog
|
23
|
+
<storage>
|
24
|
+
@type local # @type local is default.
|
25
|
+
persistent true # persistent true is default.
|
26
|
+
path ./tmp/storage.json # This is required when persistent is true.
|
27
|
+
# Or, please consider to use <system> section's root_dir parameter.
|
28
|
+
</storage>
|
22
29
|
</source>
|
23
30
|
|
24
31
|
|
@@ -4,9 +4,9 @@ $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.2.0"
|
8
8
|
spec.authors = ["okahashi117", "Hiroshi Hatake", "Masahiro Nakagawa"]
|
9
|
-
spec.email = ["naruki_okahashi@jbat.co.jp", "cosmo0920.
|
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.}
|
11
11
|
spec.description = %q{Fluentd Input plugin to read windwos event log.}
|
12
12
|
spec.homepage = "https://github.com/fluent/fluent-plugin-windows-eventlog"
|
@@ -20,6 +20,6 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_development_dependency "bundler"
|
21
21
|
spec.add_development_dependency "rake"
|
22
22
|
spec.add_development_dependency "test-unit", "~> 3.2.0"
|
23
|
-
spec.add_runtime_dependency "fluentd", [">= 0.14.
|
23
|
+
spec.add_runtime_dependency "fluentd", [">= 0.14.12", "< 2"]
|
24
24
|
spec.add_runtime_dependency "win32-eventlog"
|
25
25
|
end
|
@@ -6,8 +6,9 @@ module Fluent::Plugin
|
|
6
6
|
class WindowsEventLogInput < Input
|
7
7
|
Fluent::Plugin.register_input('windows_eventlog', self)
|
8
8
|
|
9
|
-
helpers :timer
|
9
|
+
helpers :timer, :storage
|
10
10
|
|
11
|
+
DEFAULT_STORAGE_TYPE = 'local'
|
11
12
|
KEY_MAP = {"record_number" => :record_number,
|
12
13
|
"time_generated" => :time_generated,
|
13
14
|
"time_written" => :time_written,
|
@@ -21,13 +22,20 @@ module Fluent::Plugin
|
|
21
22
|
|
22
23
|
config_param :tag, :string
|
23
24
|
config_param :read_interval, :time, default: 2
|
24
|
-
config_param :pos_file, :string, default: nil
|
25
|
+
config_param :pos_file, :string, default: nil,
|
26
|
+
obsoleted: "This section is not used anymore. Use 'store_pos' instead."
|
25
27
|
config_param :channels, :array, default: ['Application']
|
26
28
|
config_param :keys, :string, default: []
|
27
29
|
config_param :read_from_head, :bool, default: false
|
28
30
|
config_param :from_encoding, :string, default: nil
|
29
31
|
config_param :encoding, :string, default: nil
|
30
32
|
|
33
|
+
config_section :storage do
|
34
|
+
config_set_default :usage, "positions"
|
35
|
+
config_set_default :@type, DEFAULT_STORAGE_TYPE
|
36
|
+
config_set_default :persistent, true
|
37
|
+
end
|
38
|
+
|
31
39
|
attr_reader :chs
|
32
40
|
|
33
41
|
def initialize
|
@@ -55,6 +63,7 @@ module Fluent::Plugin
|
|
55
63
|
else
|
56
64
|
method(:no_encode_record)
|
57
65
|
end
|
66
|
+
@pos_storage = storage_create(usage: "positions")
|
58
67
|
end
|
59
68
|
|
60
69
|
def configure_encoding
|
@@ -92,59 +101,24 @@ module Fluent::Plugin
|
|
92
101
|
|
93
102
|
def start
|
94
103
|
super
|
95
|
-
|
96
|
-
|
97
|
-
@
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
def shutdown
|
104
|
-
stop_watchers(@tails.keys, true)
|
105
|
-
@pf_file.close if @pf_file
|
106
|
-
super
|
107
|
-
end
|
108
|
-
|
109
|
-
def setup_wacther(ch, pe)
|
110
|
-
wlw = WindowsLogWatcher.new(ch, pe, &method(:receive_lines))
|
111
|
-
wlw.attach do |watcher|
|
112
|
-
wlw.timer_trigger = timer_execute(:in_winevtlog, @read_interval, &watcher.method(:on_notify))
|
113
|
-
end
|
114
|
-
wlw
|
115
|
-
end
|
116
|
-
|
117
|
-
def start_watchers(chs)
|
118
|
-
chs.each { |ch|
|
119
|
-
pe = nil
|
120
|
-
if @pf
|
121
|
-
pe = @pf[ch]
|
122
|
-
if @read_from_head && pe.read_num.zero?
|
123
|
-
el = Win32::EventLog.open(ch)
|
124
|
-
pe.update(el.oldest_record_number-1,1)
|
125
|
-
el.close
|
126
|
-
end
|
104
|
+
@chs.each do |ch|
|
105
|
+
start, num = @pos_storage.get(ch)
|
106
|
+
if @read_from_head || (!num || num.zero?)
|
107
|
+
el = Win32::EventLog.open(ch)
|
108
|
+
@pos_storage.put(ch, [el.oldest_record_number - 1, 1])
|
109
|
+
el.close
|
127
110
|
end
|
128
|
-
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
def stop_watchers(chs, unwatched = false)
|
133
|
-
chs.each { |ch|
|
134
|
-
wlw = @tails.delete(ch)
|
135
|
-
if wlw
|
136
|
-
wlw.unwatched = unwatched
|
137
|
-
close_watcher(wlw)
|
111
|
+
timer_execute("in_windows_eventlog_#{escape_channel(ch)}".to_sym, @read_interval) do
|
112
|
+
on_notify(ch)
|
138
113
|
end
|
139
|
-
|
114
|
+
end
|
140
115
|
end
|
141
116
|
|
142
|
-
def
|
143
|
-
|
144
|
-
# flush_buffer(wlw)
|
117
|
+
def escape_channel(ch)
|
118
|
+
ch.gsub(/[^a-zA-Z0-9]/, '_')
|
145
119
|
end
|
146
120
|
|
147
|
-
def receive_lines(ch, lines
|
121
|
+
def receive_lines(ch, lines)
|
148
122
|
return if lines.empty?
|
149
123
|
begin
|
150
124
|
for r in lines
|
@@ -152,169 +126,50 @@ module Fluent::Plugin
|
|
152
126
|
@keynames.each {|k| h[k]=@receive_handlers.call(r.send(KEY_MAP[k]).to_s)}
|
153
127
|
#h = Hash[@keynames.map {|k| [k, r.send(KEY_MAP[k]).to_s]}]
|
154
128
|
router.emit(@tag, Fluent::Engine.now, h)
|
155
|
-
pe[1] +=1
|
156
|
-
end
|
157
|
-
rescue
|
158
|
-
$log.error "unexpected error", error: $!.to_s
|
159
|
-
$log.error_backtrace
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
|
164
|
-
class WindowsLogWatcher
|
165
|
-
def initialize(ch, pe, &receive_lines)
|
166
|
-
@ch = ch
|
167
|
-
@pe = pe || MemoryPositionEntry.new
|
168
|
-
@receive_lines = receive_lines
|
169
|
-
@timer_trigger = nil
|
170
|
-
end
|
171
|
-
|
172
|
-
attr_reader :ch
|
173
|
-
attr_accessor :unwatched
|
174
|
-
attr_accessor :pe
|
175
|
-
attr_accessor :timer_trigger
|
176
|
-
|
177
|
-
def attach
|
178
|
-
yield self
|
179
|
-
on_notify
|
180
|
-
end
|
181
|
-
|
182
|
-
def detach
|
183
|
-
@timer_trigger.detach if @timer_trigger.attached?
|
184
|
-
end
|
185
|
-
|
186
|
-
def close
|
187
|
-
detach
|
188
|
-
end
|
189
|
-
|
190
|
-
def on_notify
|
191
|
-
el = Win32::EventLog.open(@ch)
|
192
|
-
rl_sn = [el.oldest_record_number, el.total_records]
|
193
|
-
pe_sn = [@pe.read_start, @pe.read_num]
|
194
|
-
# if total_records is zero, oldest_record_number has no meaning.
|
195
|
-
if rl_sn[1] == 0
|
196
|
-
return
|
197
|
-
end
|
198
|
-
|
199
|
-
if pe_sn[0] == 0 && pe_sn[1] == 0
|
200
|
-
@pe.update(rl_sn[0], rl_sn[1])
|
201
|
-
return
|
202
|
-
end
|
203
|
-
|
204
|
-
cur_end = rl_sn[0] + rl_sn[1] -1
|
205
|
-
old_end = pe_sn[0] + pe_sn[1] -1
|
206
|
-
|
207
|
-
if (rl_sn[0] < pe_sn[0])
|
208
|
-
# may be a record number rotated.
|
209
|
-
cur_end += 0xFFFFFFFF
|
210
|
-
end
|
211
|
-
|
212
|
-
if (cur_end < old_end)
|
213
|
-
# something occured.
|
214
|
-
@pe.update(rl_sn[0], rl_sn[1])
|
215
|
-
return
|
216
|
-
end
|
217
|
-
|
218
|
-
read_more = false
|
219
|
-
begin
|
220
|
-
numlines = cur_end - old_end
|
221
|
-
|
222
|
-
winlogs = el.read(Win32::EventLog::SEEK_READ | Win32::EventLog::FORWARDS_READ, old_end + 1)
|
223
|
-
@receive_lines.call(@ch, winlogs, pe_sn)
|
224
|
-
|
225
|
-
@pe.update(pe_sn[0], pe_sn[1])
|
226
|
-
old_end = pe_sn[0] + pe_sn[1] -1
|
227
|
-
end while read_more
|
228
|
-
el.close
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
class PositionFile
|
233
|
-
def initialize(file, map, last_pos)
|
234
|
-
@file = file
|
235
|
-
@map = map
|
236
|
-
@last_pos = last_pos
|
237
|
-
end
|
238
|
-
|
239
|
-
def [](ch)
|
240
|
-
if m = @map[ch]
|
241
|
-
return m
|
242
129
|
end
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
seek = @file.pos
|
247
|
-
@file.write "00000000\t00000000\n"
|
248
|
-
@last_pos = @file.pos
|
249
|
-
@map[ch] = FilePositionEntry.new(@file, seek)
|
250
|
-
end
|
251
|
-
|
252
|
-
# parsing file and rebuild mysself
|
253
|
-
def self.parse(file)
|
254
|
-
map = {}
|
255
|
-
file.pos = 0
|
256
|
-
file.each_line {|line|
|
257
|
-
# check and get a matched line as m
|
258
|
-
m = /^([^\t]+)\t([0-9a-fA-F]+)\t([0-9a-fA-F]+)/.match(line)
|
259
|
-
next unless m
|
260
|
-
ch = m[1]
|
261
|
-
pos = m[2].to_i(16)
|
262
|
-
seek = file.pos - line.bytesize + ch.bytesize + 1
|
263
|
-
map[ch] = FilePositionEntry.new(file, seek)
|
264
|
-
}
|
265
|
-
new(file, map, file.pos)
|
130
|
+
rescue => e
|
131
|
+
log.error "unexpected error", error: e
|
132
|
+
log.error_backtrace
|
266
133
|
end
|
267
134
|
end
|
268
135
|
|
269
|
-
|
270
|
-
|
271
|
-
NUM_OFFSET = 9
|
272
|
-
NUM_SIZE = 8
|
273
|
-
LN_OFFSET = 17
|
274
|
-
SIZE = 18
|
136
|
+
def on_notify(ch)
|
137
|
+
el = Win32::EventLog.open(ch)
|
275
138
|
|
276
|
-
|
277
|
-
|
278
|
-
@seek = seek
|
279
|
-
end
|
139
|
+
current_oldest_record_number = el.oldest_record_number
|
140
|
+
current_total_records = el.total_records
|
280
141
|
|
281
|
-
|
282
|
-
@file.pos = @seek
|
283
|
-
@file.write "%08x\t%08x" % [start, num]
|
284
|
-
end
|
142
|
+
read_start, read_num = @pos_storage.get(ch)
|
285
143
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
raw ? raw.to_i(16) : 0
|
144
|
+
# if total_records is zero, oldest_record_number has no meaning.
|
145
|
+
if current_total_records == 0
|
146
|
+
return
|
290
147
|
end
|
291
148
|
|
292
|
-
|
293
|
-
@
|
294
|
-
|
295
|
-
raw ? raw.to_i(16) : 0
|
149
|
+
if read_start == 0 && read_num == 0
|
150
|
+
@pos_storage.put(ch, [current_oldest_record_number, current_total_records])
|
151
|
+
return
|
296
152
|
end
|
297
|
-
end
|
298
153
|
|
299
|
-
|
300
|
-
|
301
|
-
@start = 0
|
302
|
-
@num = 0
|
303
|
-
end
|
154
|
+
current_end = current_oldest_record_number + current_total_records - 1
|
155
|
+
old_end = read_start + read_num - 1
|
304
156
|
|
305
|
-
|
306
|
-
|
307
|
-
|
157
|
+
if current_oldest_record_number < read_start
|
158
|
+
# may be a record number rotated.
|
159
|
+
current_end += 0xFFFFFFFF
|
308
160
|
end
|
309
161
|
|
310
|
-
|
311
|
-
|
162
|
+
if current_end < old_end
|
163
|
+
# something occured.
|
164
|
+
@pos_storage.put(ch, [current_oldest_record_number, current_total_records])
|
165
|
+
return
|
312
166
|
end
|
313
167
|
|
314
|
-
|
315
|
-
|
316
|
-
|
168
|
+
winlogs = el.read(Win32::EventLog::SEEK_READ | Win32::EventLog::FORWARDS_READ, old_end + 1)
|
169
|
+
receive_lines(ch, winlogs)
|
170
|
+
@pos_storage.put(ch, [read_start, read_num + winlogs.size])
|
171
|
+
ensure
|
172
|
+
el.close
|
317
173
|
end
|
318
|
-
|
319
174
|
end
|
320
175
|
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.2.0
|
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: 2017-
|
13
|
+
date: 2017-03-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -60,7 +60,7 @@ dependencies:
|
|
60
60
|
requirements:
|
61
61
|
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 0.14.
|
63
|
+
version: 0.14.12
|
64
64
|
- - "<"
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: '2'
|
@@ -70,7 +70,7 @@ dependencies:
|
|
70
70
|
requirements:
|
71
71
|
- - ">="
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: 0.14.
|
73
|
+
version: 0.14.12
|
74
74
|
- - "<"
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '2'
|
@@ -91,7 +91,7 @@ dependencies:
|
|
91
91
|
description: Fluentd Input plugin to read windwos event log.
|
92
92
|
email:
|
93
93
|
- naruki_okahashi@jbat.co.jp
|
94
|
-
- cosmo0920.
|
94
|
+
- cosmo0920.oucc@gmail.com
|
95
95
|
- repeatedly@gmail.com
|
96
96
|
executables: []
|
97
97
|
extensions: []
|
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
version: '0'
|
127
127
|
requirements: []
|
128
128
|
rubyforge_project:
|
129
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.5.2
|
130
130
|
signing_key:
|
131
131
|
specification_version: 4
|
132
132
|
summary: Fluentd Input plugin to read windows event log.
|