logstash-filter-schema_check 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: df4d2d0e171441ff522ca54efa4ae55cfedd9bf722e1c35a2b89282e1a5138e0
4
+ data.tar.gz: 1247588c62c88bccc3075ff5c5396e9b9397719d5a796dc2bb19e1711c0ebddb
5
+ SHA512:
6
+ metadata.gz: 6ab3ef261ed8e59097a6824616e73e394ce798f50f36aeb7ec8e8249b63af5b1444b8d9d822e1f182549ddc9ede72fe374bf2cdc7a48d74996a81e5818b763d7
7
+ data.tar.gz: 639675dfe6fc2250dc8102f13bada82683c8187a0f9ee7504200f16a52a5287efc00a970e849ffdcc5c1ac1110cda3b83f59e8eb837f603c0bb656b559e4f62c
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ - Initial Generation of logstash-filter-schema_check
@@ -0,0 +1,24 @@
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash along its way.
3
+
4
+ Contributors and maintainers:
5
+ * Aaron Mildenstein (untergeek)
6
+ * Darren Foo (stonith)
7
+ * Jordan Sissel (jordansissel)
8
+ * Kurt Hurtado (kurtado)
9
+ * Paul Czarkowski (paulczar)
10
+ * Pier-Hugues Pellerin (ph)
11
+ * Richard Pijnenburg (electrical)
12
+ * Suyog Rao (suyograo)
13
+ * piavlo
14
+
15
+
16
+ Target Team:
17
+ * Justin Bovee (thehybridtechnician)
18
+ * Andrew Orr (andreworr)
19
+ * Thao Vo (tnvo)
20
+
21
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
22
+ Logstash, and you aren't on the list above and want to be, please let us know
23
+ and we'll make sure you're here. Contributions from folks like you are what make
24
+ open source awesome.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (C) 2018 Target Brands, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,116 @@
1
+ # Schema Check Filter for Logstash
2
+
3
+ * This is a plugin for [Logstash](https://github.com/elastic/logstash).
4
+ * This plugin have to be installed on top of the Logstash core pipeline. It is not a stand-alone program.
5
+
6
+ [![Target’s CFC-Open-Source Slack](https://cfc-slack-inv.herokuapp.com/badge.svg?colorA=155799&colorB=159953)](https://cfc-slack-inv.herokuapp.com/)
7
+
8
+
9
+ ## Installing
10
+
11
+ This plugin is to be used with the Logstash system. It is used to check whether an event is compliant with a provided schema.
12
+
13
+ ## Installing plugin
14
+
15
+ ```sh
16
+ bin/logstash-plugin install logstash-filter-schema_check
17
+ ```
18
+
19
+ ### Example Configuration
20
+ ```ruby
21
+ input {
22
+ stdin {}
23
+ }
24
+
25
+ filter {
26
+ schema_check {
27
+ schema_path => "test.json"
28
+
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ ```
35
+
36
+ ### JSON Schema Example
37
+
38
+ ```json
39
+ {
40
+ "type": "object",
41
+ "properties": {
42
+ "message": {
43
+ "oneOf":[
44
+ {
45
+ "format":"ipv4",
46
+ "type":"string"
47
+ },
48
+ {
49
+ "format":"ipv6",
50
+ "type":"string"
51
+ }
52
+ ]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ### Example run and output
59
+ `logstash -e 'input { stdin {} } filter { schema_check { schema_path => "test.json" } } output { stdout {} }'`
60
+
61
+ ```ruby
62
+ ping
63
+ {
64
+ "message" => "ping",
65
+ "@version" => "1",
66
+ "tags" => [
67
+ [0] "schema_invalid"
68
+ ],
69
+ "@timestamp" => 2018-08-06T15:49:19.021Z
70
+ }
71
+ 192.168.10.1
72
+ {
73
+ "message" => "192.168.10.1",
74
+ "@version" => "1",
75
+ "tags" => [
76
+ [0] "schema_valid"
77
+ ],
78
+ "@timestamp" => 2018-08-06T15:49:19.021Z
79
+ }
80
+
81
+ ```
82
+
83
+ ### Example run with debug and output
84
+ `logstash -e 'input { stdin {} } filter { schema_check { schema_path => "test.json" debug_output => true } } output { stdout {} }'`
85
+
86
+ ```ruby
87
+ ping
88
+ {
89
+ "message" => "ping",
90
+ "schema_errors" => [
91
+ [0] "The property '#/message' of type String did not match any of the required schemas. The schema specific errors were:\n\n- oneOf #0:\n - The property '#/message' must be a valid IPv4 address\n- oneOf #1:\n - The property '#/message' must be a valid IPv6 address"
92
+ ],
93
+ "@timestamp" => 2018-08-06T15:53:07.835Z,
94
+ "@version" => "1"
95
+ }
96
+ ```
97
+
98
+ ## Configuration Parameters
99
+
100
+ ### schema
101
+ This is schema provided by hash in the configuration instead of a separate file.
102
+ This isn't as recommended as schemas can get very large, very quickly.
103
+
104
+ ### schema_path
105
+ Path to file with schema
106
+
107
+ ### refresh_interval
108
+ Set refresh interval for reading json schema file for updates
109
+
110
+ ### debug_output
111
+ Enable debug output. This prints validation failures in an array under the
112
+ field schema_errors.
113
+
114
+
115
+ Logstash is a registered trademark of Elasticsearch BV.
116
+
@@ -0,0 +1,161 @@
1
+ # encoding: utf-8
2
+ require "logstash/filters/base"
3
+ require "logstash/namespace"
4
+ require "json"
5
+ require "json-schema"
6
+
7
+ java_import 'java.util.concurrent.locks.ReentrantReadWriteLock'
8
+
9
+ class LogStash::Filters::SchemaCheck < LogStash::Filters::Base
10
+ # configure this filter from your Logstash config.
11
+ #
12
+ # filter {
13
+ # schema_check {
14
+ # schema_path => "test.json"
15
+ # }
16
+ # }
17
+ #
18
+ # {
19
+ # "type": "object",
20
+ # "required": ["message","@version","@timestamp","host"],
21
+ # "properties": {
22
+ # "message": {
23
+ # "oneOf":[
24
+ # {
25
+ # "format":"ipv4",
26
+ # "type":"string"
27
+ # },
28
+ # {
29
+ # "format":"ipv6",
30
+ # "type":"string"
31
+ # }
32
+ # ]
33
+ # }
34
+ # }
35
+ # }
36
+ config_name "schema_check"
37
+
38
+ # Setup json schema in ruby hash inline logstash config
39
+ config :schema, :validate => :string, :default => ""
40
+ # Provide path to the json schema to use
41
+ config :schema_path, :validate => :path
42
+ # Set refresh interval for reading json schema file for updates
43
+ config :refresh_interval, :validate => :number, :default => 300
44
+ # Enable json-schema strict checking
45
+ config :strict, :validate => :boolean, :default => false
46
+ # JSON-Schema fragment option
47
+ config :fragment, :validate => :string
48
+ # JSON-Schema validate schema option
49
+ config :validate_schema, :validate => :boolean, :default => false
50
+ # Enable debug
51
+ config :debug_output, :validate => :boolean, :default => false
52
+ # Schema failures output field
53
+ config :failures_field, :validate => :string, :default => "schema_errors"
54
+ # Enable Schema Error Message
55
+ config :tag_on_failure, :validate => :array, :default => ["_schemacheckfailure"]
56
+
57
+ public
58
+ def register
59
+ rw_lock = java.util.concurrent.locks.ReentrantReadWriteLock.new
60
+ @read_lock = rw_lock.readLock
61
+ @write_lock = rw_lock.writeLock
62
+
63
+ if @schema_path && !@schema.empty?
64
+ raise LogStash::ConfigurationError, I18n.t(
65
+ "logstash.agent.configuration.invalid_plugin_register",
66
+ :plugin => "filter",
67
+ :type => "schema_check",
68
+ :error => "The configuration options 'schema' and 'schema_path' are mutually exclusive"
69
+ )
70
+ end
71
+
72
+ if @schema_path
73
+ @next_refresh = Time.now + @refresh_interval
74
+ raise_exception = true
75
+ lock_for_write { load_schema(raise_exception) }
76
+ end
77
+
78
+ @logger.debug? and @logger.debug("#{self.class.name}: schema - ", :schema => @schema)
79
+ end # def register
80
+
81
+ public
82
+ def filter(event)
83
+ if @schema_path
84
+ if needs_refresh?
85
+ lock_for_write do
86
+ if needs_refresh?
87
+ load_schema
88
+ @next_refresh = Time.now + @refresh_interval
89
+ @logger.info("refreshing schema file")
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ begin
96
+ event_obj = event.to_hash
97
+ if @debug_output
98
+ output = JSON::Validator.fully_validate(@schema, event_obj, :strict => @strict, :fragment => @fragment, :validate_schema => validate_schema)
99
+ unless output.empty?
100
+ @tag_on_failure.each {|tag| event.tag(tag)}
101
+ event.set(@failures_field, output)
102
+ end
103
+ else
104
+ unless JSON::Validator.validate(@schema, event_obj, :strict => @strict, :fragment => @fragment, :validate_schema => validate_schema)
105
+ @tag_on_failure.each {|tag| event.tag(tag)}
106
+ end
107
+ end
108
+ filter_matched(event)
109
+ rescue Exception => e
110
+ @logger.error("Something went wrong when checking schema", :exception => e, :event => event)
111
+ end
112
+ end # def filter
113
+
114
+ private
115
+ def lock_for_read
116
+ @read_lock.lock
117
+ begin
118
+ yield
119
+ ensure
120
+ @read_lock.unlock
121
+ end
122
+ end
123
+
124
+ private
125
+ def lock_for_write
126
+ @write_lock.lock
127
+ begin
128
+ yield
129
+ ensure
130
+ @write_lock.unlock
131
+ end
132
+ end
133
+
134
+ private
135
+ def load_schema(raise_exception=false)
136
+ if !File.exists?(@schema_path)
137
+ @logger.warn("schema file read failure", :path => @schema_path)
138
+ return
139
+ end
140
+ refresh_schema!(JSON.parse(File.read(@schema_path)))
141
+ end
142
+
143
+ private
144
+ def refresh_schema!(data)
145
+ @schema = data
146
+ end
147
+
148
+ def loading_exception(e, raise_exception=false)
149
+ msg = "#{self.class.name}: #{e.message} when loading schema file at #{@schema_path}"
150
+ if raise_exception
151
+ raise RuntimeError.new(msg)
152
+ else
153
+ @logger.warn("#{msg}, continuing with old schema", :schema_path => @schema_path)
154
+ end
155
+ end
156
+
157
+ private
158
+ def needs_refresh?
159
+ @next_refresh < Time.now
160
+ end
161
+ end # class LogStash::Filters::JsonSchema
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "logstash-filter-schema_check"
3
+ s.version = "0.1.0"
4
+ s.licenses = ['Apache License (2.0)']
5
+ s.summary = 'A Logstash plugin to validate JSON schemas'
6
+ s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
7
+ s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
8
+ s.authors = ["Elastic", "Justin Bovee"]
9
+ s.email = 'jbovee@thehybridtech.com'
10
+ s.require_paths = ['lib']
11
+
12
+ # Files
13
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
14
+ # Tests
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+
17
+ # Special flag to let us know this is actually a logstash plugin
18
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
19
+
20
+ # Gem dependencies
21
+ s.add_runtime_dependency "json-schema"
22
+ s.add_runtime_dependency 'logstash-core-plugin-api', '>= 2.1.1', '<= 2.99'
23
+
24
+ s.add_development_dependency 'rspec'
25
+ s.add_development_dependency 'logstash-devutils', "~> 1.3", ">= 1.3.1"
26
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/filters/schema_check"
4
+
5
+ describe LogStash::Filters::SchemaCheck do
6
+
7
+ context 'Inline Schema' do
8
+ describe "Test schema provided inline" do
9
+ config <<-CONFIG
10
+ filter {
11
+ schema_check {
12
+ schema => '{"type":"object","properties":{"ip_address":{"oneOf":[{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}]}}}'
13
+ }
14
+ }
15
+ CONFIG
16
+
17
+ sample("ip_address" => "I_AM_NOT_AN_IP") do
18
+ insist { subject.get("tags") } == ["_schemacheckfailure"]
19
+ end
20
+ sample("ip_address" => "10.0.0.1") do
21
+ insist { subject.get("tags") } != ["_schemacheckfailure"]
22
+ end
23
+ end
24
+
25
+ describe "Test schema debug functionality inline" do
26
+ config <<-CONFIG
27
+ filter {
28
+ schema_check {
29
+ schema => '{"type":"object","properties":{"ip_address":{"oneOf":[{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}]}}}'
30
+ debug_output => true
31
+ }
32
+ }
33
+ CONFIG
34
+
35
+ sample("ip_address" => "I_AM_NOT_AN_IP") do
36
+ insist { subject.get("tags") } == ["_schemacheckfailure"]
37
+ insist { subject.get("schema_errors").to be(Array) }
38
+ end
39
+ sample("ip_address" => "10.0.0.1") do
40
+ insist { subject.get("tags") } != ["_schemacheckfailure"]
41
+ end
42
+ end
43
+ end
44
+
45
+ context "File Schema" do
46
+ schema_file = File.join(File.dirname(__FILE__), "..", "fixtures", "test.json")
47
+ describe "Test schema provided from file" do
48
+ config <<-CONFIG
49
+ filter {
50
+ schema_check {
51
+ "schema_path" => "#{schema_file}"
52
+ }
53
+ }
54
+ CONFIG
55
+
56
+ sample("ip_address" => "I_AM_NOT_AN_IP") do
57
+ insist { subject.get("tags") } == ["_schemacheckfailure"]
58
+ end
59
+ sample("ip_address" => "10.0.0.1") do
60
+ insist { subject.get("tags") } != ["_schemacheckfailure"]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,17 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "ip_address": {
5
+ "oneOf":[
6
+ {
7
+ "format":"ipv4",
8
+ "type":"string"
9
+ },
10
+ {
11
+ "format":"ipv6",
12
+ "type":"string"
13
+ }
14
+ ]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-filter-schema_check
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Elastic
8
+ - Justin Bovee
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2018-10-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ name: json-schema
21
+ prerelease: false
22
+ type: :runtime
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.1.1
34
+ - - "<="
35
+ - !ruby/object:Gem::Version
36
+ version: '2.99'
37
+ name: logstash-core-plugin-api
38
+ prerelease: false
39
+ type: :runtime
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.1.1
45
+ - - "<="
46
+ - !ruby/object:Gem::Version
47
+ version: '2.99'
48
+ - !ruby/object:Gem::Dependency
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ name: rspec
55
+ prerelease: false
56
+ type: :development
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.3'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 1.3.1
71
+ name: logstash-devutils
72
+ prerelease: false
73
+ type: :development
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - "~>"
77
+ - !ruby/object:Gem::Version
78
+ version: '1.3'
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 1.3.1
82
+ description: This gem is a Logstash plugin required to be installed on top of the
83
+ Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
84
+ gem is not a stand-alone program
85
+ email: jbovee@thehybridtech.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - CONTRIBUTORS
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.md
95
+ - lib/logstash/filters/schema_check.rb
96
+ - logstash-filter-schema_check.gemspec
97
+ - spec/filters/schema_check_spec.rb
98
+ - spec/fixtures/test.json
99
+ - spec/spec_helper.rb
100
+ homepage: http://www.elastic.co/guide/en/logstash/current/index.html
101
+ licenses:
102
+ - Apache License (2.0)
103
+ metadata:
104
+ logstash_plugin: 'true'
105
+ logstash_group: filter
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.7.6
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: A Logstash plugin to validate JSON schemas
126
+ test_files:
127
+ - spec/filters/schema_check_spec.rb
128
+ - spec/fixtures/test.json
129
+ - spec/spec_helper.rb