md-logstasher 1.7.0 → 1.9.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/lib/logstasher/railtie.rb +2 -0
- data/lib/logstasher/version.rb +1 -1
- data/lib/logstasher.rb +52 -0
- data/logstasher.gemspec +1 -0
- data/spec/lib/logstasher/logstasher_spec.rb +204 -5
- data/spec/lib/logstasher/railtie_spec.rb +2 -0
- metadata +17 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fe9fbb482168a2c0e95473e02f2b219cbf116ee4f2006fe6ed15a6cde16bb44
|
4
|
+
data.tar.gz: 9735b52eae692c0b08205949cc65f894a3351e4e6e0275f25cc8a1663d1076eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db9a456790e5bf911c52f135cc1c9ce8f1486f6e47ed1aad91de52ccb9347cf6c86a83f453f8abd774be7836cfb91641f4911be017cfc23dc5463de52788e694
|
7
|
+
data.tar.gz: 4b2e935c1457a249a40297de6330ea991c5095539070acb75fe2f32d5b592039ad4c80b23b9e2ec7870a5211671a1cf188e4f568cc7b22dd207d81f85e941ed5
|
data/lib/logstasher/railtie.rb
CHANGED
@@ -8,6 +8,7 @@ module LogStasher
|
|
8
8
|
config.logstasher.silence_creation_message = true
|
9
9
|
config.logstasher.logger = nil
|
10
10
|
config.logstasher.log_level = ::Logger::INFO
|
11
|
+
config.logstasher.dry_validation_contract = nil
|
11
12
|
|
12
13
|
config.logstasher.metadata = {}
|
13
14
|
config.before_initialize do
|
@@ -20,6 +21,7 @@ module LogStasher
|
|
20
21
|
::LogStasher.logger = options.logger || default_logger
|
21
22
|
::LogStasher.logger.level = options.log_level
|
22
23
|
::LogStasher.metadata = options.metadata
|
24
|
+
::LogStasher.dry_validation_contract = options.dry_validation_contract
|
23
25
|
end
|
24
26
|
|
25
27
|
initializer 'logstasher.load' do
|
data/lib/logstasher/version.rb
CHANGED
data/lib/logstasher.rb
CHANGED
@@ -9,11 +9,44 @@ module LogStasher
|
|
9
9
|
attr_writer :serialize_parameters
|
10
10
|
attr_writer :silence_standard_logging
|
11
11
|
attr_accessor :metadata
|
12
|
+
attr_accessor :default_device
|
13
|
+
|
14
|
+
def load_from_config(config)
|
15
|
+
::LogStasher.logger = ::Logger.new("/dev/null")
|
16
|
+
|
17
|
+
config.each do |key,value|
|
18
|
+
key = key.to_s
|
19
|
+
case key
|
20
|
+
when 'metadata'
|
21
|
+
::LogStasher.metadata = value
|
22
|
+
when 'device'
|
23
|
+
::LogStasher.default_device = ::LogStasher::Device.factory(value)
|
24
|
+
::LogStasher.logger = ::Logger.new(::LogStasher.default_device)
|
25
|
+
when 'include_parameters'
|
26
|
+
::LogStasher.include_parameters = value
|
27
|
+
when 'serialize_parameters'
|
28
|
+
::LogStasher.serialize_parameters = value
|
29
|
+
when 'silence_standard_logging'
|
30
|
+
::LogStasher.silence_standard_logging = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
12
34
|
|
13
35
|
def append_fields(&block)
|
14
36
|
@append_fields_callback = block
|
15
37
|
end
|
16
38
|
|
39
|
+
def dry_validation_contract=(contract)
|
40
|
+
if contract && !contract.is_a?(::Dry::Validation::Contract)
|
41
|
+
raise ArgumentError, "Expected a Dry::Validation::Contract, got #{contract.class}"
|
42
|
+
end
|
43
|
+
@dry_validation_contract = contract
|
44
|
+
end
|
45
|
+
|
46
|
+
def dry_validation_contract
|
47
|
+
@dry_validation_contract
|
48
|
+
end
|
49
|
+
|
17
50
|
def enabled?
|
18
51
|
if @enabled.nil?
|
19
52
|
@enabled = false
|
@@ -59,6 +92,9 @@ module LogStasher
|
|
59
92
|
# example.
|
60
93
|
payload = ::LogStash::Event.new(payload) if as_logstash_event
|
61
94
|
|
95
|
+
# Validate payload if a dry_validation_contract is configured
|
96
|
+
validate_payload(payload) if dry_validation_contract
|
97
|
+
|
62
98
|
logger << payload.to_json + $INPUT_RECORD_SEPARATOR
|
63
99
|
end
|
64
100
|
|
@@ -77,6 +113,22 @@ module LogStasher
|
|
77
113
|
|
78
114
|
@silence_standard_logging
|
79
115
|
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def validate_payload(payload)
|
120
|
+
return unless payload.is_a?(::LogStash::Event) || payload.is_a?(::Hash)
|
121
|
+
|
122
|
+
validation = dry_validation_contract.call(payload.to_hash)
|
123
|
+
|
124
|
+
validation_payload = {
|
125
|
+
dry_validation_success: validation.success?,
|
126
|
+
dry_validation_errors: validation.errors.to_h.to_json
|
127
|
+
}
|
128
|
+
|
129
|
+
return payload.append(validation_payload) if payload.is_a?(::LogStash::Event)
|
130
|
+
return payload.deep_merge!(validation_payload) if payload.is_a?(::Hash)
|
131
|
+
end
|
80
132
|
end
|
81
133
|
end
|
82
134
|
|
data/logstasher.gemspec
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "dry-validation"
|
2
3
|
|
3
4
|
describe ::LogStasher do
|
5
|
+
before(:each) do
|
6
|
+
# Reset state before each test
|
7
|
+
::LogStasher.metadata = {}
|
8
|
+
::LogStasher.dry_validation_contract = nil
|
9
|
+
end
|
4
10
|
describe "#log_as_json" do
|
5
11
|
it "calls the logger with the payload" do
|
6
12
|
expect(::LogStasher.logger).to receive(:<<) do |json|
|
7
13
|
expect(::JSON.parse(json)).to eq("yolo" => "brolo")
|
8
14
|
end
|
9
15
|
|
10
|
-
::LogStasher.log_as_json(
|
16
|
+
::LogStasher.log_as_json({"yolo" => "brolo"})
|
11
17
|
end
|
12
18
|
|
13
19
|
context "with event" do
|
@@ -20,7 +26,7 @@ describe ::LogStasher do
|
|
20
26
|
expect(payload["yolo"]).to eq("brolo")
|
21
27
|
end
|
22
28
|
|
23
|
-
::LogStasher.log_as_json({
|
29
|
+
::LogStasher.log_as_json({"yolo" => "brolo"}, :as_logstash_event => true)
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
@@ -33,7 +39,7 @@ describe ::LogStasher do
|
|
33
39
|
expect(::JSON.parse(json)).to eq("yolo" => "brolo", "metadata" => { "namespace" => "cooldude" })
|
34
40
|
end
|
35
41
|
|
36
|
-
::LogStasher.log_as_json(
|
42
|
+
::LogStasher.log_as_json({"yolo" => "brolo"})
|
37
43
|
end
|
38
44
|
|
39
45
|
it "merges metadata for LogStash::Event types" do
|
@@ -41,7 +47,7 @@ describe ::LogStasher do
|
|
41
47
|
expect(::JSON.parse(json)).to match(a_hash_including("yolo" => "brolo", "metadata" => { "namespace" => "cooldude" }))
|
42
48
|
end
|
43
49
|
|
44
|
-
::LogStasher.log_as_json(::LogStash::Event.new(
|
50
|
+
::LogStasher.log_as_json(::LogStash::Event.new("yolo" => "brolo"))
|
45
51
|
end
|
46
52
|
|
47
53
|
it "does not merge metadata on an array" do
|
@@ -49,8 +55,201 @@ describe ::LogStasher do
|
|
49
55
|
expect(::JSON.parse(json)).to eq([{ "yolo" => "brolo" }])
|
50
56
|
end
|
51
57
|
|
52
|
-
::LogStasher.log_as_json([{
|
58
|
+
::LogStasher.log_as_json([{"yolo" => "brolo"}])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with dry validation contract" do
|
63
|
+
let(:validation_contract) do
|
64
|
+
Class.new(Dry::Validation::Contract) do
|
65
|
+
params do
|
66
|
+
required(:yolo).filled(:string)
|
67
|
+
end
|
68
|
+
end.new
|
69
|
+
end
|
70
|
+
|
71
|
+
before do
|
72
|
+
::LogStasher.metadata = { :namespace => :cooldude }
|
73
|
+
::LogStasher.dry_validation_contract = validation_contract
|
74
|
+
end
|
75
|
+
|
76
|
+
after do
|
77
|
+
::LogStasher.metadata = {}
|
78
|
+
::LogStasher.dry_validation_contract = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
it "validates LogStash::Event payload and appends validation metadata on success" do
|
82
|
+
expect(::LogStasher.logger).to receive(:<<) do |json|
|
83
|
+
payload = ::JSON.parse(json)
|
84
|
+
expect(payload["dry_validation_errors"]).to eq("{}")
|
85
|
+
expect(payload["dry_validation_success"]).to be true
|
86
|
+
expect(payload["yolo"]).to eq("brolo")
|
87
|
+
expect(payload["metadata"]["namespace"]).to eq("cooldude")
|
88
|
+
end
|
89
|
+
|
90
|
+
::LogStasher.log_as_json(::LogStash::Event.new("yolo" => "brolo"))
|
91
|
+
end
|
92
|
+
|
93
|
+
it "validates LogStash::Event payload and appends validation metadata on failure" do
|
94
|
+
expect(::LogStasher.logger).to receive(:<<) do |json|
|
95
|
+
payload = ::JSON.parse(json)
|
96
|
+
expect(payload["dry_validation_errors"]).to eq("{\"yolo\":[\"must be a string\"]}")
|
97
|
+
expect(payload["dry_validation_success"]).to be false
|
98
|
+
expect(payload["yolo"]).to eq(123)
|
99
|
+
expect(payload["metadata"]["namespace"]).to eq("cooldude")
|
100
|
+
end
|
101
|
+
|
102
|
+
::LogStasher.log_as_json(::LogStash::Event.new("yolo" => 123))
|
103
|
+
end
|
104
|
+
|
105
|
+
it "validates hash payload and merges validation metadata on success" do
|
106
|
+
expect(::LogStasher.logger).to receive(:<<) do |json|
|
107
|
+
payload = ::JSON.parse(json)
|
108
|
+
expect(payload["dry_validation_errors"]).to eq("{}")
|
109
|
+
expect(payload["dry_validation_success"]).to be true
|
110
|
+
expect(payload["yolo"]).to eq("brolo")
|
111
|
+
expect(payload["metadata"]["namespace"]).to eq("cooldude")
|
112
|
+
end
|
113
|
+
|
114
|
+
::LogStasher.log_as_json({"yolo" => "brolo"})
|
115
|
+
end
|
116
|
+
|
117
|
+
it "validates hash payload and merges validation metadata on failure" do
|
118
|
+
expect(::LogStasher.logger).to receive(:<<) do |json|
|
119
|
+
payload = ::JSON.parse(json)
|
120
|
+
expect(payload["dry_validation_errors"]).to eq("{\"yolo\":[\"must be a string\"]}")
|
121
|
+
expect(payload["dry_validation_success"]).to be false
|
122
|
+
expect(payload["yolo"]).to eq(123)
|
123
|
+
expect(payload["metadata"]["namespace"]).to eq("cooldude")
|
124
|
+
end
|
125
|
+
|
126
|
+
::LogStasher.log_as_json({"yolo" => 123})
|
127
|
+
end
|
128
|
+
|
129
|
+
it "does not validate array payloads" do
|
130
|
+
expect(::LogStasher.logger).to receive(:<<) do |json|
|
131
|
+
payload = ::JSON.parse(json)
|
132
|
+
expect(payload).to eq([{ "yolo" => "brolo" }])
|
133
|
+
end
|
134
|
+
|
135
|
+
::LogStasher.log_as_json([{"yolo" => "brolo"}])
|
53
136
|
end
|
54
137
|
end
|
55
138
|
end
|
139
|
+
|
140
|
+
describe "#dry_validation_contract=" do
|
141
|
+
it "accepts a valid Dry::Validation::Contract" do
|
142
|
+
contract = Class.new(Dry::Validation::Contract) do
|
143
|
+
params do
|
144
|
+
required(:test).filled(:string)
|
145
|
+
end
|
146
|
+
end.new
|
147
|
+
|
148
|
+
expect { ::LogStasher.dry_validation_contract = contract }.not_to raise_error
|
149
|
+
expect(::LogStasher.dry_validation_contract).to eq(contract)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "accepts nil" do
|
153
|
+
expect { ::LogStasher.dry_validation_contract = nil }.not_to raise_error
|
154
|
+
expect(::LogStasher.dry_validation_contract).to be_nil
|
155
|
+
end
|
156
|
+
|
157
|
+
it "raises ArgumentError for non-Contract objects" do
|
158
|
+
expect { ::LogStasher.dry_validation_contract = "not a contract" }.to raise_error(
|
159
|
+
ArgumentError, "Expected a Dry::Validation::Contract, got String"
|
160
|
+
)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "#dry_validation_contract" do
|
165
|
+
it "returns the stored contract" do
|
166
|
+
contract = double("contract")
|
167
|
+
::LogStasher.instance_variable_set(:@dry_validation_contract, contract)
|
168
|
+
expect(::LogStasher.dry_validation_contract).to eq(contract)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "returns nil when no contract is set" do
|
172
|
+
::LogStasher.instance_variable_set(:@dry_validation_contract, nil)
|
173
|
+
expect(::LogStasher.dry_validation_contract).to be_nil
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#load_from_config" do
|
178
|
+
before(:each) do
|
179
|
+
::LogStasher.metadata = {}
|
180
|
+
::LogStasher.serialize_parameters = true
|
181
|
+
::LogStasher.silence_standard_logging = false
|
182
|
+
end
|
183
|
+
|
184
|
+
it "loads with multiple config keys" do
|
185
|
+
config = {
|
186
|
+
metadata: {
|
187
|
+
namespace: 'kirby',
|
188
|
+
logged_via: 'logstasher',
|
189
|
+
},
|
190
|
+
device: {
|
191
|
+
type: 'stdout'
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
::LogStasher.load_from_config(config)
|
196
|
+
expect(::LogStasher.metadata).to eq({:namespace => 'kirby', :logged_via => 'logstasher'})
|
197
|
+
expect(::LogStasher.default_device).to eq(STDOUT)
|
198
|
+
end
|
199
|
+
|
200
|
+
it "loads metadata" do
|
201
|
+
config = {
|
202
|
+
metadata: {
|
203
|
+
namespace: 'kirby',
|
204
|
+
logged_via: 'logstasher',
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
::LogStasher.load_from_config(config)
|
209
|
+
expect(::LogStasher.metadata).to eq({:namespace => 'kirby', :logged_via => 'logstasher'})
|
210
|
+
end
|
211
|
+
|
212
|
+
it "loads parameters" do
|
213
|
+
config = {
|
214
|
+
include_parameters: false,
|
215
|
+
serialize_parameters: false,
|
216
|
+
silence_standard_logging: true,
|
217
|
+
silence_creation_message: false
|
218
|
+
}
|
219
|
+
|
220
|
+
::LogStasher.load_from_config(config)
|
221
|
+
expect(::LogStasher.instance_variable_get(:@include_parameters)).to be false
|
222
|
+
expect(::LogStasher.instance_variable_get(:@serialize_parameters)).to be false
|
223
|
+
expect(::LogStasher.instance_variable_get(:@silence_standard_logging)).to be true
|
224
|
+
end
|
225
|
+
|
226
|
+
it "loads with a stdout device" do
|
227
|
+
config = {
|
228
|
+
metadata: {
|
229
|
+
namespace: 'kirby',
|
230
|
+
logged_via: 'logstasher',
|
231
|
+
}
|
232
|
+
}
|
233
|
+
|
234
|
+
::LogStasher.load_from_config(config)
|
235
|
+
expect(::LogStasher.metadata).to eq({:namespace => 'kirby', :logged_via => 'logstasher'})
|
236
|
+
end
|
237
|
+
|
238
|
+
it "loads with a syslog device" do
|
239
|
+
config = {
|
240
|
+
device:
|
241
|
+
{
|
242
|
+
type: 'syslog',
|
243
|
+
identity: 'logstasher',
|
244
|
+
facility: 'LOG_LOCAL1',
|
245
|
+
priority: 'LOG_INFO',
|
246
|
+
flags: ['LOG_PID', 'LOG_CONS']
|
247
|
+
}
|
248
|
+
}
|
249
|
+
::LogStasher.load_from_config(config)
|
250
|
+
expect(::LogStasher.metadata).to eq({})
|
251
|
+
expect(::LogStasher.default_device).to be_a ::LogStasher::Device::Syslog
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
56
255
|
end
|
@@ -44,11 +44,13 @@ describe ::LogStasher::Railtie do
|
|
44
44
|
config.include_parameters = "include_parameters"
|
45
45
|
config.serialize_parameters = "serialize_parameters"
|
46
46
|
config.silence_standard_logging = "silence_standard_logging"
|
47
|
+
config.dry_validation_contract = "dry_validation_contract"
|
47
48
|
|
48
49
|
expect(::LogStasher).to receive(:enabled=).with("enabled")
|
49
50
|
expect(::LogStasher).to receive(:include_parameters=).with("include_parameters")
|
50
51
|
expect(::LogStasher).to receive(:serialize_parameters=).with("serialize_parameters")
|
51
52
|
expect(::LogStasher).to receive(:silence_standard_logging=).with("silence_standard_logging")
|
53
|
+
expect(::LogStasher).to receive(:dry_validation_contract=).with("dry_validation_contract")
|
52
54
|
expect(::LogStasher).to receive(:logger=).with(config.logger).and_call_original
|
53
55
|
expect(config.logger).to receive(:level=).with("log_level")
|
54
56
|
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: md-logstasher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Devin Christensen
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: logstash-event
|
@@ -24,6 +23,20 @@ dependencies:
|
|
24
23
|
- - "~>"
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: '1.2'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: dry-validation
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.11.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 1.11.0
|
27
40
|
- !ruby/object:Gem::Dependency
|
28
41
|
name: redis
|
29
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,7 +121,6 @@ homepage: https://github.com/moneydesktop/logstasher
|
|
108
121
|
licenses:
|
109
122
|
- MIT
|
110
123
|
metadata: {}
|
111
|
-
post_install_message:
|
112
124
|
rdoc_options: []
|
113
125
|
require_paths:
|
114
126
|
- lib
|
@@ -123,8 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
135
|
- !ruby/object:Gem::Version
|
124
136
|
version: '0'
|
125
137
|
requirements: []
|
126
|
-
rubygems_version: 3.
|
127
|
-
signing_key:
|
138
|
+
rubygems_version: 3.6.9
|
128
139
|
specification_version: 4
|
129
140
|
summary: Awesome rails logs
|
130
141
|
test_files:
|