logstash-logger-yajl 0.27.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.
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,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,11 @@
1
+ module LogStashLogger
2
+ module Formatter
3
+ class Cee < Base
4
+ private
5
+
6
+ def format_event(event)
7
+ "@cee:#{event.to_json}"
8
+ end
9
+ end
10
+ end
11
+ 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,11 @@
1
+ module LogStashLogger
2
+ module Formatter
3
+ class Json < Base
4
+ private
5
+
6
+ def format_event(event)
7
+ event.to_json
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module LogStashLogger
2
+ module Formatter
3
+ class JsonLines < Base
4
+ private
5
+
6
+ def format_event(event)
7
+ "#{event.to_json}\n"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module LogStashLogger
2
+ module Formatter
3
+ class LogStashEvent < Base
4
+ end
5
+ end
6
+ 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