logstash-logger 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5cc1cc91049d6f846f8d942e4d0281683b904b0f
4
- data.tar.gz: c2c7090c2787ea403b466fbfd7efa5dc73a48d6c
3
+ metadata.gz: 028f82a7160982a2b3d5d7fea16a87b408f28f19
4
+ data.tar.gz: 31e13e392d3315844dfeb73e7f8b61a764575d60
5
5
  SHA512:
6
- metadata.gz: 089bc8ab4e842eb8b2184967cf20987cca96d1ae85894b6c705eb05263ed9541dca41048ca01e3d5197eb57f8ec14bbec9f115b8537ef684770012f7f25f6674
7
- data.tar.gz: d1f170fafd89df7d792b0e0e6aa15729200ca7b8046f0f31041a5dbdd5f09a0911b11e4553f085f51f273429da5c925324af83d0f40ecb8815072409964bca65
6
+ metadata.gz: 5c97296f106d4c66323026861e587dc98b2dd00bb53a09fa2de273cbd4bcb2dd8270ffee84e2003fbb0309343a42485d08b104108da512a45f59ba39a312b711
7
+ data.tar.gz: dec18c3ff5a7d76da22ab9cdb8e62bca254742013b2f12b09298a1753bd8c3f288d35ebd18eb51b7b5eee8afd4545abedcd40a694d48b7d6d621092be3d9a884
@@ -5,6 +5,7 @@ rvm:
5
5
  - 2.1.0
6
6
  - 2.1.1
7
7
  - 2.1.2
8
+ - 2.1.3
8
9
  - jruby-19mode
9
10
  - rbx-2
10
11
  gemfile:
