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.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +1156 -0
  5. data/.travis.yml +26 -0
  6. data/Appraisals +23 -0
  7. data/CHANGELOG.md +203 -0
  8. data/Gemfile +6 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +880 -0
  11. data/Rakefile +23 -0
  12. data/gemfiles/rails_3.2.gemfile +9 -0
  13. data/gemfiles/rails_4.0.gemfile +9 -0
  14. data/gemfiles/rails_4.1.gemfile +9 -0
  15. data/gemfiles/rails_4.2.gemfile +9 -0
  16. data/gemfiles/rails_5.0.gemfile +9 -0
  17. data/gemfiles/rails_5.1.gemfile +9 -0
  18. data/lib/logstash-event.rb +1 -0
  19. data/lib/logstash-logger.rb +11 -0
  20. data/lib/logstash-logger/buffer.rb +336 -0
  21. data/lib/logstash-logger/configuration.rb +29 -0
  22. data/lib/logstash-logger/device.rb +67 -0
  23. data/lib/logstash-logger/device/aws_stream.rb +94 -0
  24. data/lib/logstash-logger/device/balancer.rb +40 -0
  25. data/lib/logstash-logger/device/base.rb +73 -0
  26. data/lib/logstash-logger/device/connectable.rb +131 -0
  27. data/lib/logstash-logger/device/file.rb +23 -0
  28. data/lib/logstash-logger/device/firehose.rb +42 -0
  29. data/lib/logstash-logger/device/io.rb +11 -0
  30. data/lib/logstash-logger/device/kafka.rb +57 -0
  31. data/lib/logstash-logger/device/kinesis.rb +44 -0
  32. data/lib/logstash-logger/device/multi_delegator.rb +36 -0
  33. data/lib/logstash-logger/device/redis.rb +69 -0
  34. data/lib/logstash-logger/device/socket.rb +21 -0
  35. data/lib/logstash-logger/device/stderr.rb +13 -0
  36. data/lib/logstash-logger/device/stdout.rb +14 -0
  37. data/lib/logstash-logger/device/tcp.rb +86 -0
  38. data/lib/logstash-logger/device/udp.rb +12 -0
  39. data/lib/logstash-logger/device/unix.rb +18 -0
  40. data/lib/logstash-logger/formatter.rb +51 -0
  41. data/lib/logstash-logger/formatter/base.rb +73 -0
  42. data/lib/logstash-logger/formatter/cee.rb +11 -0
  43. data/lib/logstash-logger/formatter/cee_syslog.rb +22 -0
  44. data/lib/logstash-logger/formatter/json.rb +11 -0
  45. data/lib/logstash-logger/formatter/json_lines.rb +11 -0
  46. data/lib/logstash-logger/formatter/logstash_event.rb +6 -0
  47. data/lib/logstash-logger/logger.rb +106 -0
  48. data/lib/logstash-logger/multi_logger.rb +153 -0
  49. data/lib/logstash-logger/railtie.rb +51 -0
  50. data/lib/logstash-logger/silenced_logging.rb +83 -0
  51. data/lib/logstash-logger/tagged_logging.rb +40 -0
  52. data/lib/logstash-logger/version.rb +3 -0
  53. data/lib/logstash/event.rb +272 -0
  54. data/lib/logstash/namespace.rb +15 -0
  55. data/lib/logstash/util.rb +105 -0
  56. data/lib/logstash/util/fieldreference.rb +49 -0
  57. data/logstash-logger.gemspec +42 -0
  58. data/samples/example.crt +16 -0
  59. data/samples/example.key +15 -0
  60. data/samples/file.conf +11 -0
  61. data/samples/redis.conf +12 -0
  62. data/samples/ssl.conf +15 -0
  63. data/samples/syslog.conf +10 -0
  64. data/samples/tcp.conf +11 -0
  65. data/samples/udp.conf +11 -0
  66. data/samples/unix.conf +11 -0
  67. data/spec/configuration_spec.rb +27 -0
  68. data/spec/constructor_spec.rb +30 -0
  69. data/spec/device/balancer_spec.rb +31 -0
  70. data/spec/device/connectable_spec.rb +74 -0
  71. data/spec/device/file_spec.rb +15 -0
  72. data/spec/device/firehose_spec.rb +41 -0
  73. data/spec/device/io_spec.rb +13 -0
  74. data/spec/device/kafka_spec.rb +32 -0
  75. data/spec/device/kinesis_spec.rb +41 -0
  76. data/spec/device/multi_delegator_spec.rb +31 -0
  77. data/spec/device/redis_spec.rb +52 -0
  78. data/spec/device/socket_spec.rb +15 -0
  79. data/spec/device/stderr_spec.rb +16 -0
  80. data/spec/device/stdout_spec.rb +31 -0
  81. data/spec/device/tcp_spec.rb +120 -0
  82. data/spec/device/udp_spec.rb +9 -0
  83. data/spec/device/unix_spec.rb +23 -0
  84. data/spec/device_spec.rb +97 -0
  85. data/spec/formatter/base_spec.rb +125 -0
  86. data/spec/formatter/cee_spec.rb +15 -0
  87. data/spec/formatter/cee_syslog_spec.rb +43 -0
  88. data/spec/formatter/json_lines_spec.rb +14 -0
  89. data/spec/formatter/json_spec.rb +10 -0
  90. data/spec/formatter/logstash_event_spec.rb +10 -0
  91. data/spec/formatter_spec.rb +79 -0
  92. data/spec/logger_spec.rb +128 -0
  93. data/spec/logstash_event_spec.rb +139 -0
  94. data/spec/multi_logger_spec.rb +59 -0
  95. data/spec/rails_spec.rb +91 -0
  96. data/spec/silenced_logging_spec.rb +31 -0
  97. data/spec/spec_helper.rb +111 -0
  98. data/spec/syslog_spec.rb +32 -0
  99. data/spec/tagged_logging_spec.rb +32 -0
  100. metadata +385 -0
