fluent-plugin-parser_cef 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f36fef400e2254cf95714e61ce9e4477a53433ac
4
+ data.tar.gz: d87286621fc65c1698674a1d8ee5f61bd6a0a66f
5
+ SHA512:
6
+ metadata.gz: 7639775cc9ce359b3046a69a7f5eee7cda203e02e82bd4a2adb133afe9223178d8ef6740a74ae98bff6777d7f03578ffcedf01704be3e1ab6e3c15ed44f62194
7
+ data.tar.gz: 8b757928f1a26b54bfcb522f365c48b2c1deeb1a7c54e895ee76bbd406ab983832782af068c3e028085eb501280223d7580d64ed076eb52b4671ac3e4531f46b
data/.gitignore ADDED
@@ -0,0 +1,58 @@
1
+
2
+ # Created by https://www.gitignore.io/api/git,ruby
3
+
4
+ ### Git ###
5
+ *.orig
6
+
7
+
8
+ ### Ruby ###
9
+ *.gem
10
+ *.rbc
11
+ /.config
12
+ /coverage/
13
+ /InstalledFiles
14
+ /pkg/
15
+ /spec/reports/
16
+ /spec/examples.txt
17
+ /test/tmp/
18
+ /test/version_tmp/
19
+ /tmp/
20
+
21
+ # Used by dotenv library to load environment variables.
22
+ .env
23
+
24
+ ## Specific to RubyMotion:
25
+ .dat*
26
+ .repl_history
27
+ build/
28
+ *.bridgesupport
29
+ build-iPhoneOS/
30
+ build-iPhoneSimulator/
31
+
32
+ ## Specific to RubyMotion (use of CocoaPods):
33
+ #
34
+ # We recommend against adding the Pods directory to your .gitignore. However
35
+ # you should judge for yourself, the pros and cons are mentioned at:
36
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
37
+ #
38
+ vendor/Pods/
39
+
40
+ ## Documentation cache and generated files:
41
+ /.yardoc/
42
+ /_yardoc/
43
+ /doc/
44
+ /rdoc/
45
+
46
+ ## Environment normalization:
47
+ /.bundle/
48
+ /vendor/bundle
49
+ /lib/bundler/man/
50
+
51
+ # for a library or gem, you might want to ignore these files since the code is
52
+ # intended to run in multiple environments; otherwise, check them in:
53
+ Gemfile.lock
54
+ .ruby-version
55
+ .ruby-gemset
56
+
57
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
58
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # fluent-plugin-parser_cef
2
+
3
+ Fluentd Parser plugin to parse CEF - common event format -
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```bash
10
+ # for fluentd
11
+ gem install fluent-plugin-parser_cef
12
+
13
+ # for td-agent2
14
+ td-agent-gem install fluent-plugin-parser_cef
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```
20
+ <source>
21
+ @type tail
22
+ tag develop.cef
23
+ path /tmp/fluentd/test.log
24
+ pos_file /tmp/fluentd/test.pos
25
+
26
+ format cef
27
+ #log_format syslog
28
+ #syslog_timestamp_format '\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2}'
29
+ #cef_version 0
30
+ #parse_strict_mode true
31
+ #cef_keyfilename 'config/cef_version_0_keys.yaml'
32
+ #output_raw_field false
33
+ </source>
34
+ ```
35
+
36
+ ## parameters
37
+
38
+ * `log_format` (default: syslog)
39
+
40
+ input log format, currently only 'syslog' is valid
41
+
42
+ * `syslog_timestamp` (default: '\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2}')
43
+
44
+ syslog timestamp format, the default is traditional syslog timestamp
45
+
46
+ * `cef_version` (default: 0)
47
+
48
+ CEF version, this should be 0
49
+
50
+ * `parse_strict_mode` (default: true)
51
+
52
+ if the CEF extensions are the following, the value of the key cs2 should 'foo hoge=fuga'
53
+
54
+ - cs1=test cs2=foo hoge=fuga cs3=bar
55
+
56
+ if parse_strict_mode is false, this is raugh parse, so the value of the key cs2 become 'foo' and non CEF key 'hoge' shown, and the value is 'fuga'
57
+
58
+ * `cef_keyfilename` (default: 'config/cef_version_0_keys.yaml')
59
+
60
+ used when parse_strict_mode is true, this is the array of the valid CEF keys
61
+
62
+ * `output_raw_field` (default: false)
63
+
64
+ append {"raw":\<message itself\>} key-value even if success parsing
65
+
66
+ ## License
67
+
68
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-parser_cef"
7
+ spec.version = File.read("VERSION").strip
8
+ spec.authors = ["Tomoyuki Sugimura"]
9
+ spec.email = ["tomoyuki.sugimura@gmail.com"]
10
+ spec.description = %q{common event format(CEF) parser plugin for fluentd}
11
+ spec.summary = %q{common event format(CEF) parser plugin, currently only 'syslog' format is permitted}
12
+ spec.homepage = "https://github.com/lunardial/fluent-plugin-parser_cef"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_runtime_dependency "fluentd", "~> 0.10", ">= 0.10.43"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ spec.add_development_dependency "rspec-core"
26
+ spec.add_development_dependency "test-unit"
27
+ end
@@ -0,0 +1,173 @@
1
+ # Implementing ArcSight Common Event Format
2
+ # Chapter2: ArcSight Extension Dictionary
3
+
4
+ # CEF Key Names For Event Producers
5
+ cef_key_names_for_event_producers:
6
+ - act
7
+ - app
8
+ - c6a1
9
+ - c6a1Label
10
+ - c6a2
11
+ - c6a2Label
12
+ - c6a3
13
+ - c6a3Label
14
+ - c6a4
15
+ - c6a4Label
16
+ - cfp1
17
+ - cfp1Label
18
+ - cfp2
19
+ - cfp2Label
20
+ - cfp3
21
+ - cfp3Label
22
+ - cfp4
23
+ - cfp4Label
24
+ - cn1
25
+ - cn1Label
26
+ - cn2
27
+ - cn2Label
28
+ - cn3
29
+ - cn3Label
30
+ - cnt
31
+ - cs1
32
+ - cs1Label
33
+ - cs2
34
+ - cs2Label
35
+ - cs3
36
+ - cs3Label
37
+ - cs4
38
+ - cs4Label
39
+ - cs5
40
+ - cs5Label
41
+ - cs6
42
+ - cs6Label
43
+ - destinationDnsDomain
44
+ - destinationServiceName
45
+ - destinationTranslatedAddress
46
+ - destinationTranslatedPort
47
+ - deviceCustomDate1
48
+ - deviceCustomDate1Label
49
+ - deviceCustomDate2
50
+ - deviceCustomDate2Label
51
+ - deviceDirection
52
+ - deviceDnsDomain
53
+ - deviceExternalId
54
+ - deviceFacility
55
+ - deviceInboundInterface
56
+ - deviceNtDomain
57
+ - deviceOutboundInterface
58
+ - devicePayloadId
59
+ - deviceProcessName
60
+ - deviceTranslatedAddress
61
+ - dhost
62
+ - dmac
63
+ - dntdom
64
+ - dpid
65
+ - dpriv
66
+ - dproc
67
+ - dpt
68
+ - dst
69
+ - dtz
70
+ - duid
71
+ - duser
72
+ - dvc
73
+ - dvchost
74
+ - dvcmac
75
+ - dvcpid
76
+ - end
77
+ - externalId
78
+ - fileCreateTime
79
+ - fileHash
80
+ - fileId
81
+ - fileModificationTime
82
+ - filePath
83
+ - filePermission
84
+ - fileType
85
+ - flexDate1
86
+ - flexDate1Label
87
+ - flexNumber1
88
+ - flexNumber1Label
89
+ - flexNumber2
90
+ - flexNumber2Label
91
+ - flexString1
92
+ - flexString1Label
93
+ - flexString2
94
+ - flexString2Label
95
+ - fname
96
+ - fsize
97
+ - in
98
+ - msg
99
+ - oldFileCreateTime
100
+ - oldFileHash
101
+ - oldFileId
102
+ - oldFileModificationTime
103
+ - oldFileName
104
+ - oldFilePath
105
+ - oldFilePermission
106
+ - oldFileSize
107
+ - oldFileType
108
+ - out
109
+ - outcome
110
+ - proto
111
+ - reason
112
+ - request
113
+ - requestClientApplication
114
+ - requestContext
115
+ - requestCookies
116
+ - requestMethod
117
+ - rt
118
+ - shost
119
+ - smac
120
+ - sntdom
121
+ - sourceDnsDomain
122
+ - sourceServiceName
123
+ - sourceTranslatedAddress
124
+ - sourceTranslatedPort
125
+ - spid
126
+ - spriv
127
+ - sproc
128
+ - spt
129
+ - src
130
+ - start
131
+ - suid
132
+ - suser
133
+ - type
134
+
135
+ # CEF Key Names For Event Consumers
136
+ cef_key_names_for_event_consumers:
137
+ - agentDnsDomain
138
+ - agentNtDomain
139
+ - agentTranslatedAddress
140
+ - agentTranslatedZoneExternalID
141
+ - agentTranslatedZoneURI
142
+ - agentZoneExternalID
143
+ - agentZoneURI
144
+ - agt
145
+ - ahost
146
+ - aid
147
+ - amac
148
+ - art
149
+ - at
150
+ - atz
151
+ - av
152
+ - cat
153
+ - customerExternalID
154
+ - customerURI
155
+ - destinationTranslatedZoneExternalID
156
+ - destinationTranslatedZoneURI
157
+ - destinationZoneExternalID
158
+ - destinationZoneURI
159
+ - deviceTranslatedZoneExternalID
160
+ - deviceTranslatedZoneURI
161
+ - deviceZoneExternalID
162
+ - deviceZoneURI
163
+ - dlat
164
+ - dlong
165
+ - eventId
166
+ - rawEvent
167
+ - slat
168
+ - slong
169
+ - sourceTranslatedZoneExternalID
170
+ - sourceTranslatedZoneURI
171
+ - sourceZoneExternalID
172
+ - sourceZoneURI
173
+
@@ -0,0 +1,164 @@
1
+ # -*- coding: utf-8
2
+
3
+ require 'fluent/log'
4
+ require 'fluent/parser'
5
+ require 'time'
6
+ require 'yaml'
7
+
8
+ module Fluent
9
+ class TextParser
10
+ class CommonEventFormatParser < Parser
11
+
12
+ Plugin.register_parser("cef", self)
13
+
14
+ config_param :log_format, :string, :default => "syslog"
15
+ config_param :syslog_timestamp_format, :string, :default => '\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2}'
16
+ config_param :cef_version, :integer, :default => 0
17
+ config_param :parse_strict_mode, :bool, :default => true
18
+ config_param :cef_keyfilename, :string, :default => 'config/cef_version_0_keys.yaml'
19
+ config_param :output_raw_field, :bool, :default => false
20
+
21
+
22
+ def configure(conf)
23
+ super
24
+
25
+ @key_value_format_regexp = /([^\s=]+)=(.*?)(?:(?=[^\s=]+=)|\z)/
26
+ @valid_format_regexp = create_valid_format_regexp
27
+
28
+ begin
29
+ if @parse_strict_mode
30
+ if @cef_keyfilename =~ /^\//
31
+ yaml_fieldinfo = YAML.load_file(@cef_keyfilename)
32
+ else
33
+ yaml_fieldinfo = YAML.load_file("#{File.dirname(File.expand_path(__FILE__))}/#{@cef_keyfilename}")
34
+ end
35
+ @keys_array = []
36
+ yaml_fieldinfo.each {|key, value| @keys_array.concat(value) }
37
+ $log.info "running with strict mode, #{@keys_array.length} keys are valid."
38
+ else
39
+ $log.info "running without strict mode"
40
+ end
41
+ rescue => e
42
+ @parse_strict_mode = false
43
+ $log.warn "running without strict mode because of the following error"
44
+ $log.warn "#{e.message}"
45
+ end
46
+ end
47
+
48
+
49
+ def create_valid_format_regexp()
50
+ case @log_format
51
+ when "syslog"
52
+ syslog_header = /
53
+ (?<syslog_timestamp>#{@syslog_timestamp_format})\s
54
+ (?<syslog_hostname>\S+)\s
55
+ (?<syslog_tag>\S*)\s*
56
+ /x
57
+ cef_header = /
58
+ CEF:(?<cef_version>#{@cef_version})\|
59
+ (?<cef_device_vendor>[^|]*)\|
60
+ (?<cef_device_product>[^|]*)\|
61
+ (?<cef_device_version>[^|]*)\|
62
+ (?<cef_device_event_class_id>[^|]*)\|
63
+ (?<cef_name>[^|]*)\|
64
+ (?<cef_severity>[^|]*)
65
+ /x
66
+ valid_format_regexp = /
67
+ \A
68
+ #{syslog_header}
69
+ #{cef_header}\|
70
+ (?<cef_extension>.*)
71
+ \z
72
+ /x
73
+ else
74
+ raise Fluent::ConfigError, "#{@log_format} is unknown format"
75
+ end
76
+ return Regexp.new(valid_format_regexp)
77
+ end
78
+
79
+
80
+ def parse(text)
81
+ if text.nil? || text.empty?
82
+ if block_given?
83
+ yield nil, nil
84
+ return
85
+ else
86
+ return nil, nil
87
+ end
88
+ end
89
+
90
+ record = {}
91
+ record_overview = @valid_format_regexp.match(text)
92
+ if record_overview.nil?
93
+ if block_given?
94
+ yield Engine.now, { "raw" => text }
95
+ return
96
+ else
97
+ return Engine.now, { "raw" => text }
98
+ end
99
+ end
100
+
101
+ begin
102
+ time = Time.parse(record_overview["syslog_timestamp"]).to_i
103
+ rescue => e
104
+ time = Engine.now
105
+ end
106
+
107
+ begin
108
+ record_overview.names.each {|key| record[key] = record_overview[key] }
109
+ text_cef_extension = record_overview["cef_extension"]
110
+ record.delete("cef_extension")
111
+ unless text_cef_extension.nil?
112
+ record_cef_extension = parse_cef_extension(text_cef_extension)
113
+ record.merge!(record_cef_extension)
114
+ end
115
+ rescue => e
116
+ end
117
+
118
+ record["raw"] = text if @output_raw_field
119
+ if block_given?
120
+ yield time, record
121
+ return
122
+ else
123
+ return time, record
124
+ end
125
+ end
126
+
127
+
128
+ def parse_cef_extension(text)
129
+ record = @parse_strict_mode ? parse_cef_extension_with_strict_mode(text) : parse_cef_extension_without_strict_mode(text)
130
+ end
131
+
132
+
133
+ def parse_cef_extension_with_strict_mode(text)
134
+ record = {}
135
+ begin
136
+ last_valid_key_name = nil
137
+ text.scan(@key_value_format_regexp) do |key, value|
138
+ if @keys_array.include?(key)
139
+ record[key] = value
140
+ record[last_valid_key_name].rstrip! unless last_valid_key_name.nil?
141
+ last_valid_key_name = key
142
+ else
143
+ record[last_valid_key_name].concat("#{key}=#{value}")
144
+ end
145
+ end
146
+ rescue => e
147
+ return {}
148
+ end
149
+ return record
150
+ end
151
+
152
+
153
+ def parse_cef_extension_without_strict_mode(text)
154
+ record = {}
155
+ begin
156
+ text.scan(@key_value_format_regexp) {|key, value| record[key] = value.rstrip }
157
+ rescue => e
158
+ return {}
159
+ end
160
+ return record
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,151 @@
1
+ #-*- coding: utf-8 -*-
2
+
3
+ require 'fluent/plugin/parser_cef'
4
+ require 'fluent/test'
5
+
6
+ RSpec.describe Fluent::TextParser::CommonEventFormatParser do
7
+
8
+ DEFAULT_CONFIGURE = %[
9
+ log_format syslog
10
+ syslog_timestamp_format \\w{3}\\s+\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2}
11
+ cef_version 0
12
+ parse_strict_mode true
13
+ cef_keyfilename 'config/cef_version_0_keys.yaml'
14
+ output_raw_field false
15
+ ]
16
+ def create_driver(conf=DEFAULT_CONFIGURE, tag='test')
17
+ Fluent::Test::ParserTestDriver.new(Fluent::TextParser::CommonEventFormatParser, tag).configure(conf)
18
+ end
19
+
20
+ before :all do
21
+ Fluent::Test.setup
22
+ end
23
+
24
+ before :each do
25
+ @test_driver = create_driver
26
+ end
27
+
28
+ describe "#parse(text)" do
29
+ context "text == nil" do
30
+ let (:text) { nil }
31
+ subject do
32
+ @test_driver.parse(text)
33
+ end
34
+ it { is_expected.to eq [nil, nil] }
35
+ end
36
+ context "text is empty string" do
37
+ let (:text) { "" }
38
+ subject do
39
+ @test_driver.parse(text)
40
+ end
41
+ it { is_expected.to eq [nil, nil] }
42
+ end
43
+ context "text is not syslog format nor CEF" do
44
+ let (:text) { "December 12 10:00:00 hostname tag message" }
45
+ subject do
46
+ @test_driver.parse(text)
47
+ end
48
+ it { is_expected.to contain_exactly(be_an(Integer), {"raw"=>"December 12 10:00:00 hostname tag message"}) }
49
+ end
50
+ context "text is not in syslog format but is CEF" do
51
+ let (:text) { "December 12 10:00:00 hostname tag CEF:0|Vendor|Product|Version|ID|Name|Severity|cs1=test" }
52
+ subject do
53
+ @test_driver.parse(text)
54
+ end
55
+ it { is_expected.to contain_exactly(be_an(Integer), {"raw"=>"December 12 10:00:00 hostname tag CEF:0|Vendor|Product|Version|ID|Name|Severity|cs1=test"}) }
56
+ end
57
+ context "text is syslog format but not CEF" do
58
+ let (:text) { "Dec 12 10:11:12 hostname tag message" }
59
+ subject do
60
+ @test_driver.parse(text)
61
+ end
62
+ it { is_expected.to contain_exactly(be_an(Integer), {"raw"=>"Dec 12 10:11:12 hostname tag message"}) }
63
+ end
64
+ context "text is syslog format and CEF (CEF Extension field is empty)" do
65
+ let (:text) { "Dec 2 03:17:06 hostname tag CEF:0|Vendor|Product|Version|ID|Name|Severity|" }
66
+ subject do
67
+ @test_driver.parse(text)
68
+ end
69
+ it { is_expected.to eq [
70
+ 1480616226,
71
+ {"syslog_timestamp"=>"Dec 2 03:17:06",
72
+ "syslog_hostname"=>"hostname",
73
+ "syslog_tag"=>"tag",
74
+ "cef_version"=>"0",
75
+ "cef_device_vendor"=>"Vendor",
76
+ "cef_device_product"=>"Product",
77
+ "cef_device_version"=>"Version",
78
+ "cef_device_event_class_id"=>"ID",
79
+ "cef_name"=>"Name",
80
+ "cef_severity"=>"Severity"}
81
+ ]}
82
+ end
83
+ context "text is syslog format and CEF (there is only one valid key in the CEF Extension field), Strict mode on" do
84
+ let (:text) { "Dec 2 03:17:06 hostname tag CEF:0|Vendor|Product|Version|ID|Name|Severity|cs1=test" }
85
+ subject do
86
+ @test_driver.parse(text)
87
+ end
88
+ it { is_expected.to eq [
89
+ 1480616226,
90
+ {"syslog_timestamp"=>"Dec 2 03:17:06",
91
+ "syslog_hostname"=>"hostname",
92
+ "syslog_tag"=>"tag",
93
+ "cef_version"=>"0",
94
+ "cef_device_vendor"=>"Vendor",
95
+ "cef_device_product"=>"Product",
96
+ "cef_device_version"=>"Version",
97
+ "cef_device_event_class_id"=>"ID",
98
+ "cef_name"=>"Name",
99
+ "cef_severity"=>"Severity",
100
+ "cs1"=>"test"}
101
+ ]}
102
+ end
103
+ context "text is syslog format and CEF (there is only one valid key in the CEF Extension field), Strict mode off" do
104
+ let (:config) {%[
105
+ parse_strict_mode false
106
+ ]}
107
+ let (:text) { "Dec 2 03:17:06 hostname tag CEF:0|Vendor|Product|Version|ID|Name|Severity|foo=bar" }
108
+ subject do
109
+ @test_driver = create_driver(config)
110
+ @test_driver.parse(text)
111
+ end
112
+ it { is_expected.to eq [
113
+ 1480616226,
114
+ {"syslog_timestamp"=>"Dec 2 03:17:06",
115
+ "syslog_hostname"=>"hostname",
116
+ "syslog_tag"=>"tag",
117
+ "cef_version"=>"0",
118
+ "cef_device_vendor"=>"Vendor",
119
+ "cef_device_product"=>"Product",
120
+ "cef_device_version"=>"Version",
121
+ "cef_device_event_class_id"=>"ID",
122
+ "cef_name"=>"Name",
123
+ "cef_severity"=>"Severity",
124
+ "foo"=>"bar"}
125
+ ]}
126
+ end
127
+ context "text is syslog format and CEF (there is only one valid key in the CEF Extension field), Strict mode on, timestamp is rfc3339" do
128
+ let (:config) {%[
129
+ syslog_timestamp_format \\d{4}-{,1}\\d{2}-{,1}\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+){,1}(?:\\Z|\\+\\d{2}:\\d{2})
130
+ ]}
131
+ let (:text) { "2014-06-07T18:55:09.019283+09:00 hostname tag CEF:0|Vendor|Product|Version|ID|Name|Severity|foo=bar" }
132
+ subject do
133
+ @test_driver = create_driver(config)
134
+ @test_driver.parse(text)
135
+ end
136
+ it { is_expected.to eq [
137
+ 1402134909,
138
+ {"syslog_timestamp"=>"2014-06-07T18:55:09.019283+09:00",
139
+ "syslog_hostname"=>"hostname",
140
+ "syslog_tag"=>"tag",
141
+ "cef_version"=>"0",
142
+ "cef_device_vendor"=>"Vendor",
143
+ "cef_device_product"=>"Product",
144
+ "cef_device_version"=>"Version",
145
+ "cef_device_event_class_id"=>"ID",
146
+ "cef_name"=>"Name",
147
+ "cef_severity"=>"Severity"}
148
+ ]}
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,31 @@
1
+ <source>
2
+ @type tail
3
+ tag develop.cef
4
+ path /tmp/fluentd/test.log
5
+ pos_file /tmp/fluentd/test.pos
6
+
7
+ format cef
8
+ #log_format syslog
9
+ #syslog_timestamp_format '\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2}'
10
+ #cef_version 0
11
+ #parse_strict_mode true
12
+ #cef_keyfilename 'config/cef_version_0_keys.yaml'
13
+ #output_raw_field false
14
+ </source>
15
+
16
+ <match **>
17
+ @type stdout
18
+ </match>
19
+
20
+ #<match cevelop.cef>
21
+ # @type elasticsearch
22
+ # host elasticsearch
23
+ # port 9200
24
+ # logstash_format true
25
+ # logstash_dateformat %Y.%m.%d
26
+ # utc_index true
27
+ # include_tag_key false
28
+ # logstash_prefix develop
29
+ # type_name develop
30
+ # flush_interval 1s
31
+ #</match>
@@ -0,0 +1,108 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+
20
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
21
+ $LOAD_PATH.unshift(File.expand_path('../spec', __FILE__))
22
+
23
+ RSpec.configure do |config|
24
+ # rspec-expectations config goes here. You can use an alternate
25
+ # assertion/expectation library such as wrong or the stdlib/minitest
26
+ # assertions if you prefer.
27
+ config.expect_with :rspec do |expectations|
28
+ # This option will default to `true` in RSpec 4. It makes the `description`
29
+ # and `failure_message` of custom matchers include text for helper methods
30
+ # defined using `chain`, e.g.:
31
+ # be_bigger_than(2).and_smaller_than(4).description
32
+ # # => "be bigger than 2 and smaller than 4"
33
+ # ...rather than:
34
+ # # => "be bigger than 2"
35
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
36
+ end
37
+
38
+ # rspec-mocks config goes here. You can use an alternate test double
39
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
40
+ config.mock_with :rspec do |mocks|
41
+ # Prevents you from mocking or stubbing a method that does not exist on
42
+ # a real object. This is generally recommended, and will default to
43
+ # `true` in RSpec 4.
44
+ mocks.verify_partial_doubles = true
45
+ end
46
+
47
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
48
+ # have no way to turn it off -- the option exists only for backwards
49
+ # compatibility in RSpec 3). It causes shared context metadata to be
50
+ # inherited by the metadata hash of host groups and examples, rather than
51
+ # triggering implicit auto-inclusion in groups with matching metadata.
52
+ config.shared_context_metadata_behavior = :apply_to_host_groups
53
+
54
+ # The settings below are suggested to provide a good initial experience
55
+ # with RSpec, but feel free to customize to your heart's content.
56
+ =begin
57
+ # This allows you to limit a spec run to individual examples or groups
58
+ # you care about by tagging them with `:focus` metadata. When nothing
59
+ # is tagged with `:focus`, all examples get run. RSpec also provides
60
+ # aliases for `it`, `describe`, and `context` that include `:focus`
61
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
62
+ config.filter_run_when_matching :focus
63
+
64
+ # Allows RSpec to persist some state between runs in order to support
65
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
66
+ # you configure your source control system to ignore this file.
67
+ config.example_status_persistence_file_path = "spec/examples.txt"
68
+
69
+ # Limits the available syntax to the non-monkey patched syntax that is
70
+ # recommended. For more details, see:
71
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
72
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
73
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
74
+ config.disable_monkey_patching!
75
+
76
+ # This setting enables warnings. It's recommended, but in some cases may
77
+ # be too noisy due to issues in dependencies.
78
+ config.warnings = true
79
+
80
+ # Many RSpec users commonly either run the entire suite or an individual
81
+ # file, and it's useful to allow more verbose output when running an
82
+ # individual spec file.
83
+ if config.files_to_run.one?
84
+ # Use the documentation formatter for detailed output,
85
+ # unless a formatter has already been configured
86
+ # (e.g. via a command-line flag).
87
+ config.default_formatter = 'doc'
88
+ end
89
+
90
+ # Print the 10 slowest examples and example groups at the
91
+ # end of the spec run, to help surface which specs are running
92
+ # particularly slow.
93
+ config.profile_examples = 10
94
+
95
+ # Run specs in random order to surface order dependencies. If you find an
96
+ # order dependency and want to debug it, you can fix the order by providing
97
+ # the seed, which is printed after each run.
98
+ # --seed 1234
99
+ #config.order = :random
100
+
101
+ # Seed global randomization in this process using the `--seed` CLI option.
102
+ # Setting this allows you to use `--seed` to deterministically reproduce
103
+ # test failures related to randomization by passing the same `--seed` value
104
+ # as the one that triggered the failure.
105
+ Kernel.srand config.seed
106
+ =end
107
+ end
108
+
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-parser_cef
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tomoyuki Sugimura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.10.43
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.10'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.10.43
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.3'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec-core
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: test-unit
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: common event format(CEF) parser plugin for fluentd
104
+ email:
105
+ - tomoyuki.sugimura@gmail.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".rspec"
112
+ - Gemfile
113
+ - LICENSE.txt
114
+ - README.md
115
+ - Rakefile
116
+ - VERSION
117
+ - fluent-plugin-parser_cef.gemspec
118
+ - lib/fluent/plugin/config/cef_version_0_keys.yaml
119
+ - lib/fluent/plugin/parser_cef.rb
120
+ - spec/fluent/plugin/parser_cef_spec.rb
121
+ - spec/sample/fluentd.conf
122
+ - spec/spec_helper.rb
123
+ homepage: https://github.com/lunardial/fluent-plugin-parser_cef
124
+ licenses:
125
+ - MIT
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.5.2
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: common event format(CEF) parser plugin, currently only 'syslog' format is
147
+ permitted
148
+ test_files:
149
+ - spec/fluent/plugin/parser_cef_spec.rb
150
+ - spec/sample/fluentd.conf
151
+ - spec/spec_helper.rb