@@ -1,3 +1,19 @@
1
+ ## 0.7.0
2
+ - Support for logging to a generic IO object.
3
+ - Support for overriding IO in stdout logger. Fixes [#20](https://github.com/dwbutler/logstash-logger/pull/20).
4
+ Thanks [Arron Mabrey](https://github.com/arronmabrey)!
5
+ - Support for configuring logger with a URI. See [#22](https://github.com/dwbutler/logstash-logger/pull/22).
6
+ Thanks [Arron Mabrey](https://github.com/arronmabrey)!
7
+ - Support logging any object. See [#23](https://github.com/dwbutler/logstash-logger/issues/23).
8
+
9
+ ## 0.6.2
10
+ - Allow type to be specified as a string. Fixes [#19](https://github.com/dwbutler/logstash-logger/pull/19).
11
+ Thanks [Arron Mabrey](https://github.com/arronmabrey)!
12
+
13
+ ## 0.6.1
14
+ - Don't mutate options passed to LogStashLogger. Fixes [#18](https://github.com/dwbutler/logstash-logger/pull/18).
15
+ Thanks [Arron Mabrey](https://github.com/arronmabrey)!
16
+
1
17
  ## 0.6.0
2
18
  - Support for logging to a file.
3
19
  - Support for logging to a Redis list.
data/README.md CHANGED
@@ -10,7 +10,7 @@ writing to a file or syslog since logstash can receive the structured data direc
10
10
  * Can write directly to logstash over a UDP or TCP/SSL connection.
11
11
  * Can write to a file, Redis, a unix socket, or stdout.
12
12
  * Always writes in logstash JSON format.
13
- * Logger can take a string message, a hash, a `LogStash::Event`, or a JSON string as input.
13
+ * Logger can take a string message, a hash, a `LogStash::Event`, an object, or a JSON string as input.
14
14
  * Events are automatically populated with message, timestamp, host, and severity.
15
15
  * Easily integrates with Rails via configuration.
16
16
 
@@ -45,6 +45,7 @@ file_logger = LogStashLogger.new(type: :file, path: 'log/development.log', sync:
45
45
  unix_logger = LogStashLogger.new(type: :unix, path: '/tmp/sock')
46
46
  redis_logger = LogStashLogger.new(type: :redis)
47
47
  stdout_logger = LogStashLogger.new(type: :stdout)
48
+ io_logger = LogStashLogger.new(type: :io, io: io)
48
49
 
49
50
  # The following messages are written to UDP port 5228:
50
51
 
@@ -65,6 +66,27 @@ logger.tagged('foo') { logger.fatal('bar') }
65
66
  # {"message":"bar","@timestamp":"2014-05-26T20:35:14.685-07:00","@version":"1","severity":"FATAL","host":"[hostname]","tags":["foo"]}
66
67
  ```
67
68
 
69
+ ## URI Configuration
70
+ You can use a URI to configure your logstash logger instead of a hash. This is useful in environments
71
+ such as Heroku where you may want to read configuration values from the environment. The URI scheme
72
+ is `type://host:port/path`. Some sample URI configurations are given below.
73
+
74
+ ```
75
+ udp://localhost:5228
76
+ tcp://localhost:5229
77
+ unix:///tmp/socket
78
+ file:///path/to/file
79
+ redis://localhost:6379
80
+ stdout:/
81
+ ```
82
+
83
+ Pass the URI into your logstash logger like so:
84
+
85
+ ```ruby
86
+ # Read the URI from an environment variable
87
+ logger = LogStashLogger.new(uri: ENV['LOGSTASH_URI'])
88
+ ```
89
+
68
90
  ## Logstash Configuration
69
91
 
70
92
  In order for logstash to correctly receive and parse the events, you will need to
@@ -120,9 +142,22 @@ input {
120
142
 
121
143
  Verified to work with both Rails 3 and 4.
122
144
 
145
+ By default, every Rails log message will be written to logstash in `LogStash::Event` JSON format.
146
+
147
+ For minimal, more-structured logstash events, try one of the following gems:
148
+
149
+ * [lograge](https://github.com/roidrage/lograge)
150
+ * [yarder](https://github.com/rurounijones/yarder)
151
+
152
+ Currently these gems output a JSON string, which LogStashLogger then parses.
153
+ Future versions of these gems could potentially have deeper integration with LogStashLogger
154
+ (e.g. by directly writing `LogStash::Event` objects).
155
+
156
+ ### Rails Configuration
157
+
123
158
  Add the following to your `config/environments/production.rb`:
124
159
 
125
- ### Common Options
160
+ #### Common Options
126
161
 
127
162
  ```ruby
128
163
  # Optional, Rails sets the default to :info
@@ -130,9 +165,12 @@ config.log_level = :debug
130
165
 
131
166
  # Optional, Rails 4 defaults to true in development and false in production
132
167
  config.autoflush_log = true
168
+
169
+ # Optional, use a URI to configure. Useful on Heroku
170
+ config.logstash.uri = ENV['LOGSTASH_URI']
133
171
  ```
134
172
 
135
- ### UDP
173
+ #### UDP
136
174
  ```ruby
137
175
  # Optional, defaults to '0.0.0.0'
138
176
  config.logstash.host = 'localhost'
@@ -144,7 +182,7 @@ config.logstash.type = :udp
144
182
  config.logstash.port = 5228
145
183
  ```
146
184
 
147
- ### TCP
185
+ #### TCP
148
186
 
149
187
  ```ruby
150
188
  # Optional, defaults to '0.0.0.0'
@@ -160,7 +198,7 @@ config.logstash.type = :tcp
160
198
  config.logstash.ssl_enable = true
161
199
  ```
162
200
 
163
- ### Unix Socket
201
+ #### Unix Socket
164
202
 
165
203
  ```ruby
166
204
  # Required
@@ -170,7 +208,7 @@ config.logstash.type = :unix
170
208
  config.logstash.path = '/tmp/sock'
171
209
  ```
172
210
 
173
- ### Redis
211
+ #### Redis
174
212
 
175
213
  ```ruby
176
214
  # Required
@@ -190,7 +228,7 @@ config.logstash.host = 'localhost'
190
228
  config.logstash.port = 6379
191
229
  ```
192
230
 
193
- ### File
231
+ #### File
194
232
 
195
233
  ```ruby
196
234
  # Required
@@ -200,15 +238,15 @@ config.logstash.type = :file
200
238
  config.logstash.path = 'log/production.log'
201
239
  ```
202
240
 
203
- By default, every Rails log message will be written to logstash in `LogStash::Event` JSON format.
204
-
205
- For minimal, more-structured logstash events, try one of the following gems:
241
+ #### IO
206
242
 
207
- * [lograge](https://github.com/roidrage/lograge)
208
- * [yarder](https://github.com/rurounijones/yarder)
243
+ ```ruby
244
+ # Required
245
+ config.logstash.type = :io
209
246
 
210
- Currently these gems output a JSON string, which LogStashLogger then parses.
211
- Future versions of these gems could potentially have deeper integration with LogStashLogger (i.e. by writing `LogStash::Event` objects).
247
+ # Required
248
+ config.logstash.io = io
249
+ ```
212
250
 
213
251
  ## Ruby Compatibility
214
252
 
@@ -220,7 +258,6 @@ Verified to work with:
220
258
 
221
259
  Ruby 1.8.7 is not supported.
222
260
 
223
-
224
261
  ## What type of logger should I use?
225
262
 
226
263
  It depends on your specific needs, but most applications should use the default (UDP). Here are the advantages and
@@ -12,15 +12,28 @@ module LogStashLogger
12
12
  autoload :Unix, 'logstash-logger/device/unix'
13
13
  autoload :Redis, 'logstash-logger/device/redis'
14
14
  autoload :File, 'logstash-logger/device/file'
15
+ autoload :IO, 'logstash-logger/device/io'
15
16
  autoload :Stdout, 'logstash-logger/device/stdout'
16
17
 
17
18
  def self.new(opts)
18
19
  opts = opts.dup
20
+
21
+ if parsed_uri_opts = parse_uri_config(opts)
22
+ opts = parsed_uri_opts
23
+ end
24
+
19
25
  type = opts.delete(:type) || DEFAULT_TYPE
20
26
 
21
27
  device_klass_for(type).new(opts)
22
28
  end
23
29
 
30
+ def self.parse_uri_config(opts)
31
+ if uri = opts[:uri]
32
+ parsed = ::URI.parse(uri)
33
+ {type: parsed.scheme, host: parsed.host, port: parsed.port, path: parsed.path}
34
+ end
35
+ end
36
+
24
37
  def self.device_klass_for(type)
25
38
  case type.to_sym
26
39
  when :udp then UDP
@@ -28,6 +41,7 @@ module LogStashLogger
28
41
  when :unix then Unix
29
42
  when :file then File
30
43
  when :redis then Redis
44
+ when :io then IO
31
45
  when :stdout then Stdout
32
46
  else fail ArgumentError, 'Invalid type'
33
47
  end
@@ -0,0 +1,11 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class IO < Base
4
+ def initialize(opts)
5
+ super
6
+ @io = opts[:io] || fail(ArgumentError, 'IO is required')
7
+ @io.sync = sync unless sync.nil?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,10 +1,8 @@
1
1
  module LogStashLogger
2
2
  module Device
3
- class Stdout < Base
3
+ class Stdout < IO
4
4
  def initialize(opts={})
5
- super
6
- @io = $stdout
7
- @io.sync = sync unless sync.nil?
5
+ super({io: $stdout}.merge(opts))
8
6
  end
9
7
 
10
8
  def close
@@ -27,8 +27,8 @@ module LogStashLogger
27
27
  when Hash
28
28
  event_data = data.merge("@timestamp" => time)
29
29
  LogStash::Event.new(event_data)
30
- when String
31
- LogStash::Event.new("message" => data, "@timestamp" => time)
30
+ else
31
+ LogStash::Event.new("message" => msg2str(data), "@timestamp" => time)
32
32
  end
33
33
 
34
34
  event['severity'] ||= severity
@@ -4,18 +4,21 @@ require 'logstash-logger/tagged_logging'
4
4
  module LogStashLogger
5
5
  def self.new(*args)
6
6
  opts = extract_opts(*args)
7
- @device = Device.new(opts)
7
+ device = Device.new(opts)
8
8
 
9
- ::Logger.new(@device).tap do |logger|
9
+ ::Logger.new(device).tap do |logger|
10
+ logger.instance_variable_set(:@device, device)
10
11
  logger.extend(self)
11
12
  logger.extend(TaggedLogging)
12
13
  logger.formatter = Formatter.new
13
14
  end
14
15
  end
15
16
 
16
- def self.included(base)
17
+ def self.extended(base)
17
18
  base.instance_eval do
18
- attr_reader :device
19
+ class << self
20
+ attr_reader :device
21
+ end
19
22
 
20
23
  def flush
21
24
  !!@device.flush
@@ -6,6 +6,11 @@ module LogStashLogger
6
6
 
7
7
  logger_options = app.config.logstash
8
8
 
9
+ if parsed_uri_options = LogStashLogger::Device.parse_uri_config(logger_options)
10
+ logger_options.delete(:uri)
11
+ logger_options.merge!(parsed_uri_options)
12
+ end
13
+
9
14
  if logger_options.type == :file
10
15
  logger_options.path ||= app.config.paths["log"].first
11
16
  end
@@ -1,3 +1,3 @@
1
1
  module LogStashLogger
2
- VERSION = "0.6.2"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -0,0 +1,14 @@
1
+ require 'logstash-logger'
2
+
3
+ describe LogStashLogger::Device::IO do
4
+ include_context 'device'
5
+
6
+ let(:subject) { io_device }
7
+ let(:io) { StringIO.new }
8
+
9
+ it "writes to the IO object" do
10
+ expect(subject.to_io).to eq(io)
11
+ expect(io).to receive(:write).once
12
+ subject.write("test")
13
+ end
14
+ end
@@ -1,14 +1,31 @@
1
1
  require 'logstash-logger'
2
2
 
3
3
  describe LogStashLogger::Device::Stdout do
4
+ let(:stdout) { $stdout }
5
+
4
6
  it "writes to $stdout" do
5
- expect(subject.to_io).to eq($stdout)
6
- expect($stdout).to receive(:write).once
7
+ expect(subject.to_io).to eq(stdout)
8
+ expect(stdout).to receive(:write).once
7
9
  subject.write("test")
8
10
  end
9
11
 
10
12
  it "ignores #close" do
11
- expect($stdout).not_to receive(:close)
13
+ expect(stdout).not_to receive(:close)
12
14
  subject.close
13
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
14
31
  end
@@ -30,4 +30,52 @@ describe LogStashLogger::Device do
30
30
  end
31
31
  end
32
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
+ end
74
+
75
+ context "when URI config is stdout" do
76
+ let(:uri_config) { stdout_uri_config }
77
+ it { is_expected.to be_a LogStashLogger::Device::Stdout }
78
+ end
79
+ end
80
+
33
81
  end
@@ -120,5 +120,20 @@ describe LogStashLogger do
120
120
  expect(listener_event['host']).to eq(hostname)
121
121
  expect(listener_event['@timestamp']).to_not be_nil
122
122
  end
123
+
124
+ it 'takes any object as input and writes a logstash event' do
125
+ message = Time.now
126
+
127
+ expect(logdev).to receive(:write).and_call_original do |event|
128
+ expect(event).to be_a LogStash::Event
129
+ expect(event.host).to eql(hostname)
130
+ expect(event['message']).to eql(message.inspect)
131
+ expect(event['severity']).to eql('INFO')
132
+ end
133
+
134
+ logger.info(message)
135
+
136
+ expect(listener_event['message']).to eq(message.inspect)
137
+ end
123
138
 
124
139
  end
@@ -14,32 +14,46 @@ end
14
14
  Test::Application.initialize!
15
15
 
16
16
  describe LogStashLogger do
17
+ include_context 'device'
18
+
17
19
  describe "Rails integration" do
18
20
  let(:app) { Rails.application }
19
21
  let(:config) { app.config }
22
+ subject { app.config.logger }
23
+
24
+ before(:each) do
25
+ app.config.logstash.clear
26
+ app.config.logger = nil
27
+ end
20
28
 
21
- describe 'Railtie' do
22
- describe 'Rails.logger' do
23
- subject { Rails.logger }
29
+ describe '#setup' do
30
+ context "when configured with a port" do
31
+ before(:each) do
32
+ app.config.logstash.port = PORT
33
+ app.config.log_level = :info
34
+ LogStashLogger.setup(app)
35
+ end
24
36
 
25
- it { should be_a LogStashLogger }
37
+ it { is_expected.to be_a LogStashLogger }
26
38
 
27
39
  it "defaults level to config.log_level" do
28
40
  expect(subject.level).to eq(::Logger::INFO)
29
41
  end
30
42
  end
31
- end
32
43
 
33
- describe '#setup' do
34
- before do
35
- app.config.logstash.port = PORT
36
- LogStashLogger.setup(app)
44
+ context "when configured with a URI" do
45
+ before(:each) do
46
+ app.config.logstash.uri = tcp_uri
47
+ LogStashLogger.setup(app)
48
+ end
49
+
50
+ it "configures the logger using the URI" do
51
+ expect(subject.device).to be_a LogStashLogger::Device::TCP
52
+ end
37
53
  end
38
54
 
39
55
  context "when logstash is not configured" do
40
- before do
41
- app.config.logstash.clear
42
- app.config.logger = nil
56
+ before(:each) do
43
57
  LogStashLogger.setup(app)
44
58
  end
45
59
 
@@ -43,5 +43,22 @@ RSpec.shared_context 'device' do
43
43
  let(:file) { Tempfile.new('test') }
44
44
  let(:file_device) { LogStashLogger::Device.new(type: :file, path: file.path)}
45
45
 
46
+ let(:io_device) { LogStashLogger::Device.new(type: :io, io: io)}
47
+
46
48
  let(:redis_device) { LogStashLogger::Device.new(type: :redis, sync: true) }
49
+
50
+ let(:udp_uri) { "udp://localhost:5228" }
51
+ let(:tcp_uri) { "tcp://localhost:5229" }
52
+ let(:unix_uri) { "unix:///some/path/to/socket" }
53
+ let(:file_uri) { "file://#{file.path}" }
54
+ let(:redis_uri) { "redis://localhost:6379" }
55
+ let(:stdout_uri) { "stdout://localhost" }
56
+
57
+ let(:invalid_uri_config) { {uri: "non parsable uri"} }
58
+ let(:udp_uri_config) { {uri: udp_uri} }
59
+ let(:tcp_uri_config) { {uri: tcp_uri} }
60
+ let(:unix_uri_config) { {uri: unix_uri} }
61
+ let(:file_uri_config) { {uri: file_uri} }
62
+ let(:redis_uri_config) { {uri: redis_uri} }
63
+ let(:stdout_uri_config) { {uri: stdout_uri} }
47
64
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Butler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-20 00:00:00.000000000 Z
11
+ date: 2014-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-event
@@ -160,6 +160,7 @@ files:
160
160
  - lib/logstash-logger/device/base.rb
161
161
  - lib/logstash-logger/device/connectable.rb
162
162
  - lib/logstash-logger/device/file.rb
163
+ - lib/logstash-logger/device/io.rb
163
164
  - lib/logstash-logger/device/redis.rb
164
165
  - lib/logstash-logger/device/socket.rb
165
166
  - lib/logstash-logger/device/stdout.rb
@@ -181,6 +182,7 @@ files:
181
182
  - samples/udp.conf
182
183
  - samples/unix.conf
183
184
  - spec/device/file_spec.rb
185
+ - spec/device/io_spec.rb
184
186
  - spec/device/redis_spec.rb
185
187
  - spec/device/socket_spec.rb
186
188
  - spec/device/stdout_spec.rb
@@ -218,6 +220,7 @@ specification_version: 4
218
220
  summary: LogStash Logger for ruby
219
221
  test_files:
220
222
  - spec/device/file_spec.rb
223
+ - spec/device/io_spec.rb
221
224
  - spec/device/redis_spec.rb
222
225
  - spec/device/socket_spec.rb
223
226
  - spec/device/stdout_spec.rb