fluent-plugin-parser-winevt_xml 0.2.7 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57f851a356d136b50d477e76df4561e38247128582670da814e9969939683dfe
4
- data.tar.gz: 806c98067fca378bb3fee19b3abcb80e768c0880a982c7a03e0f9262a1a7cd32
3
+ metadata.gz: 3da55ba29ddc8b7c6c0a9e76525ecbe15775e5d682dd7448b329a50715f49c7a
4
+ data.tar.gz: 8a4f47f6b7c1bdc10822eab7cf35751f25c67ba6b156568b49c11f2616ea7644
5
5
  SHA512:
6
- metadata.gz: 0b212dce92cf31f0d0b2bfad75a574ea3465d92fd13798eba9dfdac5acd9e46a6bf4ff3c8cc4c5ed2ee58abbe7f85e8b42e765f0351709dfdd211560be5f9486
7
- data.tar.gz: eacb700f750999d5fa2fbdfb43ec205b63edc2c45078bbb9cdc6e3365a559c2dbc0aa5af2adb320c6cfe15a8dfc172d9679ad5a03202544ad30d511c46d895af
6
+ metadata.gz: a81f1049873ed70f491fe6373ba666d3e0e76d883f49936ce585015089697784e6d95797a9052dde46b20a219b5146c8230417ce181fdd3255dd6005104ac55e
7
+ data.tar.gz: f5aeaba0d414bbc15206f4055f3685e6a49ba781f156e226a523abd560b59e79c4e1eaddb70299e370e0b6ad86c55020f244d26a6ca8fe00d6b5c0f525e87ed7
@@ -3,4 +3,21 @@ updates:
3
3
  - package-ecosystem: 'github-actions'
4
4
  directory: '/'
5
5
  schedule:
6
- interval: 'weekly'
6
+ interval: 'monthly'
7
+ groups:
8
+ # PR: "Security update [package] from [old] to [new]"
9
+ # This PR should be merged in hurry
10
+ security-updates:
11
+ applies-to: security-updates
12
+ patterns:
13
+ - '*'
14
+
15
+ # PR: "Bump [package] from [old] to [new]"
16
+ # No need to be merged this PR in hurry. It is enough to merge
17
+ # once in a month.
18
+ monthly-updates:
19
+ applies-to: version-updates
20
+ patterns:
21
+ - '*'
22
+ # Allow to create PR both of security and normal updates.
23
+ open-pull-requests-limit: 1
@@ -5,27 +5,32 @@ on:
5
5
  branches: [master]
6
6
  pull_request:
7
7
  branches: [master]
8
+ schedule:
9
+ - cron: '0 0 1 * *'
8
10
 
9
11
  jobs:
12
+ ruby-versions:
13
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
14
+ with:
15
+ engine: cruby
16
+ min_version: 3.2
10
17
  test:
18
+ needs: ruby-versions
11
19
  runs-on: ${{ matrix.os }}
12
- continue-on-error: ${{ matrix.experimental }}
20
+ continue-on-error: ${{ matrix.ruby == 'head' }}
13
21
  strategy:
14
22
  fail-fast: false
15
23
  matrix:
16
- ruby: ['3.3', '3.2', '3.1', '3.0', '2.7']
24
+ ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
25
+ exclude:
26
+ - ruby: ${{ github.event_name != 'schedule' && 'head' || '__none__' }}
17
27
  os: [ubuntu-latest]
18
- experimental: [false]
19
- include:
20
- - ruby: head
21
- os: ubuntu-latest
22
- experimental: true
23
28
 
24
29
  name: Ruby ${{ matrix.ruby }} on ${{ matrix.os }}
25
30
  steps:
26
- - uses: actions/checkout@v4
31
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
27
32
  - name: Set up Ruby
28
- uses: ruby/setup-ruby@v1
33
+ uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
29
34
  with:
30
35
  ruby-version: ${{ matrix.ruby }}
31
36
  - name: Install dependencies
@@ -5,21 +5,31 @@ on:
5
5
  branches: [master]
6
6
  pull_request:
7
7
  branches: [master]
8
+ schedule:
9
+ - cron: '0 0 1 * *'
8
10
 
9
11
  jobs:
12
+ ruby-versions:
13
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
14
+ with:
15
+ engine: cruby
16
+ min_version: 3.2
10
17
  test:
18
+ needs: ruby-versions
11
19
  runs-on: ${{ matrix.os }}