@@ -0,0 +1,13 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::IO do
4
+ include_context 'device'
5
+
6
+ subject { io_device }
7
+
8
+ it "writes to the IO object" do
9
+ expect(subject.to_io).to eq(io)
10
+ expect(io).to receive(:write).once
11
+ subject.write("test")
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::Kafka do
4
+ include_context 'device'
5
+
6
+ let(:producer) { double("Poseidon::Producer") }
7
+
8
+ before(:each) do
9
+ allow(Poseidon::Producer).to receive(:new) { producer }
10
+ end
11
+
12
+ it "writes to a Kafka topic" do
13
+ expect(producer).to receive(:send_messages)
14
+ kafka_device.write "foo"
15
+ end
16
+
17
+ it "defaults the Kafka hosts to ['localhost:9092']" do
18
+ expect(kafka_device.hosts).to eq(['localhost:9092'])
19
+ end
20
+
21
+ it "defaults the Kafka topic to 'logstash'" do
22
+ expect(kafka_device.topic).to eq('logstash')
23
+ end
24
+
25
+ it "defaults the Kafka producer to 'logstash-logger'" do
26
+ expect(kafka_device.producer).to eq('logstash-logger')
27
+ end
28
+
29
+ it "defaults the Kafka backoff to 1" do
30
+ expect(kafka_device.backoff).to eq(1)
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::Kinesis do
4
+ include_context 'device'
5
+
6
+ let(:client) { double("Aws::Kinesis::Client") }
7
+
8
+ before(:each) do
9
+ allow(Aws::Kinesis::Client).to receive(:new) { client }
10
+ end
11
+
12
+ it "writes to a Kinesis stream" do
13
+ response = ::Aws::Kinesis::Types::PutRecordsOutput.new
14
+ response.failed_record_count = 0
15
+ response.records = []
16
+ expect(client).to receive(:put_records) { response }
17
+ kinesis_device.write "foo"
18
+
19
+ expect(kinesis_device).to be_connected
20
+ kinesis_device.close!
21
+ expect(kinesis_device).not_to be_connected
22
+ end
23
+
24
+ it "it puts records with recoverable errors back in the buffer" do
25
+ failed_record = ::Aws::Kinesis::Types::PutRecordsResultEntry.new
26
+ failed_record.error_code = "ProvisionedThroughputExceededException"
27
+ failed_record.error_message = "ProvisionedThroughputExceededException"
28
+ response = ::Aws::Kinesis::Types::PutRecordsOutput.new
29
+ response.failed_record_count = 1
30
+ response.records = [failed_record]
31
+
32
+ expect(client).to receive(:put_records) { response }
33
+ expect(kinesis_device).to receive(:write).with("foo")
34
+
35
+ kinesis_device.write_one "foo"
36
+ end
37
+
38
+ it "defaults the kinesis stream to logstash" do
39
+ expect(kinesis_device.stream).to eq('logstash')
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::MultiDelegator do
4
+ include_context 'device'
5
+
6
+ # Create a MultiDelegator writing to both STDOUT and a StringIO
7
+ subject { multi_delegator_device }
8
+
9
+ it "writes to all outputs" do
10
+ expect($stdout).to receive(:write).once
11
+ expect(io).to receive(:write).once
12
+
13
+ subject.write("test")
14
+ end
15
+
16
+ describe ".new" do
17
+ it "merges top level configuration to each output" do
18
+ logger = described_class.new(
19
+ port: 1234,
20
+ outputs: [
21
+ { type: :udp },
22
+ { type: :tcp }
23
+ ]
24
+ )
25
+
26
+ logger.devices.each do |device|
27
+ expect(device.port).to eq(1234)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ require 'logstash-logger'
2
+ require 'redis'
3
+
4
+ describe LogStashLogger::Device::Redis do
5
+ include_context 'device'
6
+
7
+ let(:redis) { double("Redis") }
8
+
9
+ before(:each) do
10
+ allow(Redis).to receive(:new) { redis }
11
+ allow(redis).to receive(:connect)
12
+ end
13
+
14
+ it "writes to a Redis list" do
15
+ expect(redis).to receive(:rpush)
16
+ redis_device.write "foo"
17
+ end
18
+
19
+ it "defaults the Redis list to 'logstash'" do
20
+ expect(redis_device.list).to eq('logstash')
21
+ end
22
+
23
+ describe "initializer" do
24
+ let(:redis_options) { { host: HOST, port: 6379 } }
25
+ subject { LogStashLogger::Device::Redis.new(redis_options).connect }
26
+
27
+ context "path is not blank" do
28
+ before do
29
+ redis_options[:path] = "/0"
30
+ end
31
+
32
+ it "sets the db" do
33
+ expect(Redis).to receive(:new).with(hash_including(db: 0))
34
+ subject
35
+ end
36
+
37
+ end
38
+
39
+ context "path is blank" do
40
+ before do
41
+ redis_options[:path] = ""
42
+ end
43
+
44
+ it "does not set the db" do
45
+ expect(Redis).to receive(:new).with(hash_excluding(:db))
46
+ subject
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,15 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::Socket do
4
+ include_context 'device'
5
+
6
+ it "defaults host to 0.0.0.0" do
7
+ expect(device_with_port.host).to eq("0.0.0.0")
8
+ end
9
+
10
+ context "when port is not specified" do
11
+ it "raises an exception" do
12
+ expect { described_class.new }.to raise_error(ArgumentError)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::Stderr do
4
+ let(:stderr) { $stderr }
5
+
6
+ it 'writes to stderr' do
7
+ expect(subject.to_io).to eq stderr
8
+ expect(stderr).to receive(:write).once
9
+ subject.write("test")
10
+ end
11
+
12
+ it 'ignores #close' do
13
+ expect(stderr).not_to receive(:close)
14
+ subject.close
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::Stdout do
4
+ let(:stdout) { $stdout }
5
+
6
+ it "writes to $stdout" do
7
+ expect(subject.to_io).to eq(stdout)
8
+ expect(stdout).to receive(:write).once
9
+ subject.write("test")
10
+ end
11
+
12
+ it "ignores #close" do
13
+ expect(stdout).not_to receive(:close)
14
+ subject.close
15
+ end
16
+
17
+ context "when the default $stdout has been overridden" do
18
+ before { $stdout = StringIO.new }
19
+ after { $stdout = STDOUT }
20
+
21
+ let(:injected_stdout) { STDOUT }
22
+
23
+ subject { described_class.new(io: injected_stdout) }
24
+
25
+ it "accepts an injectable reference to stdout" do
26
+ expect(subject.to_io).to eq(injected_stdout)
27
+ expect(injected_stdout).to receive(:write).once
28
+ subject.write("test")
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,120 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::TCP do
4
+ include_context 'device'
5
+
6
+ let(:tcp_socket) { double('TCPSocket') }
7
+ let(:ssl_socket) { double('SSLSocket') }
8
+
9
+ before(:each) do
10
+ allow(TCPSocket).to receive(:new) { tcp_socket }
11
+ allow(tcp_socket).to receive(:sync=)
12
+
13
+ allow(OpenSSL::SSL::SSLSocket).to receive(:new) { ssl_socket }
14
+ allow(ssl_socket).to receive(:connect)
15
+ allow(ssl_socket).to receive(:post_connection_check)
16
+ allow(ssl_tcp_device).to receive(:warn)
17
+ end
18
+
19
+ context "when not using SSL" do
20
+ it "writes to a TCP socket" do
21
+ expect(tcp_socket).to receive(:write)
22
+ tcp_device.write('test')
23
+ end
24
+
25
+ it "returns false for #use_ssl?" do
26
+ expect(tcp_device.use_ssl?).to be_falsey
27
+ end
28
+
29
+ it "exposes the TCP socket via #io" do
30
+ expect(tcp_device.io).to eq tcp_socket
31
+ end
32
+ end
33
+
34
+ context "when using SSL" do
35
+ it "writes to an SSL TCP socket" do
36
+ expect(ssl_socket).to receive(:write)
37
+ ssl_tcp_device.write('test')
38
+ end
39
+
40
+ it "returns true for #use_ssl?" do
41
+ expect(ssl_tcp_device.use_ssl?).to be_truthy
42
+ end
43
+
44
+ it "exposes the SSL socket via #io" do
45
+ expect(ssl_tcp_device.io).to eq ssl_socket
46
+ end
47
+
48
+ context 'hostname validation' do
49
+ let(:ssl_context) { double('test_ssl_context', verify_mode: OpenSSL::SSL::VERIFY_PEER) }
50
+ let(:ssl_tcp_options) { { type: :tcp, port: port, sync: true, ssl_context: ssl_context } }
51
+
52
+ context 'is enabled by default' do
53
+ let(:ssl_tcp_device) { LogStashLogger::Device.new(ssl_tcp_options) }
54
+
55
+ it 'validates' do
56
+ expect(ssl_tcp_device.send(:verify_hostname?)).to be_truthy
57
+ expect(ssl_socket).to receive(:post_connection_check).with HOST
58
+ ssl_tcp_device.connect
59
+ end
60
+ end
61
+
62
+ context 'is disabled explicitly' do
63
+ let(:ssl_tcp_device) { LogStashLogger::Device.new(ssl_tcp_options.merge(verify_hostname: false)) }
64
+
65
+ it 'does not validate' do
66
+ expect(ssl_tcp_device.send(:verify_hostname?)).to be_falsey
67
+ expect(ssl_socket).not_to receive(:post_connection_check)
68
+ ssl_tcp_device.connect
69
+ end
70
+ end
71
+
72
+ context 'is implicitly enabled by providing a hostname' do
73
+ let(:hostname) { 'www.example.com' }
74
+ let(:ssl_tcp_device) { LogStashLogger::Device.new(ssl_tcp_options.merge(verify_hostname: hostname)) }
75
+
76
+ it 'validates with supplied hostname' do
77
+ expect(ssl_socket).to receive(:post_connection_check).with hostname
78
+ ssl_tcp_device.connect
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'with a provided SSL context' do
84
+ let(:ssl_context) { double('test_ssl_context', verify_mode: OpenSSL::SSL::VERIFY_PEER) }
85
+ let(:ssl_tcp_device) { LogStashLogger::Device.new(type: :tcp, port: port, sync: true, ssl_context: ssl_context) }
86
+
87
+ it 'creates the socket using that context' do
88
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_context)
89
+ ssl_tcp_device.connect
90
+ end
91
+
92
+ it 'implicitly sets @use_ssl to true' do
93
+ expect(ssl_tcp_device.use_ssl?).to be_truthy
94
+ end
95
+
96
+ context 'and :ssl_enable explicitly set to false' do
97
+ let(:ssl_tcp_device) { LogStashLogger::Device.new(type: :tcp, port: port, sync: true, ssl_enable: false, ssl_context: ssl_context) }
98
+
99
+ it 'explicitly sets @use_ssl to false' do
100
+ expect(ssl_tcp_device.use_ssl?).to be_falsey
101
+ end
102
+ end
103
+ end
104
+
105
+ context 'without a provided SSL context' do
106
+ it 'ssl_context returns nil' do
107
+ expect(ssl_tcp_device.ssl_context).to be_nil
108
+ end
109
+ end
110
+
111
+ context 'only providing a certificate file' do
112
+ let(:ssl_tcp_device) { LogStashLogger::Device.new(type: :tcp, port: port, ssl_enable: true, sync: true, ssl_certificate: '/path/to/cert.pem') }
113
+
114
+ it 'implicitly uses a context with the configured certificate' do
115
+ expect(ssl_tcp_device.ssl_context.cert).to eq('/path/to/cert.pem')
116
+ end
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,9 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::UDP do
4
+ include_context 'device'
5
+
6
+ it "writes to a UDP socket" do
7
+ expect(udp_device.to_io).to be_a UDPSocket
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::Unix do
4
+ include_context 'device'
5
+
6
+ let(:unix_socket) { double("UNIXSocket") }
7
+
8
+ before(:each) do
9
+ allow(::UNIXSocket).to receive(:new) { unix_socket }
10
+ allow(unix_socket).to receive(:sync=)
11
+ end
12
+
13
+ it "writes to a local unix socket" do
14
+ expect(unix_socket).to receive(:write)
15
+ unix_device.write('foo')
16
+ end
17
+
18
+ context "when path is not specified" do
19
+ it "raises an exception" do
20
+ expect { described_class.new }.to raise_error(ArgumentError)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,97 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device do
4
+ include_context 'device'
5
+
6
+ context "when port is specified" do
7
+ it "defaults type to UDP" do
8
+ expect(device_with_port).to be_a LogStashLogger::Device::UDP
9
+ end
10
+ end
11
+
12
+ context "when passing in configuration" do
13
+ let(:configuration) { {type: :udp, port: port} }
14
+
15
+ subject(:new_device) { described_class.new(configuration) }
16
+
17
+ it "does not mutate the passed configuration" do
18
+ expect{ new_device }.to_not change { configuration }
19
+ expect( new_device ).to be_a LogStashLogger::Device::UDP
20
+ end
21
+ end
22
+
23
+ context "when configuration type is a String" do
24
+ let(:configuration) { {type: "udp", port: port} }
25
+
26
+ subject(:new_device) { described_class.new(configuration) }
27
+
28
+ it "it correctly recognizes the device type" do
29
+ expect(new_device).to be_a LogStashLogger::Device::UDP
30
+ end
31
+ end
32
+
33
+ describe ".parse_uri_config" do
34
+ subject(:parse_uri_config) { described_class.parse_uri_config(uri_config) }
35
+
36
+ context "when uri_config is valid" do
37
+ let(:uri_config) { udp_uri_config }
38
+ it { is_expected.to eq({type: 'udp', host: 'localhost', port: 5228, path: ''}) }
39
+ end
40
+
41
+ context "when uri is invalid" do
42
+ let(:uri_config) { invalid_uri_config }
43
+ specify { expect { parse_uri_config }.to raise_error(URI::InvalidURIError) }
44
+ end
45
+ end
46
+
47
+ describe "Parsing URI configurations" do
48
+ subject(:new_device) { described_class.new(uri_config) }
49
+
50
+ context "when URI config is udp" do
51
+ let(:uri_config) { udp_uri_config }
52
+ it { is_expected.to be_a LogStashLogger::Device::UDP }
53
+ end
54
+
55
+ context "when URI config is tcp" do
56
+ let(:uri_config) { tcp_uri_config }
57
+ it { is_expected.to be_a LogStashLogger::Device::TCP }
58
+ end
59
+
60
+ context "when URI config is unix" do
61
+ let(:uri_config) { unix_uri_config }
62
+ it { is_expected.to be_a LogStashLogger::Device::Unix }
63
+ end
64
+
65
+ context "when URI config is file" do
66
+ let(:uri_config) { file_uri_config }
67
+ it { is_expected.to be_a LogStashLogger::Device::File }
68
+ end
69
+
70
+ context "when URI config is redis" do
71
+ let(:uri_config) { redis_uri_config }
72
+ it { is_expected.to be_a LogStashLogger::Device::Redis }
73
+ context "list specified" do
74
+ let(:uri_config) { redis_uri_config.merge({list: 'mylist'}) }
75
+ it 'is expected to have the list option set' do
76
+ expect(new_device.list).to eq('mylist')
77
+ end
78
+ end
79
+ end
80
+
81
+ context "when URI config is kafka" do
82
+ let(:uri_config) { kafka_uri_config }
83
+ it { is_expected.to be_a LogStashLogger::Device::Kafka }
84
+ end
85
+
86
+ context "when URI config is stdout" do
87
+ let(:uri_config) { stdout_uri_config }
88
+ it { is_expected.to be_a LogStashLogger::Device::Stdout }
89
+ end
90
+
91
+ context 'when URI config is stderr' do
92
+ let(:uri_config) { stderr_uri_config }
93
+ it { is_expected.to be_a LogStashLogger::Device::Stderr }
94
+ end
95
+ end
96
+
97
+ end