logstash-logger 0.6.2 → 0.7.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 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