12
20
  strategy:
13
21
  fail-fast: false
14
22
  matrix:
15
- ruby: ['3.3', '3.2', '3.1', '3.0', '2.7']
23
+ ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
24
+ exclude:
25
+ - ruby: ${{ github.event_name != 'schedule' && 'head' || '__none__' }}
16
26
  os: [macos-latest]
17
27
 
18
28
  name: Ruby ${{ matrix.ruby }} on ${{ matrix.os }}
19
29
  steps:
20
- - uses: actions/checkout@v4
30
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
21
31
  - name: Set up Ruby
22
- uses: ruby/setup-ruby@v1
32
+ uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
23
33
  with:
24
34
  ruby-version: ${{ matrix.ruby }}
25
35
  - name: Install dependencies
@@ -5,21 +5,31 @@ on:
5
5
  branches: [master]
6
6
  pull_request:
7
7
  branches: [master]
8
+ schedule:
9
+ - cron: '0 0 1 * *'
8
10
 
9
11
  jobs:
12
+ ruby-versions:
13
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
14
+ with:
15
+ engine: cruby
16
+ min_version: 3.2
10
17
  test:
18
+ needs: ruby-versions
11
19
  runs-on: ${{ matrix.os }}
12
20
  strategy:
13
21
  fail-fast: false
14
22
  matrix:
15
- ruby: ['3.3', '3.2', '3.1', '3.0', '2.7']
23
+ ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
24
+ exclude:
25
+ - ruby: ${{ github.event_name != 'schedule' && 'head' || '__none__' }}
16
26
  os:
17
27
  - windows-latest
18
28
  name: Ruby ${{ matrix.ruby }} on ${{ matrix.os }}
19
29
  steps:
20
- - uses: actions/checkout@v4
30
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
21
31
  - name: Set up Ruby
22
- uses: ruby/setup-ruby@v1
32
+ uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
23
33
  with:
24
34
  ruby-version: ${{ matrix.ruby }}
25
35
  - name: Install dependencies
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # fluent-plugin-parser-winevt_xml
2
2
 
