logstash-logger-yajl 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +26 -0
- data/Appraisals +23 -0
- data/CHANGELOG.md +203 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +880 -0
- data/Rakefile +23 -0
- data/gemfiles/rails_3.2.gemfile +9 -0
- data/gemfiles/rails_4.0.gemfile +9 -0
- data/gemfiles/rails_4.1.gemfile +9 -0
- data/gemfiles/rails_4.2.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +9 -0
- data/lib/logstash-event.rb +1 -0
- data/lib/logstash-logger.rb +11 -0
- data/lib/logstash-logger/buffer.rb +336 -0
- data/lib/logstash-logger/configuration.rb +29 -0
- data/lib/logstash-logger/device.rb +67 -0
- data/lib/logstash-logger/device/aws_stream.rb +94 -0
- data/lib/logstash-logger/device/balancer.rb +40 -0
- data/lib/logstash-logger/device/base.rb +73 -0
- data/lib/logstash-logger/device/connectable.rb +131 -0
- data/lib/logstash-logger/device/file.rb +23 -0
- data/lib/logstash-logger/device/firehose.rb +42 -0
- data/lib/logstash-logger/device/io.rb +11 -0
- data/lib/logstash-logger/device/kafka.rb +57 -0
- data/lib/logstash-logger/device/kinesis.rb +44 -0
- data/lib/logstash-logger/device/multi_delegator.rb +36 -0
- data/lib/logstash-logger/device/redis.rb +69 -0
- data/lib/logstash-logger/device/socket.rb +21 -0
- data/lib/logstash-logger/device/stderr.rb +13 -0
- data/lib/logstash-logger/device/stdout.rb +14 -0
- data/lib/logstash-logger/device/tcp.rb +86 -0
- data/lib/logstash-logger/device/udp.rb +12 -0
- data/lib/logstash-logger/device/unix.rb +18 -0
- data/lib/logstash-logger/formatter.rb +51 -0
- data/lib/logstash-logger/formatter/base.rb +73 -0
- data/lib/logstash-logger/formatter/cee.rb +11 -0
- data/lib/logstash-logger/formatter/cee_syslog.rb +22 -0
- data/lib/logstash-logger/formatter/json.rb +11 -0
- data/lib/logstash-logger/formatter/json_lines.rb +11 -0
- data/lib/logstash-logger/formatter/logstash_event.rb +6 -0
- data/lib/logstash-logger/logger.rb +106 -0
- data/lib/logstash-logger/multi_logger.rb +153 -0
- data/lib/logstash-logger/railtie.rb +51 -0
- data/lib/logstash-logger/silenced_logging.rb +83 -0
- data/lib/logstash-logger/tagged_logging.rb +40 -0
- data/lib/logstash-logger/version.rb +3 -0
- data/lib/logstash/event.rb +272 -0
- data/lib/logstash/namespace.rb +15 -0
- data/lib/logstash/util.rb +105 -0
- data/lib/logstash/util/fieldreference.rb +49 -0
- data/logstash-logger.gemspec +42 -0
- data/samples/example.crt +16 -0
- data/samples/example.key +15 -0
- data/samples/file.conf +11 -0
- data/samples/redis.conf +12 -0
- data/samples/ssl.conf +15 -0
- data/samples/syslog.conf +10 -0
- data/samples/tcp.conf +11 -0
- data/samples/udp.conf +11 -0
- data/samples/unix.conf +11 -0
- data/spec/configuration_spec.rb +27 -0
- data/spec/constructor_spec.rb +30 -0
- data/spec/device/balancer_spec.rb +31 -0
- data/spec/device/connectable_spec.rb +74 -0
- data/spec/device/file_spec.rb +15 -0
- data/spec/device/firehose_spec.rb +41 -0
- data/spec/device/io_spec.rb +13 -0
- data/spec/device/kafka_spec.rb +32 -0
- data/spec/device/kinesis_spec.rb +41 -0
- data/spec/device/multi_delegator_spec.rb +31 -0
- data/spec/device/redis_spec.rb +52 -0
- data/spec/device/socket_spec.rb +15 -0
- data/spec/device/stderr_spec.rb +16 -0
- data/spec/device/stdout_spec.rb +31 -0
- data/spec/device/tcp_spec.rb +120 -0
- data/spec/device/udp_spec.rb +9 -0
- data/spec/device/unix_spec.rb +23 -0
- data/spec/device_spec.rb +97 -0
- data/spec/formatter/base_spec.rb +125 -0
- data/spec/formatter/cee_spec.rb +15 -0
- data/spec/formatter/cee_syslog_spec.rb +43 -0
- data/spec/formatter/json_lines_spec.rb +14 -0
- data/spec/formatter/json_spec.rb +10 -0
- data/spec/formatter/logstash_event_spec.rb +10 -0
- data/spec/formatter_spec.rb +79 -0
- data/spec/logger_spec.rb +128 -0
- data/spec/logstash_event_spec.rb +139 -0
- data/spec/multi_logger_spec.rb +59 -0
- data/spec/rails_spec.rb +91 -0
- data/spec/silenced_logging_spec.rb +31 -0
- data/spec/spec_helper.rb +111 -0
- data/spec/syslog_spec.rb +32 -0
- data/spec/tagged_logging_spec.rb +32 -0
- metadata +385 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'socket'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module LogStashLogger
|
6
|
+
module Formatter
|
7
|
+
HOST = ::Socket.gethostname
|
8
|
+
|
9
|
+
class Base < ::Logger::Formatter
|
10
|
+
include ::LogStashLogger::TaggedLogging::Formatter
|
11
|
+
|
12
|
+
def initialize(customize_event: nil)
|
13
|
+
@customize_event = customize_event
|
14
|
+
super()
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(severity, time, _progname, message)
|
18
|
+
event = build_event(message, severity, time)
|
19
|
+
format_event(event) unless event.cancelled?
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def build_event(message, severity, time)
|
25
|
+
data = message
|
26
|
+
if data.is_a?(String) && data.start_with?('{'.freeze)
|
27
|
+
data = (JSON.parse(message) rescue nil) || message
|
28
|
+
end
|
29
|
+
|
30
|
+
event = case data
|
31
|
+
when LogStash::Event
|
32
|
+
data.clone
|
33
|
+
when Hash
|
34
|
+
event_data = data.clone
|
35
|
+
event_data['message'.freeze] = event_data.delete(:message) if event_data.key?(:message)
|
36
|
+
event_data['tags'.freeze] = event_data.delete(:tags) if event_data.key?(:tags)
|
37
|
+
event_data['source'.freeze] = event_data.delete(:source) if event_data.key?(:source)
|
38
|
+
event_data['type'.freeze] = event_data.delete(:type) if event_data.key?(:type)
|
39
|
+
event_data['@timestamp'.freeze] = time
|
40
|
+
LogStash::Event.new(event_data)
|
41
|
+
else
|
42
|
+
LogStash::Event.new("message".freeze => msg2str(data), "@timestamp".freeze => time)
|
43
|
+
end
|
44
|
+
|
45
|
+
event['severity'.freeze] ||= severity
|
46
|
+
#event.type = progname
|
47
|
+
|
48
|
+
event['host'.freeze] ||= HOST
|
49
|
+
|
50
|
+
current_tags.each { |tag| event.tag(tag) }
|
51
|
+
|
52
|
+
LogStashLogger.configuration.customize_event_block.call(event) if LogStashLogger.configuration.customize_event_block.respond_to?(:call)
|
53
|
+
|
54
|
+
@customize_event.call(event) if @customize_event
|
55
|
+
|
56
|
+
# In case Time#to_json has been overridden
|
57
|
+
if event.timestamp.is_a?(Time)
|
58
|
+
event.timestamp = event.timestamp.iso8601(3)
|
59
|
+
end
|
60
|
+
|
61
|
+
if LogStashLogger.configuration.max_message_size && event['message']
|
62
|
+
event['message'.freeze] = event['message'.freeze].byteslice(0, LogStashLogger.configuration.max_message_size)
|
63
|
+
end
|
64
|
+
|
65
|
+
event
|
66
|
+
end
|
67
|
+
|
68
|
+
def format_event(event)
|
69
|
+
event
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LogStashLogger
|
2
|
+
module Formatter
|
3
|
+
class CeeSyslog < Cee
|
4
|
+
def call(severity, time, progname, message)
|
5
|
+
@progname = progname
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def build_facility(host)
|
12
|
+
facility = host.dup
|
13
|
+
facility << " #{@progname}" if @progname
|
14
|
+
facility
|
15
|
+
end
|
16
|
+
|
17
|
+
def format_event(event)
|
18
|
+
"#{build_facility(event["host".freeze])}:#{super}\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'logstash-logger/tagged_logging'
|
3
|
+
require 'logstash-logger/silenced_logging'
|
4
|
+
|
5
|
+
module LogStashLogger
|
6
|
+
autoload :MultiLogger, 'logstash-logger/multi_logger'
|
7
|
+
|
8
|
+
def self.new(*args)
|
9
|
+
opts = extract_opts(*args)
|
10
|
+
build_logger(opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.extended(base)
|
14
|
+
base.instance_eval do
|
15
|
+
class << self
|
16
|
+
attr_reader :device
|
17
|
+
end
|
18
|
+
|
19
|
+
def flush
|
20
|
+
!!(@device.flush if @device.respond_to?(:flush))
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset
|
24
|
+
@device.reset if @device.respond_to?(:reset)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def self.extract_opts(*args)
|
32
|
+
args.flatten!
|
33
|
+
|
34
|
+
if args.length > 1
|
35
|
+
if args.all?{|arg| arg.is_a?(Hash)}
|
36
|
+
# Deprecated array of hashes
|
37
|
+
warn "[LogStashLogger] Passing an array of hashes to the constructor is deprecated. Please replace with an options hash: { type: :multi_delegator, outputs: [...] }"
|
38
|
+
{ type: :multi_delegator, outputs: args }
|
39
|
+
else
|
40
|
+
# Deprecated host/port/type constructor
|
41
|
+
warn "[LogStashLogger] The (host, port, type) constructor is deprecated. Please use an options hash instead."
|
42
|
+
host, port, type = *args
|
43
|
+
{ host: host, port: port, type: type }
|
44
|
+
end
|
45
|
+
elsif Hash === args[0]
|
46
|
+
args[0]
|
47
|
+
else
|
48
|
+
fail ArgumentError, "Invalid LogStashLogger options"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.build_logger(opts)
|
53
|
+
formatter = Formatter.new(opts.delete(:formatter), customize_event: opts.delete(:customize_event))
|
54
|
+
|
55
|
+
logger_type = opts[:type].to_s.to_sym
|
56
|
+
logger = case logger_type
|
57
|
+
when :multi_logger
|
58
|
+
build_multi_logger(opts)
|
59
|
+
when :syslog
|
60
|
+
build_syslog_logger(opts)
|
61
|
+
else
|
62
|
+
build_default_logger(opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
logger.formatter = formatter if formatter
|
66
|
+
logger
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def self.build_default_logger(opts)
|
72
|
+
logger_class = opts.delete(:logger_class) || ::Logger
|
73
|
+
device = Device.new(opts)
|
74
|
+
logger_class.new(device).tap do |logger|
|
75
|
+
logger.instance_variable_set(:@device, device)
|
76
|
+
extend_logger(logger)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.build_multi_logger(opts)
|
81
|
+
output_configurations = opts.delete(:outputs) || []
|
82
|
+
loggers = output_configurations.map do |config|
|
83
|
+
logger_opts = opts.merge(config)
|
84
|
+
build_logger(logger_opts)
|
85
|
+
end
|
86
|
+
MultiLogger.new(loggers)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.build_syslog_logger(opts)
|
90
|
+
logger = begin
|
91
|
+
require 'syslog/logger'
|
92
|
+
|
93
|
+
Syslog::Logger.new(opts[:program_name], opts[:facility])
|
94
|
+
rescue ArgumentError
|
95
|
+
Syslog::Logger.new(opts[:program_name])
|
96
|
+
end
|
97
|
+
|
98
|
+
extend_logger(logger)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.extend_logger(logger)
|
102
|
+
logger.extend(self)
|
103
|
+
logger.extend(TaggedLogging)
|
104
|
+
logger.extend(SilencedLogging)
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# Adapted from https://github.com/ffmike/multilogger
|
2
|
+
module LogStashLogger
|
3
|
+
class MultiLogger < ::Logger
|
4
|
+
# Array of Loggers to be logged to. These can be anything that acts reasonably like a Logger.
|
5
|
+
attr_accessor :loggers
|
6
|
+
|
7
|
+
def level=(value)
|
8
|
+
super
|
9
|
+
@loggers.each do |logger|
|
10
|
+
logger.level = value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def progname=(value)
|
15
|
+
super
|
16
|
+
@loggers.each do |logger|
|
17
|
+
logger.progname = value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def datetime_format=(datetime_format)
|
22
|
+
super
|
23
|
+
@loggers.each do |logger|
|
24
|
+
logger.datetime_format = datetime_format
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def formatter=(formatter)
|
29
|
+
super
|
30
|
+
@loggers.each do |logger|
|
31
|
+
logger.formatter ||= formatter
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def silence(temporary_level = ::Logger::ERROR, &block)
|
36
|
+
silenceable_loggers = @loggers.select do |logger|
|
37
|
+
logger.respond_to?(:silence)
|
38
|
+
end
|
39
|
+
|
40
|
+
silence_loggers(temporary_level, silenceable_loggers, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def silence_loggers(temporary_level = ::Logger::ERROR, silenceable_loggers, &block)
|
44
|
+
return yield(self) if silenceable_loggers.empty?
|
45
|
+
|
46
|
+
silenceable_loggers.shift.silence(temporary_level) do
|
47
|
+
silence_loggers(temporary_level, silenceable_loggers, &block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
private :silence_loggers
|
51
|
+
|
52
|
+
def tagged(*tags, &block)
|
53
|
+
taggable_loggers = @loggers.select do |logger|
|
54
|
+
logger.respond_to?(:tagged)
|
55
|
+
end
|
56
|
+
|
57
|
+
tag_loggers(tags, taggable_loggers, &block)
|
58
|
+
end
|
59
|
+
|
60
|
+
def tag_loggers(tags, taggable_loggers, &block)
|
61
|
+
return yield(self) if taggable_loggers.empty?
|
62
|
+
|
63
|
+
taggable_loggers.shift.tagged(*tags) do
|
64
|
+
tag_loggers(tags, taggable_loggers, &block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
private :tag_loggers
|
68
|
+
|
69
|
+
# Any method not defined on standard Logger class, just send it on to anyone who will listen
|
70
|
+
def method_missing(name, *args, &block)
|
71
|
+
@loggers.each do |logger|
|
72
|
+
if logger.respond_to?(name)
|
73
|
+
logger.send(name, args, &block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# === Synopsis
|
80
|
+
#
|
81
|
+
# MultiLogger.new([logger1, logger2])
|
82
|
+
#
|
83
|
+
# === Args
|
84
|
+
#
|
85
|
+
# +loggers+::
|
86
|
+
# An array of loggers. Each one gets every message that is sent to the MultiLogger instance
|
87
|
+
#
|
88
|
+
# === Description
|
89
|
+
#
|
90
|
+
# Create an instance.
|
91
|
+
#
|
92
|
+
def initialize(loggers)
|
93
|
+
@loggers = []
|
94
|
+
super(nil)
|
95
|
+
@loggers = Array(loggers)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Methods that write to logs just write to each contained logger in turn
|
99
|
+
def add(severity, message = nil, progname = nil, &block)
|
100
|
+
@loggers.each do |logger|
|
101
|
+
logger.add(severity, message, progname, &block)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def <<(msg)
|
106
|
+
@loggers.each do |logger|
|
107
|
+
logger << msg
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def debug(progname = nil, &block)
|
112
|
+
@loggers.each do |logger|
|
113
|
+
logger.debug(progname, &block)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def info(progname = nil, &block)
|
118
|
+
@loggers.each do |logger|
|
119
|
+
logger.info(progname, &block)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def warn(progname = nil, &block)
|
124
|
+
@loggers.each do |logger|
|
125
|
+
logger.warn(progname, &block)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def error(progname = nil, &block)
|
130
|
+
@loggers.each do |logger|
|
131
|
+
logger.error(progname, &block)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def fatal(progname = nil, &block)
|
136
|
+
@loggers.each do |logger|
|
137
|
+
logger.fatal(progname, &block)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def unknown(progname = nil, &block)
|
142
|
+
@loggers.each do |logger|
|
143
|
+
logger.unknown(progname, &block)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def close
|
148
|
+
@loggers.each do |logger|
|
149
|
+
logger.close if logger.respond_to?(:close)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
|
3
|
+
module LogStashLogger
|
4
|
+
def self.setup(app)
|
5
|
+
return unless app.config.logstash.present?
|
6
|
+
|
7
|
+
logger_options = app.config.logstash
|
8
|
+
|
9
|
+
sanitized_logger_options = if logger_options.is_a?(Array)
|
10
|
+
logger_options.map do |opts|
|
11
|
+
sanitize_logger_options(app, opts)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
sanitize_logger_options(app, logger_options)
|
15
|
+
end
|
16
|
+
|
17
|
+
logger = LogStashLogger.new(sanitized_logger_options)
|
18
|
+
|
19
|
+
logger.level = ::Logger.const_get(app.config.log_level.to_s.upcase)
|
20
|
+
|
21
|
+
app.config.logger = logger
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.sanitize_logger_options(app, logger_options)
|
25
|
+
# Convert logger options to OrderedOptions if regular Hash
|
26
|
+
logger_options = ActiveSupport::OrderedOptions.new.merge(logger_options)
|
27
|
+
|
28
|
+
if parsed_uri_options = LogStashLogger::Device.parse_uri_config(logger_options)
|
29
|
+
logger_options.delete(:uri)
|
30
|
+
logger_options.merge!(parsed_uri_options)
|
31
|
+
end
|
32
|
+
|
33
|
+
if logger_options.type == :file
|
34
|
+
logger_options.path ||= app.config.paths["log"].first
|
35
|
+
end
|
36
|
+
|
37
|
+
if app.config.respond_to?(:autoflush_log)
|
38
|
+
logger_options.sync = app.config.autoflush_log
|
39
|
+
end
|
40
|
+
|
41
|
+
logger_options
|
42
|
+
end
|
43
|
+
|
44
|
+
class Railtie < ::Rails::Railtie
|
45
|
+
config.logstash = ActiveSupport::OrderedOptions.new
|
46
|
+
|
47
|
+
initializer :logstash_logger, before: :initialize_logger do |app|
|
48
|
+
LogStashLogger.setup(app)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|