logstash-logger-yajl 0.27.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 +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +26 -0
- data/Appraisals +23 -0
- data/CHANGELOG.md +203 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +880 -0
- data/Rakefile +23 -0
- data/gemfiles/rails_3.2.gemfile +9 -0
- data/gemfiles/rails_4.0.gemfile +9 -0
- data/gemfiles/rails_4.1.gemfile +9 -0
- data/gemfiles/rails_4.2.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +9 -0
- data/lib/logstash-event.rb +1 -0
- data/lib/logstash-logger.rb +11 -0
- data/lib/logstash-logger/buffer.rb +336 -0
- data/lib/logstash-logger/configuration.rb +29 -0
- data/lib/logstash-logger/device.rb +67 -0
- data/lib/logstash-logger/device/aws_stream.rb +94 -0
- data/lib/logstash-logger/device/balancer.rb +40 -0
- data/lib/logstash-logger/device/base.rb +73 -0
- data/lib/logstash-logger/device/connectable.rb +131 -0
- data/lib/logstash-logger/device/file.rb +23 -0
- data/lib/logstash-logger/device/firehose.rb +42 -0
- data/lib/logstash-logger/device/io.rb +11 -0
- data/lib/logstash-logger/device/kafka.rb +57 -0
- data/lib/logstash-logger/device/kinesis.rb +44 -0
- data/lib/logstash-logger/device/multi_delegator.rb +36 -0
- data/lib/logstash-logger/device/redis.rb +69 -0
- data/lib/logstash-logger/device/socket.rb +21 -0
- data/lib/logstash-logger/device/stderr.rb +13 -0
- data/lib/logstash-logger/device/stdout.rb +14 -0
- data/lib/logstash-logger/device/tcp.rb +86 -0
- data/lib/logstash-logger/device/udp.rb +12 -0
- data/lib/logstash-logger/device/unix.rb +18 -0
- data/lib/logstash-logger/formatter.rb +51 -0
- data/lib/logstash-logger/formatter/base.rb +73 -0
- data/lib/logstash-logger/formatter/cee.rb +11 -0
- data/lib/logstash-logger/formatter/cee_syslog.rb +22 -0
- data/lib/logstash-logger/formatter/json.rb +11 -0
- data/lib/logstash-logger/formatter/json_lines.rb +11 -0
- data/lib/logstash-logger/formatter/logstash_event.rb +6 -0
- data/lib/logstash-logger/logger.rb +106 -0
- data/lib/logstash-logger/multi_logger.rb +153 -0
- data/lib/logstash-logger/railtie.rb +51 -0
- data/lib/logstash-logger/silenced_logging.rb +83 -0
- data/lib/logstash-logger/tagged_logging.rb +40 -0
- data/lib/logstash-logger/version.rb +3 -0
- data/lib/logstash/event.rb +272 -0
- data/lib/logstash/namespace.rb +15 -0
- data/lib/logstash/util.rb +105 -0
- data/lib/logstash/util/fieldreference.rb +49 -0
- data/logstash-logger.gemspec +42 -0
- data/samples/example.crt +16 -0
- data/samples/example.key +15 -0
- data/samples/file.conf +11 -0
- data/samples/redis.conf +12 -0
- data/samples/ssl.conf +15 -0
- data/samples/syslog.conf +10 -0
- data/samples/tcp.conf +11 -0
- data/samples/udp.conf +11 -0
- data/samples/unix.conf +11 -0
- data/spec/configuration_spec.rb +27 -0
- data/spec/constructor_spec.rb +30 -0
- data/spec/device/balancer_spec.rb +31 -0
- data/spec/device/connectable_spec.rb +74 -0
- data/spec/device/file_spec.rb +15 -0
- data/spec/device/firehose_spec.rb +41 -0
- data/spec/device/io_spec.rb +13 -0
- data/spec/device/kafka_spec.rb +32 -0
- data/spec/device/kinesis_spec.rb +41 -0
- data/spec/device/multi_delegator_spec.rb +31 -0
- data/spec/device/redis_spec.rb +52 -0
- data/spec/device/socket_spec.rb +15 -0
- data/spec/device/stderr_spec.rb +16 -0
- data/spec/device/stdout_spec.rb +31 -0
- data/spec/device/tcp_spec.rb +120 -0
- data/spec/device/udp_spec.rb +9 -0
- data/spec/device/unix_spec.rb +23 -0
- data/spec/device_spec.rb +97 -0
- data/spec/formatter/base_spec.rb +125 -0
- data/spec/formatter/cee_spec.rb +15 -0
- data/spec/formatter/cee_syslog_spec.rb +43 -0
- data/spec/formatter/json_lines_spec.rb +14 -0
- data/spec/formatter/json_spec.rb +10 -0
- data/spec/formatter/logstash_event_spec.rb +10 -0
- data/spec/formatter_spec.rb +79 -0
- data/spec/logger_spec.rb +128 -0
- data/spec/logstash_event_spec.rb +139 -0
- data/spec/multi_logger_spec.rb +59 -0
- data/spec/rails_spec.rb +91 -0
- data/spec/silenced_logging_spec.rb +31 -0
- data/spec/spec_helper.rb +111 -0
- data/spec/syslog_spec.rb +32 -0
- data/spec/tagged_logging_spec.rb +32 -0
- metadata +385 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Formatter::Base do
|
4
|
+
include_context "formatter"
|
5
|
+
|
6
|
+
describe "#call" do
|
7
|
+
context "when event is not cancelled" do
|
8
|
+
it "returns a formatted message" do
|
9
|
+
expect(subject).to receive(:format_event).once.with(instance_of(LogStash::Event)).and_call_original
|
10
|
+
expect(subject.call(severity, time, progname, message)).to be_a(LogStash::Event)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when event is cancelled" do
|
15
|
+
before(:each) do
|
16
|
+
LogStashLogger.configure do |config|
|
17
|
+
config.customize_event(&:cancel)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns `nil`" do
|
22
|
+
expect(subject).not_to receive(:format_event)
|
23
|
+
expect(subject.call(severity, time, progname, message)).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#build_event" do
|
29
|
+
let(:event) { formatted_message }
|
30
|
+
|
31
|
+
describe "message type" do
|
32
|
+
context "string" do
|
33
|
+
it "puts the message into the message field" do
|
34
|
+
expect(event['message']).to eq(message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "JSON string" do
|
39
|
+
let(:message) do
|
40
|
+
{ message: 'test', foo: 'bar' }.to_json
|
41
|
+
end
|
42
|
+
|
43
|
+
it "parses the JSON and merges into the event" do
|
44
|
+
expect(event['message']).to eq('test')
|
45
|
+
expect(event['foo']).to eq('bar')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "hash" do
|
50
|
+
let(:message) do
|
51
|
+
{ 'message' => 'test', 'foo' => 'bar' }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "merges into the event" do
|
55
|
+
expect(event['message']).to eq('test')
|
56
|
+
expect(event['foo']).to eq('bar')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "LogStash::Event" do
|
61
|
+
let(:message) { LogStash::Event.new("message" => "foo") }
|
62
|
+
|
63
|
+
it "returns a clone of the original event" do
|
64
|
+
expect(event['message']).to eq("foo")
|
65
|
+
expect(event).to_not equal(message)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "fallback" do
|
70
|
+
let(:message) { [1, 2, 3] }
|
71
|
+
|
72
|
+
it "calls inspect" do
|
73
|
+
expect(event['message']).to eq(message.inspect)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "extra fields on the event" do
|
79
|
+
it "adds severity" do
|
80
|
+
expect(event['severity']).to eq(severity)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "adds host" do
|
84
|
+
expect(event['host']).to eq(hostname)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "timestamp" do
|
89
|
+
it "ensures time is in ISO8601 format" do
|
90
|
+
expect(event.timestamp).to eq(time.iso8601(3))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "long messages" do
|
95
|
+
|
96
|
+
context "message field is present" do
|
97
|
+
let(:message) { long_message }
|
98
|
+
|
99
|
+
it "truncates long messages when max_message_size is set" do
|
100
|
+
LogStashLogger.configure do |config|
|
101
|
+
config.max_message_size = 2000
|
102
|
+
end
|
103
|
+
|
104
|
+
expect(event['message'].size).to eq(2000)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "event without message field" do
|
109
|
+
let(:message) do
|
110
|
+
{ 'test_field' => 'test', 'foo' => 'bar' }
|
111
|
+
end
|
112
|
+
|
113
|
+
it "still works" do
|
114
|
+
LogStashLogger.configure do |config|
|
115
|
+
config.max_message_size = 2000
|
116
|
+
end
|
117
|
+
|
118
|
+
expect(event['message']).to eq(nil)
|
119
|
+
expect(event['test_field']).to eq('test')
|
120
|
+
expect(event['foo']).to eq('bar')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Formatter::Cee do
|
4
|
+
include_context "formatter"
|
5
|
+
|
6
|
+
it "outputs in CEE format" do
|
7
|
+
expect(formatted_message).to match(/\A@cee:/)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "serializes the LogStash::Event data as JSON" do
|
11
|
+
json_data = formatted_message[/\A@cee:\s?(.*)\z/, 1]
|
12
|
+
json_message = JSON.parse(json_data)
|
13
|
+
expect(json_message["message"]).to eq(message)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Formatter::CeeSyslog do
|
4
|
+
include_context "formatter"
|
5
|
+
|
6
|
+
describe "#call" do
|
7
|
+
let(:facility) { "facility" }
|
8
|
+
|
9
|
+
before do
|
10
|
+
allow(subject).to receive(:build_facility).and_return(facility)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "outputs a facility before the @cee" do
|
14
|
+
expect(formatted_message).to match(/\A#{facility}:@cee:/)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "serializes the LogStash::Event data as JSON" do
|
18
|
+
json_data = formatted_message[/\A#{facility}:@cee:\s?(.*)\Z/, 1]
|
19
|
+
json_message = JSON.parse(json_data)
|
20
|
+
expect(json_message["message"]).to eq(message)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#build_facility" do
|
25
|
+
let(:host) { Socket.gethostname }
|
26
|
+
|
27
|
+
before do
|
28
|
+
formatted_message
|
29
|
+
end
|
30
|
+
|
31
|
+
it "includes hostname and progname" do
|
32
|
+
expect(subject.send(:build_facility, host)).to match(/\A#{host}\s#{progname}\z/)
|
33
|
+
end
|
34
|
+
|
35
|
+
context "without progname" do
|
36
|
+
let(:progname) { nil }
|
37
|
+
|
38
|
+
it "only includes hostname" do
|
39
|
+
expect(subject.send(:build_facility, host)).to match(/\A#{host}\z/)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Formatter::JsonLines do
|
4
|
+
include_context "formatter"
|
5
|
+
|
6
|
+
it "outputs in JSON format" do
|
7
|
+
json_message = JSON.parse(formatted_message)
|
8
|
+
expect(json_message["message"]).to eq(message)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "terminates with a line break" do
|
12
|
+
expect(formatted_message[-1]).to eq("\n")
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Formatter::LogStashEvent do
|
4
|
+
include_context "formatter"
|
5
|
+
|
6
|
+
it "outputs a LogStash::Event" do
|
7
|
+
expect(formatted_message).to be_a LogStash::Event
|
8
|
+
expect(formatted_message["message"]).to eq(message)
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Formatter do
|
4
|
+
describe "#new" do
|
5
|
+
context "built in formatters" do
|
6
|
+
it "returns a new JsonLines formatter" do
|
7
|
+
expect(described_class.new(:json_lines)).to be_a LogStashLogger::Formatter::JsonLines
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns a new Json formatter" do
|
11
|
+
expect(described_class.new(:json)).to be_a LogStashLogger::Formatter::Json
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns a new Cee formatter" do
|
15
|
+
expect(described_class.new(:cee)).to be_a LogStashLogger::Formatter::Cee
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns a new CeeSyslog formatter" do
|
19
|
+
expect(described_class.new(:cee_syslog)).to be_a LogStashLogger::Formatter::CeeSyslog
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a new LogStashEvent formatter" do
|
23
|
+
expect(described_class.new(:logstash_event)).to be_a LogStashLogger::Formatter::LogStashEvent
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "custom formatter" do
|
28
|
+
subject { described_class.new(formatter) }
|
29
|
+
|
30
|
+
context "formatter class" do
|
31
|
+
let(:formatter) { ::Logger::Formatter }
|
32
|
+
|
33
|
+
it "returns a new instance of the class" do
|
34
|
+
expect(subject).to be_a formatter
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "formatter instance" do
|
39
|
+
let(:formatter) { ::Logger::Formatter.new }
|
40
|
+
|
41
|
+
it "returns the same formatter instance" do
|
42
|
+
expect(subject).to eql(formatter)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "supports tagged logging" do
|
46
|
+
expect(subject).to be_a ::LogStashLogger::TaggedLogging::Formatter
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "formatter proc" do
|
51
|
+
let(:formatter) do
|
52
|
+
proc { |severity, time, progname, msg| msg }
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns the same formatter proc" do
|
56
|
+
expect(subject).to eql(formatter)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "supports tagged logging" do
|
60
|
+
expect(subject).to be_a ::LogStashLogger::TaggedLogging::Formatter
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "formatter lambda" do
|
65
|
+
let(:formatter) do
|
66
|
+
->(severity, time, progname, msg) { msg }
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns the same formatter lambda" do
|
70
|
+
expect(subject).to eql(formatter)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "supports tagged logging" do
|
74
|
+
expect(subject).to be_a ::LogStashLogger::TaggedLogging::Formatter
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/logger_spec.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger do
|
4
|
+
include_context 'logger'
|
5
|
+
|
6
|
+
let! :listener do
|
7
|
+
case connection_type
|
8
|
+
when :tcp
|
9
|
+
TCPServer.new(port)
|
10
|
+
when :udp
|
11
|
+
UDPSocket.new.tap {|socket| socket.bind(host, port)}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# The TCP socket written to by the TCP logstash listener server
|
16
|
+
let(:tcp_client) { listener.accept }
|
17
|
+
|
18
|
+
# The logstash event to log
|
19
|
+
let(:logstash_event) do
|
20
|
+
LogStash::Event.new.tap do |event|
|
21
|
+
event['message'] = 'test'
|
22
|
+
event['severity'] = 'INFO'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# The raw input received by the logstash listener
|
27
|
+
let :listener_input do
|
28
|
+
case connection_type
|
29
|
+
when :tcp then tcp_client.readline
|
30
|
+
when :udp then listener.recvfrom(8192)[0]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# The logstash event received by the listener
|
35
|
+
let(:listener_event) { LogStash::Event.new(JSON.parse listener_input) }
|
36
|
+
|
37
|
+
#before(:each) do
|
38
|
+
# Sync socket writes so we can receive them in the listener immediately
|
39
|
+
#@socket = logdev.instance_variable_get(:@dev).send(:connect)
|
40
|
+
#@socket.sync = true
|
41
|
+
#end
|
42
|
+
|
43
|
+
after(:each) do
|
44
|
+
listener.close
|
45
|
+
end
|
46
|
+
|
47
|
+
# The socket that the logger is writing to
|
48
|
+
#let(:socket) { @socket }
|
49
|
+
|
50
|
+
it 'uses a LogStashLogger::Device as the log device' do
|
51
|
+
expect(logdev).to be_a Logger::LogDevice
|
52
|
+
expect(logdev.instance_variable_get(:@dev)).to be_a LogStashLogger::Device::Base
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'takes a string message as input and writes a logstash event' do
|
56
|
+
message = 'test'
|
57
|
+
logger.info(message)
|
58
|
+
|
59
|
+
expect(listener_event['severity']).to eql('INFO')
|
60
|
+
expect(listener_event['message']).to eq(message)
|
61
|
+
expect(listener_event['host']).to eq(hostname)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'takes a logstash-formatted json string as input and writes out a logstash event' do
|
65
|
+
logger.info(logstash_event.to_json)
|
66
|
+
|
67
|
+
expect(listener_event['message']).to eq(logstash_event['message'])
|
68
|
+
expect(listener_event['host']).to eq(hostname)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'takes a LogStash::Event as input and writes it out intact' do
|
72
|
+
logger.warn(logstash_event)
|
73
|
+
|
74
|
+
expect(listener_event['message']).to eq(logstash_event['message'])
|
75
|
+
expect(listener_event['severity']).to eq(logstash_event['severity'])
|
76
|
+
expect(listener_event['@timestamp'].iso8601).to eq(logstash_event.timestamp.iso8601)
|
77
|
+
expect(listener_event['host']).to eq(hostname)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'takes a data hash as input and writes out a logstash event' do
|
81
|
+
data = {
|
82
|
+
'message' => 'test',
|
83
|
+
'severity' => 'INFO',
|
84
|
+
'foo' => 'bar'
|
85
|
+
}
|
86
|
+
|
87
|
+
logger.info(data.dup)
|
88
|
+
|
89
|
+
expect(listener_event['message']).to eq(data["message"])
|
90
|
+
expect(listener_event['severity']).to eq(data['severity'])
|
91
|
+
expect(listener_event['foo']).to eq(data['foo'])
|
92
|
+
expect(listener_event['host']).to eq(hostname)
|
93
|
+
expect(listener_event['@timestamp']).to_not be_nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'takes any object as input and writes a logstash event' do
|
97
|
+
message = Time.now
|
98
|
+
|
99
|
+
logger.info(message)
|
100
|
+
|
101
|
+
expect(listener_event['message']).to eq(message.inspect)
|
102
|
+
expect(listener_event['host']).to eq(hostname)
|
103
|
+
expect(listener_event['severity']).to eq('INFO')
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'allows event to be customized via configuration' do
|
107
|
+
LogStashLogger.configure do |config|
|
108
|
+
config.customize_event do |event|
|
109
|
+
event["test1"] = "response1"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
logger.info("test")
|
114
|
+
|
115
|
+
expect(listener_event["test1"]).to eq("response1")
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'customize_event on instance' do
|
119
|
+
let!(:customize_event) { ->(event){ event['custom'] = 'custom' } }
|
120
|
+
let!(:logger) { LogStashLogger.new(host: host, port: port, type: connection_type, sync: true, customize_event: customize_event)}
|
121
|
+
|
122
|
+
specify 'logger produce messages with custom field' do
|
123
|
+
logger.info('test')
|
124
|
+
expect(listener_event['custom']).to eq('custom')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require "logstash/event"
|
2
|
+
require "insist"
|
3
|
+
|
4
|
+
describe LogStash::Event do
|
5
|
+
subject do
|
6
|
+
LogStash::Event.new(
|
7
|
+
"@timestamp" => Time.iso8601("2013-01-01T00:00:00.000Z"),
|
8
|
+
"type" => "sprintf",
|
9
|
+
"message" => "hello world",
|
10
|
+
"tags" => [ "tag1" ],
|
11
|
+
"source" => "/home/foo",
|
12
|
+
"a" => "b",
|
13
|
+
"c" => {
|
14
|
+
"d" => "f",
|
15
|
+
"e" => {"f" => "g"}
|
16
|
+
},
|
17
|
+
"f" => { "g" => { "h" => "i" } },
|
18
|
+
"j" => {
|
19
|
+
"k1" => "v",
|
20
|
+
"k2" => [ "w", "x" ],
|
21
|
+
"k3" => {"4" => "m"},
|
22
|
+
5 => 6,
|
23
|
+
"5" => 7
|
24
|
+
}
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
context "#sprintf" do
|
29
|
+
it "should report a unix timestamp for %{+%s}" do
|
30
|
+
insist { subject.sprintf("%{+%s}") } == "1356998400"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should report a time with %{+format} syntax", :if => RUBY_ENGINE == "jruby" do
|
34
|
+
insist { subject.sprintf("%{+YYYY}") } == "2013"
|
35
|
+
insist { subject.sprintf("%{+MM}") } == "01"
|
36
|
+
insist { subject.sprintf("%{+HH}") } == "00"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should report fields with %{field} syntax" do
|
40
|
+
insist { subject.sprintf("%{type}") } == "sprintf"
|
41
|
+
insist { subject.sprintf("%{message}") } == subject["message"]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should print deep fields" do
|
45
|
+
insist { subject.sprintf("%{[j][k1]}") } == "v"
|
46
|
+
insist { subject.sprintf("%{[j][k2][0]}") } == "w"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be able to take a non-string for the format" do
|
50
|
+
insist { subject.sprintf(2) } == "2"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "#[]" do
|
55
|
+
it "should fetch data" do
|
56
|
+
insist { subject["type"] } == "sprintf"
|
57
|
+
end
|
58
|
+
it "should fetch fields" do
|
59
|
+
insist { subject["a"] } == "b"
|
60
|
+
insist { subject['c']['d'] } == "f"
|
61
|
+
end
|
62
|
+
it "should fetch deep fields" do
|
63
|
+
insist { subject["[j][k1]"] } == "v"
|
64
|
+
insist { subject["[c][d]"] } == "f"
|
65
|
+
insist { subject['[f][g][h]'] } == "i"
|
66
|
+
insist { subject['[j][k3][4]'] } == "m"
|
67
|
+
insist { subject['[j][5]'] } == 7
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be fast?", :if => ENV["SPEEDTEST"] do
|
72
|
+
2.times do
|
73
|
+
start = Time.now
|
74
|
+
100000.times { subject["[j][k1]"] }
|
75
|
+
puts "Duration: #{Time.now - start}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "#append" do
|
81
|
+
it "should append strings to an array" do
|
82
|
+
subject.append(LogStash::Event.new("message" => "another thing"))
|
83
|
+
insist { subject["message"] } == [ "hello world", "another thing" ]
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should concatenate tags" do
|
87
|
+
subject.append(LogStash::Event.new("tags" => [ "tag2" ]))
|
88
|
+
insist { subject["tags"] } == [ "tag1", "tag2" ]
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when event field is nil" do
|
92
|
+
it "should add single value as string" do
|
93
|
+
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
94
|
+
insist { subject[ "field1" ] } == "append1"
|
95
|
+
end
|
96
|
+
it "should add multi values as array" do
|
97
|
+
subject.append(LogStash::Event.new({"field1" => [ "append1","append2" ]}))
|
98
|
+
insist { subject[ "field1" ] } == [ "append1","append2" ]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when event field is a string" do
|
103
|
+
before { subject[ "field1" ] = "original1" }
|
104
|
+
|
105
|
+
it "should append string to values, if different from current" do
|
106
|
+
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
107
|
+
insist { subject[ "field1" ] } == [ "original1", "append1" ]
|
108
|
+
end
|
109
|
+
it "should not change value, if appended value is equal current" do
|
110
|
+
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
111
|
+
insist { subject[ "field1" ] } == "original1"
|
112
|
+
end
|
113
|
+
it "should concatenate values in an array" do
|
114
|
+
subject.append(LogStash::Event.new({"field1" => [ "append1" ]}))
|
115
|
+
insist { subject[ "field1" ] } == [ "original1", "append1" ]
|
116
|
+
end
|
117
|
+
it "should join array, removing duplicates" do
|
118
|
+
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
119
|
+
insist { subject[ "field1" ] } == [ "original1", "append1" ]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
context "when event field is an array" do
|
123
|
+
before { subject[ "field1" ] = [ "original1", "original2" ] }
|
124
|
+
|
125
|
+
it "should append string values to array, if not present in array" do
|
126
|
+
subject.append(LogStash::Event.new({"field1" => "append1"}))
|
127
|
+
insist { subject[ "field1" ] } == [ "original1", "original2", "append1" ]
|
128
|
+
end
|
129
|
+
it "should not append string values, if the array already contains it" do
|
130
|
+
subject.append(LogStash::Event.new({"field1" => "original1"}))
|
131
|
+
insist { subject[ "field1" ] } == [ "original1", "original2" ]
|
132
|
+
end
|
133
|
+
it "should join array, removing duplicates" do
|
134
|
+
subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]}))
|
135
|
+
insist { subject[ "field1" ] } == [ "original1", "original2", "append1" ]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|