3
- [![Build status](https://ci.appveyor.com/api/projects/status/eb0capv0q70u381f/branch/master?svg=true)](https://ci.appveyor.com/project/fluent/fluent-plugin-parser-winevt-xml/branch/master)
4
- [![Build Status](https://travis-ci.org/fluent/fluent-plugin-parser-winevt_xml.svg?branch=master)](https://travis-ci.org/fluent/fluent-plugin-parser-winevt_xml)
3
+ [![Test on macOS](https://github.com/fluent/fluent-plugin-parser-winevt_xml/actions/workflows/macos-test.yaml/badge.svg)](https://github.com/fluent/fluent-plugin-parser-winevt_xml/actions/workflows/macos-test.yaml)
4
+ [![Test on Ubuntu](https://github.com/fluent/fluent-plugin-parser-winevt_xml/actions/workflows/linux-test.yaml/badge.svg)](https://github.com/fluent/fluent-plugin-parser-winevt_xml/actions/workflows/linux-test.yaml)
5
+ [![Test on Windows](https://github.com/fluent/fluent-plugin-parser-winevt_xml/actions/workflows/windows-test.yaml/badge.svg)](https://github.com/fluent/fluent-plugin-parser-winevt_xml/actions/workflows/windows-test.yaml)
5
6
 
6
7
  ## Component
7
8
 
@@ -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-parser-winevt_xml"
7
- spec.version = "0.2.7"
7
+ spec.version = "0.3.0"
8
8
  spec.authors = ["Hiroshi Hatake", "Masahiro Nakagawa"]
9
9
  spec.email = ["cosmo0920.oucc@gmail.com", "repeatedly@gmail.com"]
10
10
  spec.summary = %q{Fluentd Parser plugin to parse XML rendered windows event log.}
@@ -20,8 +20,10 @@ 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.4.0"
23
+ spec.add_development_dependency "nokogiri", ">= 1.12.5"
24
+
23
25
  spec.add_runtime_dependency "fluentd", [">= 0.14.12", "< 2"]
24
- spec.add_runtime_dependency "nokogiri", [">= 1.12.5", "< 1.17"]
26
+ spec.add_runtime_dependency "rexml", "~> 3.2"
25
27
 
26
28
  # gems that aren't default gems as of Ruby 3.4
27
29
  spec.add_runtime_dependency "base64", "~> 0.2"
@@ -1,12 +1,38 @@
1
1
  require 'fluent/plugin/parser'
2
- require 'fluent/plugin/winevt_sax_document'
3
- require 'nokogiri'
4
2
 
5
3
  module Fluent::Plugin
6
4
  class WinevtSAXparser < Parser
7
5
  Fluent::Plugin.register_parser('winevt_sax', self)
8
6
 
9
7
  config_param :preserve_qualifiers, :bool, default: true
8
+ config_param :parser, :enum, list: [:auto, :rexml, :nokogiri], default: :auto
9
+
10
+ def initialize
11
+ super
12
+ @use_nokogiri = false
13
+ end
14
+
15
+ def configure(conf)
16
+ super
17
+ if @parser != :rexml
18
+ begin
19
+ require 'nokogiri'
20
+ require 'fluent/plugin/winevt_sax_document_nokogiri'
21
+ @use_nokogiri = true
22
+ rescue
23
+ if @parser == :nokogiri
24
+ raise Fluent::ConfigError,
25
+ "Nokogiri is required when 'parser nokogiri' is specified, but it isn't installed. " \
26
+ "Install nokogiri, or set 'parser' to 'rexml' or 'auto': #{e.message}"
27
+ end
28
+ end
29
+ end
30
+
31
+ if !@use_nokogiri
32
+ require 'rexml/parsers/sax2parser'
33
+ require 'fluent/plugin/winevt_sax_document_rexml'
34
+ end
35
+ end
10
36
 
11
37
  def winevt_xml?
12
38
  true
@@ -17,9 +43,16 @@ module Fluent::Plugin
17
43
  end
18
44
 
19
45
  def parse(text)
20
- evtxml = WinevtXMLDocument.new(@preserve_qualifiers)
21
- parser = Nokogiri::XML::SAX::Parser.new(evtxml)
22
- parser.parse(text)
46
+ if @use_nokogiri
47
+ evtxml = WinevtXMLDocumentNokogiri.new(@preserve_qualifiers)
48
+ parser = Nokogiri::XML::SAX::Parser.new(evtxml)
49
+ parser.parse(text)
50
+ else
51
+ evtxml = WinevtXMLDocumentREXML.new(@preserve_qualifiers)
52
+ parser = REXML::Parsers::SAX2Parser.new(text)
53
+ parser.listen(evtxml)
54
+ parser.parse
55
+ end
23
56
  time = @estimate_current_event ? Fluent::EventTime.now : nil
24
57
  yield time, evtxml.result
25
58
  end
@@ -1,11 +1,36 @@
1
1
  require 'fluent/plugin/parser'
2
- require 'nokogiri'
3
2
 
4
3
  module Fluent::Plugin
5
4
  class WinevtXMLparser < Parser
6
5
  Fluent::Plugin.register_parser('winevt_xml', self)
7
6
 
8
7
  config_param :preserve_qualifiers, :bool, default: true
8
+ config_param :parser, :enum, list: [:auto, :rexml, :nokogiri], default: :auto
9
+
10
+ def initialize
11
+ super
12
+ @use_nokogiri = false
13
+ end
14
+
15
+ def configure(conf)
16
+ super
17
+ if @parser != :rexml
18
+ begin
19
+ require 'nokogiri'
20
+ @use_nokogiri = true
21
+ rescue
22
+ if @parser == :nokogiri
23
+ raise Fluent::ConfigError,
24
+ "Nokogiri is required when 'parser nokogiri' is specified, but it isn't installed. " \
25
+ "Install nokogiri, or set 'parser' to 'rexml' or 'auto': #{e.message}"
26
+ end
27
+ end
28
+ end
29
+
30
+ if !@use_nokogiri
31
+ require 'rexml/document'
32
+ end
33
+ end
9
34
 
10
35
  def winevt_xml?
11
36
  true
@@ -19,8 +44,10 @@ module Fluent::Plugin
19
44
  (low & 0xffff) | (high & 0xffff) << 16
20
45
  end
21
46
 
22
- def event_id(system_elem)
23
- return (system_elem/'EventID').text rescue nil if @preserve_qualifiers
47
+ def event_id_nokogiri(system_elem)
48
+ if @preserve_qualifiers
49
+ return ((system_elem/'EventID').text rescue nil)
50
+ end
24
51
 
25
52
  qualifiers = (system_elem/'EventID').attribute("Qualifiers").text rescue nil
26
53
  if qualifiers
@@ -32,16 +59,29 @@ module Fluent::Plugin
32
59
  end
33
60
  end
34
61
 
35
- def parse(text)
62
+ def event_id_rexml(system_elem)
63
+ return system_elem.elements['EventID'].text rescue nil if @preserve_qualifiers
64
+
65
+ qualifiers = system_elem.elements['EventID'].attributes['Qualifiers'] rescue nil
66
+ if qualifiers
67
+ event_id = system_elem.elements['EventID'].text
68
+ event_id = MAKELONG(event_id.to_i, qualifiers.to_i)
69
+ event_id.to_s
70
+ else
71
+ system_elem.elements['EventID'].text rescue nil
72
+ end
73
+ end
74
+
75
+ def parse_nokogiri(text)
36
76
  record = {}
37
77
  doc = Nokogiri::XML(text)
38
78
  system_elem = doc/'Event'/'System'
39
79
  record["ProviderName"] = (system_elem/"Provider").attribute("Name").text rescue nil
40
80
  record["ProviderGUID"] = (system_elem/"Provider").attribute("Guid").text rescue nil
41
81
  if @preserve_qualifiers
42
- record["Qualifiers"] = (system_elem/'EventID').attribute("Qualifiers").text rescue nil
82
+ record["Qualifiers"] = (system_elem/'EventID').attribute("Qualifiers").text rescue nil
43
83
  end
44
- record["EventID"] = event_id(system_elem)
84
+ record["EventID"] = event_id_nokogiri(system_elem)
45
85
  record["Level"] = (system_elem/'Level').text rescue nil
46
86
  record["Task"] = (system_elem/'Task').text rescue nil
47
87
  record["Opcode"] = (system_elem/'Opcode').text rescue nil
@@ -57,6 +97,43 @@ module Fluent::Plugin
57
97
  record["UserID"] = (system_elem/'Security').attribute("UserID").text rescue nil
58
98
  record["Version"] = (system_elem/'Version').text rescue nil
59
99
  time = @estimate_current_event ? Fluent::EventTime.now : nil
100
+ return time, record
101
+ end
102
+
103
+ def parse_rexml(text)
104
+ record = {}
105
+ doc = REXML::Document.new(text)
106
+ system_elem = doc.root.elements['System'] rescue nil
107
+ record["ProviderName"] = system_elem.elements['Provider'].attributes['Name'] rescue nil
108
+ record["ProviderGUID"] = system_elem.elements['Provider'].attributes['Guid'] rescue nil
109
+ if @preserve_qualifiers
110
+ record["Qualifiers"] = system_elem.elements['EventID'].attributes['Qualifiers'] rescue nil
111
+ end
112
+ record["EventID"] = event_id_rexml(system_elem)
113
+ record["Level"] = system_elem.elements['Level'].text rescue nil
114
+ record["Task"] = system_elem.elements['Task'].text rescue nil
115
+ record["Opcode"] = system_elem.elements['Opcode'].text rescue nil
116
+ record["Keywords"] = system_elem.elements['Keywords'].text rescue nil
117
+ record["TimeCreated"] = system_elem.elements['TimeCreated'].attributes['SystemTime'] rescue nil
118
+ record["EventRecordID"] = system_elem.elements['EventRecordID'].text rescue nil
119
+ record["ActivityID"] = system_elem.elements['Correlation'].attributes['ActivityID'] rescue nil
120
+ record["RelatedActivityID"] = system_elem.elements['Correlation'].attributes['RelatedActivityID'] rescue nil
121
+ record["ThreadID"] = system_elem.elements['Execution'].attributes['ThreadID'] rescue nil
122
+ record["ProcessID"] = system_elem.elements['Execution'].attributes['ProcessID'] rescue nil
123
+ record["Channel"] = system_elem.elements['Channel'].text rescue nil
124
+ record["Computer"] = system_elem.elements['Computer'].text rescue nil
125
+ record["UserID"] = system_elem.elements['Security'].attributes['UserID'] rescue nil
126
+ record["Version"] = system_elem.elements['Version'].text rescue nil
127
+ time = @estimate_current_event ? Fluent::EventTime.now : nil
128
+ return time, record
129
+ end
130
+
131
+ def parse(text)
132
+ if @use_nokogiri
133
+ time, record = parse_nokogiri(text)
134
+ else
135
+ time, record = parse_rexml(text)
136
+ end
60
137
  yield time, record
61
138
  end
62
139
  end
@@ -1,6 +1,6 @@
1
1
  require 'nokogiri'
2
2
 
3
- class WinevtXMLDocument < Nokogiri::XML::SAX::Document
3
+ class WinevtXMLDocumentNokogiri < Nokogiri::XML::SAX::Document
4
4
  def initialize(preserve_qualifiers)
5
5
  @stack = []
6
6
  @result = {}
@@ -66,6 +66,7 @@ class WinevtXMLDocument < Nokogiri::XML::SAX::Document
66
66
  end
67
67
 
68
68
  def end_element(name, attributes = [])
69
+ @stack.pop
69
70
  end
70
71
 
71
72
  def end_document
@@ -0,0 +1,98 @@
1
+ require 'rexml/parsers/sax2parser'
2
+
3
+ class WinevtXMLDocumentREXML
4
+ def initialize(preserve_qualifiers)
5
+ @stack = []
6
+ @result = {}
7
+ @preserve_qualifiers = preserve_qualifiers
8
+ end
9
+
10
+ def MAKELONG(low, high)
11
+ (low & 0xffff) | (high & 0xffff) << 16
12
+ end
13
+
14
+ def event_id
15
+ if @result.has_key?("Qualifiers")
16
+ qualifiers = @result.delete("Qualifiers")
17
+ event_id = @result['EventID']
18
+ event_id = MAKELONG(event_id.to_i, qualifiers.to_i)
19
+ @result['EventID'] = event_id.to_s
20
+ else
21
+ @result['EventID']
22
+ end
23
+ end
24
+
25
+ def result
26
+ return @result if @preserve_qualifiers
27
+
28
+ if @result
29
+ @result['EventID'] = event_id
30
+ end
31
+ @result
32
+ end
33
+
34
+ def start_element(*args)
35
+ # REXML SAX2 may pass (uri, localname, qname, attributes) or (qname, attributes)
36
+ name = if args.length >= 3
37
+ args[1].to_s
38
+ else
39
+ args[0].to_s
40
+ end
41
+ # normalize namespace/prefix
42
+ name = name.split('}').last if name.include?('}')
43
+ name = name.split(':').last if name.include?(':')
44
+ @stack << name
45
+
46
+ attrs = args.last || {}
47
+
48
+ # helper to fetch attribute value from different attribute containers
49
+ get_attr = lambda do |a, k|
50
+ begin
51
+ if a.is_a?(Array)
52
+ pair = a.find { |p| p && p[0] && p[0].to_s == k.to_s }
53
+ pair && pair[1]
54
+ elsif a.respond_to?(:[])
55
+ a[k] || a[k.to_sym]
56
+ else
57
+ nil
58
+ end
59
+ rescue
60
+ nil
61
+ end
62
+ end
63
+
64
+ if name == "Provider"
65
+ @result["ProviderName"] = get_attr.call(attrs, 'Name')
66
+ @result["ProviderGUID"] = get_attr.call(attrs, 'Guid')
67
+ elsif name == "EventID"
68
+ @result["Qualifiers"] = get_attr.call(attrs, 'Qualifiers')
69
+ elsif name == "TimeCreated"
70
+ @result["TimeCreated"] = get_attr.call(attrs, 'SystemTime')
71
+ elsif name == "Correlation"
72
+ @result["ActivityID"] = get_attr.call(attrs, 'ActivityID')
73
+ @result["RelatedActivityID"] = get_attr.call(attrs, 'RelatedActivityID')
74
+ elsif name == "Execution"
75
+ @result["ProcessID"] = get_attr.call(attrs, 'ProcessID')
76
+ @result["ThreadID"] = get_attr.call(attrs, 'ThreadID')
77
+ elsif name == "Security"
78
+ @result["UserID"] = get_attr.call(attrs, 'UserID')
79
+ end
80
+ end
81
+
82
+ def characters(string)
83
+ element = @stack.last
84
+ return unless element
85
+
86
+ if /^EventID|Level|Task|Opcode|Keywords|EventRecordID|ActivityID|Channel|Computer|Security|Version$/ === element
87
+ @result[element] = (@result[element] || '') + string
88
+ end
89
+ end
90
+
91
+ def end_element(*_)
92
+ @stack.pop
93
+ end
94
+
95
+ def method_missing(name, *args, &block)
96
+ # Ignore any SAX2 events we don't explicitly handle (e.g., progress)
97
+ end
98
+ end
@@ -2,43 +2,56 @@ require_relative '../helper'
2
2
 
3
3
  class WinevtSAXparserTest < Test::Unit::TestCase
4
4
 
5
- def setup
6
- Fluent::Test.setup
7
- end
8
-
9
5
  CONFIG = %[]
10
- XMLLOG = File.open(File.join(__dir__, "..", "data", "eventlog.xml") )
11
6
 
12
7
  def create_driver(conf = CONFIG)
13
8
  Fluent::Test::Driver::Parser.new(Fluent::Plugin::WinevtSAXparser).configure(conf)
14
9
  end
15
10
 
16
- def test_parse
17
- d = create_driver
18
- xml = XMLLOG
19
- expected = {"ProviderName" => "Microsoft-Windows-Security-Auditing",
20
- "ProviderGUID" => "{54849625-5478-4994-A5BA-3E3B0328C30D}",
21
- "EventID" => "4624",
22
- "Qualifiers" => nil,
23
- "Level" => "0",
24
- "Task" => "12544",
25
- "Opcode" => "0",
26
- "Keywords" => "0x8020000000000000",
27
- "TimeCreated" => "2019-06-13T09:21:23.345889600Z",
28
- "EventRecordID" => "80688",
29
- "ActivityID" => "{587F0743-1F71-0006-5007-7F58711FD501}",
30
- "RelatedActivityID" => nil,
31
- "ProcessID" => "912",
32
- "ThreadID" => "24708",
33
- "Channel" => "Security",
34
- "Computer" => "Fluentd-Developing-Windows",
35
- "UserID" => nil,
36
- "Version" => "2",}
37
- d.instance.parse(xml) do |time, record|
38
- assert_equal(expected, record)
11
+ class ParseTest < self
12
+ def setup
13
+ Fluent::Test.setup
14
+ @xml = File.open(File.join(__dir__, "..", "data", "eventlog.xml"))
15
+ end
16
+
17
+ def teardown
18
+ @xml.close
39
19
  end
40
20
 
41
- assert_true(d.instance.winevt_xml?)
21
+ data(
22
+ "auto" => [%[parser auto], true],
23
+ "nokogiri" => [%[parser nokogiri], true],
24
+ "rexml" => [%[parser rexml], false]
25
+ )
26
+ def test_parse(data)
27
+ config, expected_use_nokogiri = data
28
+ d = create_driver(CONFIG + config)
29
+ @xml = File.open(File.join(__dir__, "..", "data", "eventlog.xml"))
30
+ expected = {"ProviderName" => "Microsoft-Windows-Security-Auditing",
31
+ "ProviderGUID" => "{54849625-5478-4994-A5BA-3E3B0328C30D}",
32
+ "EventID" => "4624",
33
+ "Qualifiers" => nil,
34
+ "Level" => "0",
35
+ "Task" => "12544",
36
+ "Opcode" => "0",
37
+ "Keywords" => "0x8020000000000000",
38
+ "TimeCreated" => "2019-06-13T09:21:23.345889600Z",
39
+ "EventRecordID" => "80688",
40
+ "ActivityID" => "{587F0743-1F71-0006-5007-7F58711FD501}",
41
+ "RelatedActivityID" => nil,
42
+ "ProcessID" => "912",
43
+ "ThreadID" => "24708",
44
+ "Channel" => "Security",
45
+ "Computer" => "Fluentd-Developing-Windows",
46
+ "UserID" => nil,
47
+ "Version" => "2",}
48
+ d.instance.parse(@xml) do |time, record|
49
+ assert_equal(expected, record)
50
+ end
51
+
52
+ assert_true(d.instance.winevt_xml?)
53
+ assert_equal(expected_use_nokogiri, d.instance.instance_variable_get(:@use_nokogiri))
54
+ end
42
55
  end
43
56
 
44
57
  class QualifiersTest < self
@@ -50,8 +63,14 @@ class WinevtSAXparserTest < Test::Unit::TestCase
50
63
  @xml.close
51
64
  end
52
65
 
53
- def test_parse_without_qualifiers
54
- d = create_driver CONFIG + %[preserve_qualifiers false]
66
+ data(
67
+ "auto" => [%[parser auto], true],
68
+ "nokogiri" => [%[parser nokogiri], true],
69
+ "rexml" => [%[parser rexml], false]
70
+ )
71
+ def test_parse_without_qualifiers(data)
72
+ config, expected_use_nokogiri = data
73
+ d = create_driver(CONFIG + config + %[\npreserve_qualifiers false])
55
74
  expected = {"ActivityID" => nil,
56
75
  "Channel" => "Application",
57
76
  "Computer" => "DESKTOP-G457RDR",
@@ -74,6 +93,7 @@ class WinevtSAXparserTest < Test::Unit::TestCase
74
93
  end
75
94
 
76
95
  assert_true(d.instance.winevt_xml?)
96
+ assert_equal(expected_use_nokogiri, d.instance.instance_variable_get(:@use_nokogiri))
77
97
  end
78
98
  end
79
99
  end
@@ -2,44 +2,56 @@ require_relative '../helper'
2
2
 
3
3
  class WinevtXMLparserTest < Test::Unit::TestCase
4
4
 
5
- def setup
6
- Fluent::Test.setup
7
- end
8
-
9
5
  CONFIG = %[]
10
- XMLLOG = File.open(File.join(__dir__, "..", "data", "eventlog.xml"))
11
6
 
12
7
  def create_driver(conf = CONFIG)
13
8
  Fluent::Test::Driver::Parser.new(Fluent::Plugin::WinevtXMLparser).configure(conf)
14
9
  end
15
10
 
16
- def test_parse
17
- d = create_driver
18
- xml = XMLLOG
19
- expected = {"ProviderName" => "Microsoft-Windows-Security-Auditing",
20
- "ProviderGUID" => "{54849625-5478-4994-A5BA-3E3B0328C30D}",
21
- "EventID" => "4624",
22
- "Qualifiers" => nil,
23
- "Level" => "0",
24
- "Task" => "12544",
25
- "Opcode" => "0",
26
- "Keywords" => "0x8020000000000000",
27
- "TimeCreated" => "2019-06-13T09:21:23.345889600Z",
28
- "EventRecordID" => "80688",
29
- "ActivityID" => "{587F0743-1F71-0006-5007-7F58711FD501}",
30
- "RelatedActivityID" => nil,
31
- "ProcessID" => "912",
32
- "ThreadID" => "24708",
33
- "Channel" => "Security",
34
- "Computer" => "Fluentd-Developing-Windows",
35
- "UserID" => nil,
36
- "Version" => "2",}
37
- d.instance.parse(xml) do |time, record|
38
- assert_equal(expected, record)
11
+ class ParseTest < self
12
+ def setup
13
+ Fluent::Test.setup
14
+ @xml = File.open(File.join(__dir__, "..", "data", "eventlog.xml"))
15
+ end
16
+
17
+ def teardown
18
+ @xml.close
39
19
  end
40
- xml.close
41
20
 
42
- assert_true(d.instance.winevt_xml?)
21
+ data(
22
+ "auto" => [%[parser auto], true],
23
+ "nokogiri" => [%[parser nokogiri], true],
24
+ "rexml" => [%[parser rexml], false]
25
+ )
26
+ def test_parse(data)
27
+ config, expected_use_nokogiri = data
28
+ d = create_driver(CONFIG + config)
29
+ @xml = File.open(File.join(__dir__, "..", "data", "eventlog.xml"))
30
+ expected = {"ProviderName" => "Microsoft-Windows-Security-Auditing",
31
+ "ProviderGUID" => "{54849625-5478-4994-A5BA-3E3B0328C30D}",
32
+ "EventID" => "4624",
33
+ "Qualifiers" => nil,
34
+ "Level" => "0",
35
+ "Task" => "12544",
36
+ "Opcode" => "0",
37
+ "Keywords" => "0x8020000000000000",
38
+ "TimeCreated" => "2019-06-13T09:21:23.345889600Z",
39
+ "EventRecordID" => "80688",
40
+ "ActivityID" => "{587F0743-1F71-0006-5007-7F58711FD501}",
41
+ "RelatedActivityID" => nil,
42
+ "ProcessID" => "912",
43
+ "ThreadID" => "24708",
44
+ "Channel" => "Security",
45
+ "Computer" => "Fluentd-Developing-Windows",
46
+ "UserID" => nil,
47
+ "Version" => "2",}
48
+ d.instance.parse(@xml) do |time, record|
49
+ assert_equal(expected, record)
50
+ end
51
+
52
+ assert_true(d.instance.winevt_xml?)
53
+ assert_equal(expected_use_nokogiri, d.instance.instance_variable_get(:@use_nokogiri))
54
+ end
43
55
  end
44
56
 
45
57
  class QualifiersTest < self
@@ -51,8 +63,14 @@ class WinevtXMLparserTest < Test::Unit::TestCase
51
63
  @xml.close
52
64
  end
53
65
 
54
- def test_without_qualifiers
55
- d = create_driver CONFIG + %[preserve_qualifiers false]
66
+ data(
67
+ "auto" => [%[parser auto], true],
68
+ "nokogiri" => [%[parser nokogiri], true],
69
+ "rexml" => [%[parser rexml], false]
70
+ )
71
+ def test_parse_without_qualifiers(data)
72
+ config, expected_use_nokogiri = data
73
+ d = create_driver(CONFIG + config + %[\npreserve_qualifiers false])
56
74
  expected = {"ActivityID" => nil,
57
75
  "Channel" => "Application",
58
76
  "Computer" => "DESKTOP-G457RDR",
@@ -75,6 +93,7 @@ class WinevtXMLparserTest < Test::Unit::TestCase
75
93
  end
76
94
 
77
95
  assert_true(d.instance.winevt_xml?)
96
+ assert_equal(expected_use_nokogiri, d.instance.instance_variable_get(:@use_nokogiri))
78
97
  end
79
98
  end
80
99
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-parser-winevt_xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Hatake
8
8
  - Masahiro Nakagawa
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2024-03-07 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
@@ -53,6 +52,20 @@ dependencies:
53
52
  - - "~>"
54
53
  - !ruby/object:Gem::Version
55
54
  version: 3.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.12.5
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.12.5
56
69
  - !ruby/object:Gem::Dependency
57
70
  name: fluentd
58
71
  requirement: !ruby/object:Gem::Requirement
@@ -74,25 +87,19 @@ dependencies:
74
87
  - !ruby/object:Gem::Version
75
88
  version: '2'
76
89
  - !ruby/object:Gem::Dependency
77
- name: nokogiri
90
+ name: rexml
78
91
  requirement: !ruby/object:Gem::Requirement
79
92
  requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: 1.12.5
83
- - - "<"
93
+ - - "~>"
84
94
  - !ruby/object:Gem::Version
85
- version: '1.17'
95
+ version: '3.2'
86
96
  type: :runtime
87
97
  prerelease: false
88
98
  version_requirements: !ruby/object:Gem::Requirement
89
99
  requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- version: 1.12.5
93
- - - "<"
100
+ - - "~>"
94
101
  - !ruby/object:Gem::Version
95
- version: '1.17'
102
+ version: '3.2'
96
103
  - !ruby/object:Gem::Dependency
97
104
  name: base64
98
105
  requirement: !ruby/object:Gem::Requirement
@@ -141,7 +148,8 @@ files:
141
148
  - fluent-plugin-parser-winevt_xml.gemspec
142
149
  - lib/fluent/plugin/parser_winevt_sax.rb
143
150
  - lib/fluent/plugin/parser_winevt_xml.rb
144
- - lib/fluent/plugin/winevt_sax_document.rb
151
+ - lib/fluent/plugin/winevt_sax_document_nokogiri.rb
152
+ - lib/fluent/plugin/winevt_sax_document_rexml.rb
145
153
  - test/data/eventlog-with-qualifiers.xml
146
154
  - test/data/eventlog.xml
147
155
  - test/helper.rb
@@ -151,7 +159,6 @@ homepage: https://github.com/fluent/fluent-plugin-parser-winevt_xml
151
159
  licenses:
152
160
  - Apache-2.0
153
161
  metadata: {}
154
- post_install_message:
155
162
  rdoc_options: []
156
163
  require_paths:
157
164
  - lib
@@ -166,8 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
173
  - !ruby/object:Gem::Version
167
174
  version: '0'
168
175
  requirements: []
169
- rubygems_version: 3.3.26
170
- signing_key:
176
+ rubygems_version: 4.0.10
171
177
  specification_version: 4
172
178
  summary: Fluentd Parser plugin to parse XML rendered windows event log.
173
179
  test_files: