logstash-logger-yajl 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|