logstash-logger-yajl 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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