logstash-logger 0.12.0 → 0.13.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -1
- data/README.md +90 -16
- data/gemfiles/rails_3.2.gemfile +1 -0
- data/gemfiles/rails_4.0.gemfile +1 -0
- data/gemfiles/rails_4.1.gemfile +1 -0
- data/gemfiles/rails_4.2.gemfile +1 -0
- data/lib/logstash-logger/device.rb +3 -12
- data/lib/logstash-logger/device/balancer.rb +1 -1
- data/lib/logstash-logger/device/multi_delegator.rb +8 -2
- data/lib/logstash-logger/formatter.rb +4 -1
- data/lib/logstash-logger/logger.rb +28 -15
- data/lib/logstash-logger/multi_logger.rb +135 -0
- data/lib/logstash-logger/version.rb +1 -1
- data/logstash-logger.gemspec +1 -0
- data/spec/device/balancer_spec.rb +2 -5
- data/spec/device/file_spec.rb +1 -1
- data/spec/device/io_spec.rb +1 -2
- data/spec/device/multi_delegator_spec.rb +3 -9
- data/spec/device/socket_spec.rb +1 -1
- data/spec/device/unix_spec.rb +1 -1
- data/spec/device_spec.rb +1 -1
- data/spec/formatter_spec.rb +40 -13
- data/spec/multi_logger_spec.rb +52 -0
- data/spec/rails_spec.rb +6 -4
- data/spec/spec_helper.rb +21 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc77de67a993f6d92e48eb51a03403545adb4a36
|
4
|
+
data.tar.gz: 155105ccaa41672d379ba39f1f58891079814ef1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49065907ddd39ea7dce437da0d9e4d640667a48d056f487b23948a6a4a97bb2d8a117c6370a430b9465f739b3225a1ac8cb9419f8144928b30af78a118c18a96
|
7
|
+
data.tar.gz: 945c34c855bf8f0fe36b1a40d8b6daaf72ac452590da3e8f3d74069f3fdcc41865f6926513255bd2bca91e661130dbe7ec8a1f82d5813879ca625fd9df7ee135
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 0.13.0
|
2
|
+
- Support for sending messages to multiple loggers. Each one can have a different formatter. [#58](https://github.com/dwbutler/logstash-logger/pull/58)
|
3
|
+
- Fixes tagged logging support when using a custom formatter.
|
4
|
+
|
1
5
|
## 0.12.0
|
2
6
|
- Support for other formatters, including custom formatters. [#56](https://github.com/dwbutler/logstash-logger/pull/56)
|
3
7
|
- Support for CEE output.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# LogStashLogger
|
2
|
-
[](https://travis-ci.org/dwbutler/logstash-logger) [](https://codeclimate.com/github/dwbutler/logstash-logger) [](http://codecov.io/github/dwbutler/logstash-logger?branch=master)
|
3
3
|
|
4
|
-
|
5
|
-
It
|
4
|
+
LogStashLogger extends Ruby's `Logger` class to log directly to [logstash](http://logstash.net).
|
5
|
+
It supports writing to various outputs in logstash JSON format. This is an improvement over
|
6
6
|
writing to a file or syslog since logstash can receive the structured data directly.
|
7
7
|
|
8
8
|
## Features
|
9
9
|
|
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, stdout or stderr.
|
12
|
-
*
|
12
|
+
* Writes in logstash JSON format, but supports other formats as well.
|
13
|
+
* Can write to multiple outputs.
|
13
14
|
* Logger can take a string message, a hash, a `LogStash::Event`, an object, or a JSON string as input.
|
14
15
|
* Events are automatically populated with message, timestamp, host, and severity.
|
15
16
|
* Easily integrates with Rails via configuration.
|
@@ -50,16 +51,53 @@ stderr_logger = LogStashLogger.new(type: :stderr)
|
|
50
51
|
io_logger = LogStashLogger.new(type: :io, io: io)
|
51
52
|
|
52
53
|
# Use a different formatter
|
53
|
-
cee_logger = LogStashLogger.new(
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
54
|
+
cee_logger = LogStashLogger.new(
|
55
|
+
type: :tcp,
|
56
|
+
host: 'logsene-receiver-syslog.sematext.com',
|
57
|
+
port: 514,
|
58
|
+
formatter: :cee_syslog
|
59
|
+
)
|
60
|
+
|
61
|
+
custom_formatted_logger = LogStashLogger.new(
|
62
|
+
type: :redis,
|
63
|
+
formatter: MyCustomFormatter
|
64
|
+
)
|
65
|
+
|
66
|
+
lambda_formatted_logger = LogStashLogger.new(
|
67
|
+
type: :stdout,
|
68
|
+
formatter: ->(severity, time, progname, msg) { "[#{progname}] #{msg}" }
|
69
|
+
)
|
70
|
+
|
71
|
+
ruby_default_formatter_logger = LogStashLogger.new(
|
72
|
+
type: :file,
|
73
|
+
path: 'log/development.log',
|
74
|
+
formatter: ::Logger::Formatter
|
75
|
+
)
|
76
|
+
|
77
|
+
# Send messages to multiple outputs. Each output will have the same format.
|
78
|
+
multi_delegating_logger = LogStashLogger.new(
|
79
|
+
type: :multi_delegator,
|
80
|
+
outputs: [
|
81
|
+
{ type: :file, path: 'log/development.log' },
|
82
|
+
{ type: :udp, host: 'localhost', port: 5228 }
|
83
|
+
])
|
84
|
+
|
85
|
+
# Balance messages between several outputs
|
86
|
+
balancer_logger = LogStashLogger.new(
|
87
|
+
type: :balancer,
|
88
|
+
outputs: [
|
89
|
+
{ type: :udp, host: 'host1', port: 5228 },
|
90
|
+
{ type: :udp, host: 'host2', port: 5228 }
|
91
|
+
])
|
92
|
+
|
93
|
+
# Send messages to multiple loggers.
|
94
|
+
# Use this if you need to send different formats to different outputs.
|
95
|
+
multi_logger = LogStashLogger.new(
|
96
|
+
type: :multi_logger,
|
97
|
+
outputs: [
|
98
|
+
{ type: :file, path: 'log/development.log', formatter: ::Logger::Formatter },
|
99
|
+
{ type: :tcp, host: 'localhost', port: 5228, formatter: :json }
|
100
|
+
])
|
63
101
|
|
64
102
|
# The following messages are written to UDP port 5228:
|
65
103
|
|
@@ -223,6 +261,10 @@ config.autoflush_log = true
|
|
223
261
|
|
224
262
|
# Optional, use a URI to configure. Useful on Heroku
|
225
263
|
config.logstash.uri = ENV['LOGSTASH_URI']
|
264
|
+
|
265
|
+
# Optional. Defaults to :json_lines. If there are multiple outputs,
|
266
|
+
# they will all share the same formatter.
|
267
|
+
config.logstash.formatter = :json_lines
|
226
268
|
```
|
227
269
|
|
228
270
|
#### UDP
|
@@ -331,10 +373,14 @@ config.logstash.type = :io
|
|
331
373
|
config.logstash.io = io
|
332
374
|
```
|
333
375
|
|
334
|
-
####
|
376
|
+
#### Multi Delegator
|
335
377
|
|
336
378
|
```ruby
|
337
|
-
|
379
|
+
# Required
|
380
|
+
config.logstash.type = :multi_delegator
|
381
|
+
|
382
|
+
# Required
|
383
|
+
config.logstash.outputs = [
|
338
384
|
{
|
339
385
|
type: :file,
|
340
386
|
path: 'log/production.log'
|
@@ -347,6 +393,27 @@ config.logstash = [
|
|
347
393
|
]
|
348
394
|
```
|
349
395
|
|
396
|
+
#### Multi Logger
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
# Required
|
400
|
+
config.logstash.type = :multi_logger
|
401
|
+
|
402
|
+
# Required. Each logger may have its own formatter.
|
403
|
+
config.logstash.outputs = [
|
404
|
+
{
|
405
|
+
type: :file,
|
406
|
+
path: 'log/production.log',
|
407
|
+
formatter: ::Logger::Formatter
|
408
|
+
},
|
409
|
+
{
|
410
|
+
type: :udp,
|
411
|
+
port: 5228,
|
412
|
+
host: 'localhost'
|
413
|
+
}
|
414
|
+
]
|
415
|
+
```
|
416
|
+
|
350
417
|
### Logging HTTP request data
|
351
418
|
|
352
419
|
In web applications, you can log data from HTTP requests (such as headers) using the
|
@@ -421,6 +488,11 @@ This is most likely not a problem with LogStashLogger, but rather a different ge
|
|
421
488
|
This is especially likely if you're using a threaded server such as Puma, since gems often change the log level of
|
422
489
|
`Rails.logger` in a non thread-safe way. See [#17](https://github.com/dwbutler/logstash-logger/issues/17) for more information.
|
423
490
|
|
491
|
+
### Sometimes two lines of JSON log messages get sent as one message
|
492
|
+
If you're using UDP output and writing to a logstash listener, you are most likely encountering a bug in the UDP implementation
|
493
|
+
of the logstash listener. There is no known fix at this time. See [#43](https://github.com/dwbutler/logstash-logger/issues/43)
|
494
|
+
for more information.
|
495
|
+
|
424
496
|
## Breaking changes
|
425
497
|
|
426
498
|
### Version 0.5+
|
@@ -457,6 +529,8 @@ logger = LogStashLogger.new('localhost', 5228, :tcp)
|
|
457
529
|
* [Vadim Kazakov](https://github.com/yads)
|
458
530
|
* [Anil Rhemtulla](https://github.com/AnilRh)
|
459
531
|
* [Nikita Vorobei](https://github.com/Nikita-V)
|
532
|
+
* [fireboy1919](https://github.com/fireboy1919)
|
533
|
+
* [Mike Gunderloy](https://github.com/ffmike)
|
460
534
|
|
461
535
|
## Contributing
|
462
536
|
|
data/gemfiles/rails_3.2.gemfile
CHANGED
data/gemfiles/rails_4.0.gemfile
CHANGED
data/gemfiles/rails_4.1.gemfile
CHANGED
data/gemfiles/rails_4.2.gemfile
CHANGED
@@ -21,17 +21,7 @@ module LogStashLogger
|
|
21
21
|
|
22
22
|
def self.new(opts)
|
23
23
|
opts = opts.dup
|
24
|
-
|
25
|
-
if opts.is_a?(Array)
|
26
|
-
# Multiple device configs supplied... create a MultiDelegator
|
27
|
-
devices = opts.map{|opt| build_device(opt)}
|
28
|
-
Device::MultiDelegator.new(*devices)
|
29
|
-
elsif Hash
|
30
|
-
# Create a single device
|
31
|
-
build_device(opts)
|
32
|
-
else
|
33
|
-
raise ArgumentError, "Invalid device options: must be a Hash or an Array of Hashes"
|
34
|
-
end
|
24
|
+
build_device(opts)
|
35
25
|
end
|
36
26
|
|
37
27
|
def self.build_device(opts)
|
@@ -63,8 +53,9 @@ module LogStashLogger
|
|
63
53
|
when :io then IO
|
64
54
|
when :stdout then Stdout
|
65
55
|
when :stderr then Stderr
|
56
|
+
when :multi_delegator then MultiDelegator
|
66
57
|
when :balancer then Balancer
|
67
|
-
else fail ArgumentError, 'Invalid type'
|
58
|
+
else fail ArgumentError, 'Invalid device type'
|
68
59
|
end
|
69
60
|
end
|
70
61
|
end
|
@@ -8,14 +8,20 @@ module LogStashLogger
|
|
8
8
|
class MultiDelegator < Base
|
9
9
|
attr_reader :devices
|
10
10
|
|
11
|
-
def initialize(
|
11
|
+
def initialize(opts)
|
12
12
|
@io = self
|
13
|
-
@devices =
|
13
|
+
@devices = create_devices(opts[:outputs])
|
14
14
|
self.class.delegate(:write, :close, :flush)
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
+
def create_devices(opts)
|
20
|
+
opts.map do |device_opts|
|
21
|
+
Device.new(device_opts)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
19
25
|
def self.delegate(*methods)
|
20
26
|
methods.each do |m|
|
21
27
|
define_method(m) do |*args|
|
@@ -17,13 +17,16 @@ module LogStashLogger
|
|
17
17
|
def self.build_formatter(formatter_type)
|
18
18
|
formatter_type ||= DEFAULT_FORMATTER
|
19
19
|
|
20
|
-
if custom_formatter_instance?(formatter_type)
|
20
|
+
formatter = if custom_formatter_instance?(formatter_type)
|
21
21
|
formatter_type
|
22
22
|
elsif custom_formatter_class?(formatter_type)
|
23
23
|
formatter_type.new
|
24
24
|
else
|
25
25
|
formatter_klass(formatter_type).new
|
26
26
|
end
|
27
|
+
|
28
|
+
formatter.send(:extend, ::LogStashLogger::TaggedLogging::Formatter)
|
29
|
+
formatter
|
27
30
|
end
|
28
31
|
|
29
32
|
def self.formatter_klass(formatter_type)
|
@@ -2,17 +2,11 @@ require 'logger'
|
|
2
2
|
require 'logstash-logger/tagged_logging'
|
3
3
|
|
4
4
|
module LogStashLogger
|
5
|
+
autoload :MultiLogger, 'logstash-logger/multi_logger'
|
6
|
+
|
5
7
|
def self.new(*args)
|
6
8
|
opts = extract_opts(*args)
|
7
|
-
|
8
|
-
device = Device.new(opts)
|
9
|
-
|
10
|
-
::Logger.new(device).tap do |logger|
|
11
|
-
logger.instance_variable_set(:@device, device)
|
12
|
-
logger.extend(self)
|
13
|
-
logger.extend(TaggedLogging)
|
14
|
-
logger.formatter = formatter
|
15
|
-
end
|
9
|
+
build_logger(opts)
|
16
10
|
end
|
17
11
|
|
18
12
|
def self.extended(base)
|
@@ -22,7 +16,7 @@ module LogStashLogger
|
|
22
16
|
end
|
23
17
|
|
24
18
|
def flush
|
25
|
-
|
19
|
+
!!(@device.flush if @device.respond_to?(:flush))
|
26
20
|
end
|
27
21
|
end
|
28
22
|
end
|
@@ -34,13 +28,14 @@ module LogStashLogger
|
|
34
28
|
|
35
29
|
if args.length > 1
|
36
30
|
if args.all?{|arg| arg.is_a?(Hash)}
|
37
|
-
#
|
38
|
-
|
31
|
+
# Deprecated array of hashes
|
32
|
+
warn "[LogStashLogger] Passing an array of hashes to the constructor is deprecated. Please replace with an options hash: { type: :multi_delegator, outputs: [...] }"
|
33
|
+
{ type: :multi_delegator, outputs: args }
|
39
34
|
else
|
40
|
-
# Deprecated host/port/type
|
41
|
-
|
35
|
+
# Deprecated host/port/type constructor
|
36
|
+
warn "[LogStashLogger] The (host, port, type) constructor is deprecated. Please use an options hash instead."
|
42
37
|
host, port, type = *args
|
43
|
-
{host: host, port: port, type: type}
|
38
|
+
{ host: host, port: port, type: type }
|
44
39
|
end
|
45
40
|
elsif Hash === args[0]
|
46
41
|
args[0]
|
@@ -48,4 +43,22 @@ module LogStashLogger
|
|
48
43
|
fail ArgumentError, "Invalid LogStashLogger options"
|
49
44
|
end
|
50
45
|
end
|
46
|
+
|
47
|
+
def self.build_logger(opts)
|
48
|
+
case opts[:type]
|
49
|
+
when :multi_logger
|
50
|
+
loggers = opts[:outputs].map {|logger_opts| build_logger(logger_opts) }
|
51
|
+
MultiLogger.new(loggers)
|
52
|
+
else
|
53
|
+
formatter = Formatter.new(opts.delete(:formatter))
|
54
|
+
device = Device.new(opts)
|
55
|
+
|
56
|
+
::Logger.new(device).tap do |logger|
|
57
|
+
logger.instance_variable_set(:@device, device)
|
58
|
+
logger.extend(self)
|
59
|
+
logger.extend(TaggedLogging)
|
60
|
+
logger.formatter = formatter
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
51
64
|
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# Adapted from https://github.com/ffmike/multilogger
|
2
|
+
module LogStashLogger
|
3
|
+
class MultiLogger < ::Logger
|
4
|
+
def level=(value)
|
5
|
+
super
|
6
|
+
@loggers.each do |logger|
|
7
|
+
logger.level = value
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def progname=(value)
|
12
|
+
super
|
13
|
+
@loggers.each do |logger|
|
14
|
+
logger.progname = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def datetime_format=(datetime_format)
|
19
|
+
super
|
20
|
+
@loggers.each do |logger|
|
21
|
+
logger.datetime_format = datetime_format
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def formatter=(formatter)
|
26
|
+
@loggers.each do |logger|
|
27
|
+
logger.formatter = formatter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Array of Loggers to be logged to. These can be anything that acts reasonably like a Logger.
|
32
|
+
attr_accessor :loggers
|
33
|
+
|
34
|
+
# Any method not defined on standard Logger class, just send it on to anyone who will listen
|
35
|
+
def method_missing(name, *args, &block)
|
36
|
+
@loggers.each do |logger|
|
37
|
+
if logger.respond_to?(name)
|
38
|
+
logger.send(name, args, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# === Synopsis
|
45
|
+
#
|
46
|
+
# MultiLogger.new([logger1, logger2])
|
47
|
+
#
|
48
|
+
# === Args
|
49
|
+
#
|
50
|
+
# +loggers+::
|
51
|
+
# An array of loggers. Each one gets every message that is sent to the MultiLogger instance
|
52
|
+
#
|
53
|
+
# === Description
|
54
|
+
#
|
55
|
+
# Create an instance.
|
56
|
+
#
|
57
|
+
def initialize(loggers)
|
58
|
+
@loggers = []
|
59
|
+
super(nil)
|
60
|
+
@loggers = Array(loggers)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Methods that write to logs just write to each contained logger in turn
|
64
|
+
def add(severity, message = nil, progname = nil, &block)
|
65
|
+
@loggers.each do |logger|
|
66
|
+
logger.add(severity, message, progname, &block)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def <<(msg)
|
71
|
+
@loggers.each do |logger|
|
72
|
+
logger << msg
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def debug(progname = nil, &block)
|
77
|
+
@loggers.each do |logger|
|
78
|
+
logger.debug(progname, &block)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def info(progname = nil, &block)
|
83
|
+
@loggers.each do |logger|
|
84
|
+
logger.info(progname, &block)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def warn(progname = nil, &block)
|
89
|
+
@loggers.each do |logger|
|
90
|
+
logger.warn(progname, &block)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def error(progname = nil, &block)
|
95
|
+
@loggers.each do |logger|
|
96
|
+
logger.error(progname, &block)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def fatal(progname = nil, &block)
|
101
|
+
@loggers.each do |logger|
|
102
|
+
logger.fatal(progname, &block)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def unknown(progname = nil, &block)
|
107
|
+
@loggers.each do |logger|
|
108
|
+
logger.unknown(progname, &block)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def close
|
113
|
+
@loggers.each do |logger|
|
114
|
+
logger.close if logger.respond_to?(:close)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module TaggedLogging
|
119
|
+
def tagged(*tags)
|
120
|
+
@loggers.each do |logger|
|
121
|
+
logger.formatter.tagged(*tags) { yield self }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def flush
|
126
|
+
@loggers.each do |logger|
|
127
|
+
logger.formatter.clear_tags!
|
128
|
+
end
|
129
|
+
super if defined?(super)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
include TaggedLogging
|
134
|
+
end
|
135
|
+
end
|
data/logstash-logger.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |gem|
|
|
24
24
|
gem.add_development_dependency 'rails'
|
25
25
|
gem.add_development_dependency 'redis'
|
26
26
|
gem.add_development_dependency 'poseidon'
|
27
|
+
|
27
28
|
gem.add_development_dependency 'rspec', '>= 3'
|
28
29
|
gem.add_development_dependency 'rake'
|
29
30
|
gem.add_development_dependency 'pry'
|
@@ -4,10 +4,7 @@ describe LogStashLogger::Device::Balancer do
|
|
4
4
|
include_context 'device'
|
5
5
|
|
6
6
|
# Create a Balancer writing to both STDOUT and a StringIO
|
7
|
-
|
8
|
-
|
9
|
-
let(:stdout) { $stdout }
|
10
|
-
let(:io) { StringIO.new }
|
7
|
+
subject { balancer_device }
|
11
8
|
|
12
9
|
describe '#write' do
|
13
10
|
before do
|
@@ -16,7 +13,7 @@ describe LogStashLogger::Device::Balancer do
|
|
16
13
|
|
17
14
|
it "writes to one device" do
|
18
15
|
expect(io).to receive(:write).once
|
19
|
-
expect(stdout).to_not receive(:write)
|
16
|
+
expect($stdout).to_not receive(:write)
|
20
17
|
subject.write("log message")
|
21
18
|
end
|
22
19
|
end
|
data/spec/device/file_spec.rb
CHANGED
data/spec/device/io_spec.rb
CHANGED
@@ -4,16 +4,10 @@ describe LogStashLogger::Device::MultiDelegator do
|
|
4
4
|
include_context 'device'
|
5
5
|
|
6
6
|
# Create a MultiDelegator writing to both STDOUT and a StringIO
|
7
|
-
|
7
|
+
subject { multi_delegator_device }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
it "writes to $stdout" do
|
13
|
-
# MultiDelegator writes to stdout
|
14
|
-
expect(stdout).to receive(:write).once
|
15
|
-
|
16
|
-
# MultiDelegator writes to IO
|
9
|
+
it "writes to all outputs" do
|
10
|
+
expect($stdout).to receive(:write).once
|
17
11
|
expect(io).to receive(:write).once
|
18
12
|
|
19
13
|
subject.write("test")
|
data/spec/device/socket_spec.rb
CHANGED
data/spec/device/unix_spec.rb
CHANGED
data/spec/device_spec.rb
CHANGED
@@ -40,7 +40,7 @@ describe LogStashLogger::Device do
|
|
40
40
|
|
41
41
|
context "when uri is invalid" do
|
42
42
|
let(:uri_config) { invalid_uri_config }
|
43
|
-
specify { expect{ parse_uri_config }.to raise_error(URI::InvalidURIError) }
|
43
|
+
specify { expect { parse_uri_config }.to raise_error(URI::InvalidURIError) }
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
data/spec/formatter_spec.rb
CHANGED
@@ -25,27 +25,54 @@ describe LogStashLogger::Formatter do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
context "custom formatter" do
|
28
|
-
|
29
|
-
|
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
|
30
36
|
end
|
31
37
|
|
32
|
-
|
33
|
-
formatter
|
34
|
-
|
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
|
35
48
|
end
|
36
49
|
|
37
|
-
|
38
|
-
formatter
|
39
|
-
msg
|
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
|
40
61
|
end
|
41
|
-
expect(described_class.new(formatter)).to eql(formatter)
|
42
62
|
end
|
43
63
|
|
44
|
-
|
45
|
-
formatter
|
46
|
-
msg
|
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
|
47
75
|
end
|
48
|
-
expect(described_class.new(formatter)).to eql(formatter)
|
49
76
|
end
|
50
77
|
end
|
51
78
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::MultiLogger do
|
4
|
+
include_context 'device'
|
5
|
+
|
6
|
+
# Create a MultiLogger writing to both STDOUT and a StringIO
|
7
|
+
subject { multi_logger }
|
8
|
+
|
9
|
+
it { is_expected.to be_a LogStashLogger::MultiLogger }
|
10
|
+
|
11
|
+
it "has multiple loggers" do
|
12
|
+
expect(subject.loggers.count).to eq(2)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has one logger per output" do
|
16
|
+
expect(subject.loggers[0].device).to be_a LogStashLogger::Device::Stdout
|
17
|
+
expect(subject.loggers[1].device).to be_a LogStashLogger::Device::IO
|
18
|
+
end
|
19
|
+
|
20
|
+
it "allows a different formatter for each logger" do
|
21
|
+
expect(subject.loggers[0].formatter).to be_a ::Logger::Formatter
|
22
|
+
expect(subject.loggers[1].formatter).to be_a LogStashLogger::Formatter::JsonLines
|
23
|
+
end
|
24
|
+
|
25
|
+
it "logs to all loggers" do
|
26
|
+
subject.loggers.each do |logger|
|
27
|
+
expect(logger).to receive(:info).with("test")
|
28
|
+
end
|
29
|
+
|
30
|
+
multi_logger.info("test")
|
31
|
+
end
|
32
|
+
|
33
|
+
context "tagged logging" do
|
34
|
+
it "forwards tags to each logger's formatter" do
|
35
|
+
subject.loggers.each do |logger|
|
36
|
+
expect(logger.formatter).to receive(:tagged).with("foo")
|
37
|
+
end
|
38
|
+
|
39
|
+
subject.tagged("foo") do |logger|
|
40
|
+
logger.debug("bar")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "clears tags on each logger's formatter when flushing" do
|
45
|
+
subject.loggers.each do |logger|
|
46
|
+
expect(logger.formatter).to receive(:clear_tags!)
|
47
|
+
end
|
48
|
+
|
49
|
+
subject.flush
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/rails_spec.rb
CHANGED
@@ -52,21 +52,23 @@ describe LogStashLogger do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
context "when
|
55
|
+
context "when configuring a multi delegator" do
|
56
56
|
before(:each) do
|
57
|
-
app.config.logstash =
|
57
|
+
app.config.logstash.type = :multi_delegator
|
58
|
+
app.config.logstash.outputs = [
|
58
59
|
{
|
59
60
|
type: :udp,
|
60
61
|
uri: udp_uri
|
61
62
|
},
|
62
63
|
{
|
63
|
-
type: :file
|
64
|
+
type: :file,
|
65
|
+
path: '/tmp/foo.log'
|
64
66
|
}
|
65
67
|
]
|
66
68
|
LogStashLogger.setup(app)
|
67
69
|
end
|
68
70
|
|
69
|
-
it "uses a multi
|
71
|
+
it "uses a multi delegator" do
|
70
72
|
expect(subject.device).to be_a LogStashLogger::Device::MultiDelegator
|
71
73
|
expect(subject.device.devices.map(&:class)).to eq([
|
72
74
|
LogStashLogger::Device::UDP,
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
require 'pry'
|
2
2
|
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start
|
5
|
+
if ENV['CI']=='true'
|
6
|
+
require 'codecov'
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
8
|
+
end
|
9
|
+
|
3
10
|
RSpec.configure do |config|
|
4
11
|
config.order = "random"
|
5
12
|
|
@@ -49,12 +56,24 @@ RSpec.shared_context 'device' do
|
|
49
56
|
let(:file) { Tempfile.new('test') }
|
50
57
|
let(:file_device) { LogStashLogger::Device.new(type: :file, path: file.path)}
|
51
58
|
|
59
|
+
let(:io) { StringIO.new }
|
52
60
|
let(:io_device) { LogStashLogger::Device.new(type: :io, io: io)}
|
53
61
|
|
54
62
|
let(:redis_device) { LogStashLogger::Device.new(type: :redis, sync: true) }
|
55
63
|
let(:kafka_device) { LogStashLogger::Device.new(type: :kafka, sync: true) }
|
56
|
-
|
57
|
-
let(:
|
64
|
+
|
65
|
+
let(:outputs) { [{type: :stdout}, {type: :io, io: io}] }
|
66
|
+
let(:multi_delegator_device) { LogStashLogger::Device.new(type: :multi_delegator, outputs: outputs) }
|
67
|
+
let(:balancer_device) { LogStashLogger::Device.new(type: :balancer, outputs: outputs) }
|
68
|
+
let(:multi_logger) do
|
69
|
+
LogStashLogger.new(
|
70
|
+
type: :multi_logger,
|
71
|
+
outputs: [
|
72
|
+
{ type: :stdout, formatter: ::Logger::Formatter },
|
73
|
+
{ type: :io, io: io }
|
74
|
+
]
|
75
|
+
)
|
76
|
+
end
|
58
77
|
|
59
78
|
let(:udp_uri) { "udp://localhost:5228" }
|
60
79
|
let(:tcp_uri) { "tcp://localhost:5229" }
|
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.
|
4
|
+
version: 0.13.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: 2015-
|
11
|
+
date: 2015-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-event
|
@@ -195,6 +195,7 @@ files:
|
|
195
195
|
- lib/logstash-logger/formatter/json_lines.rb
|
196
196
|
- lib/logstash-logger/formatter/logstash_event.rb
|
197
197
|
- lib/logstash-logger/logger.rb
|
198
|
+
- lib/logstash-logger/multi_logger.rb
|
198
199
|
- lib/logstash-logger/railtie.rb
|
199
200
|
- lib/logstash-logger/tagged_logging.rb
|
200
201
|
- lib/logstash-logger/version.rb
|
@@ -229,6 +230,7 @@ files:
|
|
229
230
|
- spec/formatter/logstash_event_spec.rb
|
230
231
|
- spec/formatter_spec.rb
|
231
232
|
- spec/logger_spec.rb
|
233
|
+
- spec/multi_logger_spec.rb
|
232
234
|
- spec/rails_spec.rb
|
233
235
|
- spec/spec_helper.rb
|
234
236
|
- spec/tagged_logging_spec.rb
|
@@ -279,6 +281,7 @@ test_files:
|
|
279
281
|
- spec/formatter/logstash_event_spec.rb
|
280
282
|
- spec/formatter_spec.rb
|
281
283
|
- spec/logger_spec.rb
|
284
|
+
- spec/multi_logger_spec.rb
|
282
285
|
- spec/rails_spec.rb
|
283
286
|
- spec/spec_helper.rb
|
284
287
|
- spec/tagged_logging_spec.rb
|