logstash-logger-yajl 0.27.0

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