semantic_logger 3.0.1 → 3.1.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/semantic_logger.rb +29 -13
  4. data/lib/semantic_logger/ansi_colors.rb +27 -0
  5. data/lib/semantic_logger/appender/base.rb +54 -128
  6. data/lib/semantic_logger/appender/bugsnag.rb +29 -19
  7. data/lib/semantic_logger/appender/elasticsearch.rb +9 -9
  8. data/lib/semantic_logger/appender/file.rb +40 -18
  9. data/lib/semantic_logger/appender/graylog.rb +30 -26
  10. data/lib/semantic_logger/appender/http.rb +14 -19
  11. data/lib/semantic_logger/appender/mongodb.rb +20 -20
  12. data/lib/semantic_logger/appender/new_relic.rb +15 -15
  13. data/lib/semantic_logger/appender/splunk.rb +1 -1
  14. data/lib/semantic_logger/appender/splunk_http.rb +28 -25
  15. data/lib/semantic_logger/appender/syslog.rb +41 -42
  16. data/lib/semantic_logger/appender/wrapper.rb +19 -17
  17. data/lib/semantic_logger/base.rb +57 -32
  18. data/lib/semantic_logger/concerns/compatibility.rb +51 -0
  19. data/lib/semantic_logger/debug_as_trace_logger.rb +6 -2
  20. data/lib/semantic_logger/formatters/color.rb +66 -0
  21. data/lib/semantic_logger/formatters/default.rb +39 -0
  22. data/lib/semantic_logger/formatters/json.rb +16 -0
  23. data/lib/semantic_logger/jruby/garbage_collection_logger.rb +1 -1
  24. data/lib/semantic_logger/log.rb +13 -8
  25. data/lib/semantic_logger/loggable.rb +2 -2
  26. data/lib/semantic_logger/logger.rb +18 -13
  27. data/lib/semantic_logger/metrics/new_relic.rb +18 -0
  28. data/lib/semantic_logger/metrics/statsd.rb +48 -0
  29. data/lib/semantic_logger/semantic_logger.rb +122 -55
  30. data/lib/semantic_logger/version.rb +1 -1
  31. data/test/appender/bugsnag_test.rb +12 -3
  32. data/test/appender/mongodb_test.rb +6 -5
  33. data/test/appender/new_relic_test.rb +1 -1
  34. data/test/appender/splunk_http_test.rb +1 -0
  35. data/test/concerns/compatibility_test.rb +106 -0
  36. data/test/debug_as_trace_logger_test.rb +1 -1
  37. data/test/loggable_test.rb +1 -1
  38. data/test/logger_test.rb +183 -24
  39. metadata +12 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50213eafcd6560b8240844cfb686a2a954537091
4
- data.tar.gz: d6df1d6905b315ccef4915cf59b819e62d2697bf
3
+ metadata.gz: 7010f9d28a473c9cd0c9fb9d52608216bad68043
4
+ data.tar.gz: 052152f47b9eb211a26c47a2bbbff8742f497449
5
5
  SHA512:
6
- metadata.gz: 048295e8e5a07f91ffe44a2108cb12135fbcfb25d604ad3ec0656e41cc0435689dc215de8bd0c994b81ec1fcf4e850e46d7733c7e2a5676e3b2e92ecc42971e5
7
- data.tar.gz: ce6f018889578dc8a44855e2bfc528d939cf5b8c0bd4872c41f55b5e1537adb8e99cd231c86e4829164bea1a5f1c2b728c2df52c566d79d73bcbf7bf578370b5
6
+ metadata.gz: 17d21c7f8bc35b93e52074cfac26bb0c350c989b589a8fb4a096c43a71148b4e245ace66ef36c8af9693355dc3741623896afb48bc2a01473b062a3ee1b6111a
7
+ data.tar.gz: 43eaa8a554e95b8936e4a595593977e30a98b849dcaa9d419762420a0f3edcd03d9f1f923cdeda2897b48332c1b5bcd89a9500f1df181d57283e56c11cc296ac
data/README.md CHANGED
@@ -65,7 +65,7 @@ require 'semantic_logger'
65
65
  SemanticLogger.default_level = :trace
66
66
 
67
67
  # Log to a file, and use the colorized formatter
68
- SemanticLogger.add_appender('development.log', &SemanticLogger::Appender::Base.colorized_formatter)
68
+ SemanticLogger.add_appender(file: 'development.log', formatter: :color)
69
69
  ```
70
70
 
71
71
  If running rails, see: [Semantic Logger Rails](http://rocketjob.github.io/semantic_logger/rails.html)
@@ -4,6 +4,7 @@ require 'semantic_logger/semantic_logger'
4
4
 
5
5
  # @formatter:off
6
6
  module SemanticLogger
7
+ autoload :AnsiColors, 'semantic_logger/ansi_colors'
7
8
  autoload :Base, 'semantic_logger/base'
8
9
  autoload :DebugAsTraceLogger, 'semantic_logger/debug_as_trace_logger'
9
10
  autoload :Log, 'semantic_logger/log'
@@ -11,20 +12,34 @@ module SemanticLogger
11
12
  autoload :Loggable, 'semantic_logger/loggable'
12
13
 
13
14
  module Appender
14
- autoload :Base, 'semantic_logger/appender/base'
15
- autoload :Bugsnag, 'semantic_logger/appender/bugsnag'
16
- autoload :Elasticsearch, 'semantic_logger/appender/elasticsearch'
17
- autoload :File, 'semantic_logger/appender/file'
18
- autoload :Graylog, 'semantic_logger/appender/graylog'
19
- autoload :Http, 'semantic_logger/appender/http'
20
- autoload :MongoDB, 'semantic_logger/appender/mongodb'
21
- autoload :NewRelic, 'semantic_logger/appender/new_relic'
22
- autoload :Splunk, 'semantic_logger/appender/splunk'
23
- autoload :SplunkHttp, 'semantic_logger/appender/splunk_http'
24
- autoload :Syslog, 'semantic_logger/appender/syslog'
25
- autoload :Wrapper, 'semantic_logger/appender/wrapper'
15
+ autoload :Base, 'semantic_logger/appender/base'
16
+ autoload :Bugsnag, 'semantic_logger/appender/bugsnag'
17
+ autoload :Elasticsearch, 'semantic_logger/appender/elasticsearch'
18
+ autoload :File, 'semantic_logger/appender/file'
19
+ autoload :Graylog, 'semantic_logger/appender/graylog'
20
+ autoload :Http, 'semantic_logger/appender/http'
21
+ autoload :MongoDB, 'semantic_logger/appender/mongodb'
22
+ autoload :NewRelic, 'semantic_logger/appender/new_relic'
23
+ autoload :Splunk, 'semantic_logger/appender/splunk'
24
+ autoload :SplunkHttp, 'semantic_logger/appender/splunk_http'
25
+ autoload :Syslog, 'semantic_logger/appender/syslog'
26
+ autoload :Wrapper, 'semantic_logger/appender/wrapper'
27
+ end
28
+
29
+ module Concerns
30
+ autoload :Compatibility, 'semantic_logger/concerns/compatibility'
31
+ end
32
+
33
+ module Formatters
34
+ autoload :Color, 'semantic_logger/formatters/color'
35
+ autoload :Default, 'semantic_logger/formatters/default'
36
+ autoload :Json, 'semantic_logger/formatters/json'
37
+ end
38
+
39
+ module Metrics
40
+ autoload :NewRelic, 'semantic_logger/metrics/new_relic'
41
+ autoload :Statsd, 'semantic_logger/metrics/statsd'
26
42
  end
27
- # @formatter:on
28
43
 
29
44
  if defined?(JRuby)
30
45
  module JRuby
@@ -32,6 +47,7 @@ module SemanticLogger
32
47
  end
33
48
  end
34
49
  end
50
+ # @formatter:on
35
51
 
36
52
  # Flush all appenders at exit, waiting for outstanding messages on the queue
37
53
  # to be written first
@@ -0,0 +1,27 @@
1
+ module SemanticLogger
2
+ # Formatting & colors used by optional color formatter
3
+ module AnsiColors
4
+ CLEAR = "\e[0m"
5
+ BOLD = "\e[1m"
6
+ BLACK = "\e[30m"
7
+ RED = "\e[31m"
8
+ GREEN = "\e[32m"
9
+ YELLOW = "\e[33m"
10
+ BLUE = "\e[34m"
11
+ MAGENTA = "\e[35m"
12
+ CYAN = "\e[36m"
13
+ WHITE = "\e[37m"
14
+
15
+ # Maps the log level to a color for colorized formatters
16
+ # Since this map is not frozen, it can be modified as needed
17
+ LEVEL_MAP = {
18
+ trace: MAGENTA,
19
+ debug: GREEN,
20
+ info: CYAN,
21
+ warn: BOLD,
22
+ error: RED,
23
+ fatal: RED
24
+ }
25
+ end
26
+
27
+ end
@@ -1,10 +1,3 @@
1
- require 'json'
2
- # Load AwesomePrint if available
3
- begin
4
- require 'awesome_print'
5
- rescue LoadError
6
- end
7
-
8
1
  # Base appender
9
2
  #
10
3
  # Abstract base class for appenders
@@ -16,128 +9,42 @@ end
16
9
  module SemanticLogger
17
10
  module Appender
18
11
 
19
- # Formatting & colors used by optional colorized_formatter
20
- module AnsiColors
21
- CLEAR = "\e[0m"
22
- BOLD = "\e[1m"
23
- BLACK = "\e[30m"
24
- RED = "\e[31m"
25
- GREEN = "\e[32m"
26
- YELLOW = "\e[33m"
27
- BLUE = "\e[34m"
28
- MAGENTA = "\e[35m"
29
- CYAN = "\e[36m"
30
- WHITE = "\e[37m"
31
-
32
- # Maps the log level to a color for colorized formatters
33
- # Since this map is not frozen, it can be modified as needed
34
- LEVEL_MAP = {
35
- trace: MAGENTA,
36
- debug: GREEN,
37
- info: CYAN,
38
- warn: BOLD,
39
- error: RED,
40
- fatal: RED
41
- }
42
- end
12
+ # DEPRECATED, use SemanticLogger::AnsiColors
13
+ AnsiColors = SemanticLogger::AnsiColors
43
14
 
44
15
  class Base < SemanticLogger::Base
16
+ # Every logger has its own formatter
45
17
  attr_accessor :formatter
46
18
 
47
- # Default log formatter
48
- # Replace this formatter by supplying a Block to the initializer
49
- # Generates logs of the form:
50
- # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
51
- def default_formatter
52
- Proc.new do |log, logger|
53
- # Header with date, time, log level and process info
54
- entry = "#{log.formatted_time} #{log.level_to_s} [#{log.process_info}]"
55
-
56
- # Tags
57
- entry << ' ' << log.tags.collect { |tag| "[#{tag}]" }.join(' ') if log.tags && (log.tags.size > 0)
58
-
59
- # Duration
60
- entry << " (#{log.duration_human})" if log.duration
61
-
62
- # Class / app name
63
- entry << " #{log.name}"
64
-
65
- # Log message
66
- entry << " -- #{log.message}" if log.message
67
-
68
- # Payload
69
- if payload = log.payload_to_s(false)
70
- entry << ' -- ' << payload
71
- end
72
-
73
- # Exceptions
74
- if log.exception
75
- entry << " -- Exception: #{log.exception.class}: #{log.exception.message}\n"
76
- entry << log.backtrace_to_s
77
- end
78
- entry
79
- end
19
+ # Returns the current log level if set, otherwise it logs everything it receives
20
+ def level
21
+ @level || :trace
80
22
  end
81
23
 
82
- # Optional log formatter to colorize log output
83
- # To use this formatter
84
- # SemanticLogger.add_appender($stdout, &SemanticLogger::Appender::Base.colorized_formatter)
85
- #
86
- # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
87
- def self.colorized_formatter
88
- Proc.new do |log, logger|
89
- colors = SemanticLogger::Appender::AnsiColors
90
- level_color = colors::LEVEL_MAP[log.level]
91
-
92
- # Header with date, time, log level and process info
93
- entry = "#{log.formatted_time} #{level_color}#{log.level_to_s}#{colors::CLEAR} [#{log.process_info}]"
94
-
95
- # Tags
96
- entry << ' ' << log.tags.collect { |tag| "[#{level_color}#{tag}#{colors::CLEAR}]" }.join(' ') if log.tags && (log.tags.size > 0)
97
-
98
- # Duration
99
- entry << " (#{colors::BOLD}#{log.duration_human}#{colors::CLEAR})" if log.duration
100
-
101
- # Class / app name
102
- entry << " #{level_color}#{log.name}#{colors::CLEAR}"
103
-
104
- # Log message
105
- entry << " -- #{log.message}" if log.message
106
-
107
- # Payload
108
- if payload = log.payload_to_s(true)
109
- entry << ' -- ' << payload
110
- end
111
-
112
- # Exceptions
113
- if log.exception
114
- entry << " -- Exception: #{colors::BOLD}#{log.exception.class}: #{log.exception.message}#{colors::CLEAR}\n"
115
- entry << log.backtrace_to_s
116
- end
117
- entry
118
- end
24
+ # An appender can implement a flush method if it is able to.
25
+ def flush
26
+ # NOOP
119
27
  end
120
28
 
121
- # Optional log formatter to output data in a hash format
122
- # To use this formatter
123
- # SemanticLogger.add_appender($stdout, &SemanticLogger::Appender::Base.json_formatter)
124
- def self.json_formatter
125
- Proc.new do |log, logger|
126
- h = log.to_h
127
- h.delete(:time)
128
- h[:timestamp] = log.time.utc.iso8601(defined?(JRuby) ? 3 : 6)
129
- h.to_json
130
- end
29
+ # DEPRECATED: use SemanticLogger::Formatters::Default.new
30
+ def default_formatter
31
+ warn '[DEPRECATION] SemanticLogger::Appender::Base.default_level is deprecated. Please use SemanticLogger::Formatters::Default.new instead.'
32
+ formatter = SemanticLogger::Formatters::Default.new
33
+ Proc.new { |log, logger| formatter.call(log, logger) }
131
34
  end
132
35
 
133
- def flush
134
- # An appender can implement a flush method if it supports it.
36
+ # DEPRECATED: use SemanticLogger::Formatters::Color.new
37
+ def self.colorized_formatter
38
+ warn '[DEPRECATION] SemanticLogger::Appender::Base.colorized_formatter is deprecated. Please use SemanticLogger::Formatters::Color.new instead.'
39
+ formatter = SemanticLogger::Formatters::Color.new
40
+ Proc.new { |log, logger| formatter.call(log, logger) }
135
41
  end
136
42
 
137
- # Returns the current log level if set, otherwise it returns the global
138
- # default log level
139
- def level
140
- @level || :trace
43
+ # DEPRECATED: use SemanticLogger::Formatters::Json.new
44
+ def self.json_formatter
45
+ warn '[DEPRECATION] SemanticLogger::Appender::Base.json_formatter is deprecated. Please use SemanticLogger::Formatters::Json.new instead.'
46
+ formatter = SemanticLogger::Formatters::Json.new
47
+ Proc.new { |log, logger| formatter.call(log, logger) }
141
48
  end
142
49
 
143
50
  private
@@ -145,18 +52,32 @@ module SemanticLogger
145
52
  # Initializer for Abstract Class SemanticLogger::Appender
146
53
  #
147
54
  # Parameters
148
- # level [Symbol]
149
- # Only allow log entries of this level or higher to be written to this appender
150
- # For example if set to :warn, this appender would only log :warn and :fatal
151
- # log messages when other appenders could be logging :info and lower
55
+ # level: [:trace | :debug | :info | :warn | :error | :fatal]
56
+ # Override the log level for this appender.
57
+ # Default: :error
58
+ #
59
+ # formatter: [Object|Proc]
60
+ # An instance of a class that implements #call, or a Proc to be used to format
61
+ # the output from this appender
62
+ # Default: Use the built-in formatter (See: #call)
152
63
  #
153
- # filter [RegExp|Proc]
154
- # Optional regular expression to filter log entries based on the class name
155
- # When filter is a proc, it is passed the entire log struct and must return
156
- # true or false indicating whether to log the message
157
- def initialize(level=nil, filter=nil, &block)
158
- # Set the formatter to the supplied block
159
- @formatter = block || default_formatter
64
+ # filter: [Regexp|Proc]
65
+ # RegExp: Only include log messages where the class name matches the supplied.
66
+ # regular expression. All other messages will be ignored.
67
+ # Proc: Only include log messages where the supplied Proc returns true
68
+ # The Proc must return true or false.
69
+ def initialize(options={}, &block)
70
+ # Backward compatibility
71
+ options = {level: options} unless options.is_a?(Hash)
72
+ options = options.dup
73
+ level = options.delete(:level)
74
+ filter = options.delete(:filter)
75
+ @formatter = options.delete(:formatter)
76
+ @formatter = self.class.extract_formatter(@formatter) if @formatter.is_a?(Symbol)
77
+ @formatter ||= block
78
+ # Default to #call method for formatting if defined for an appender
79
+ @formatter ||= (respond_to?(:call) ? self : SemanticLogger::Formatters::Default.new)
80
+ raise(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
160
81
 
161
82
  # Appenders don't take a class name, so use this class name if an appender
162
83
  # is logged to directly
@@ -170,6 +91,11 @@ module SemanticLogger
170
91
  @level_index || 0
171
92
  end
172
93
 
94
+ # Return formatter for supplied Symbol
95
+ def self.extract_formatter(formatter)
96
+ SemanticLogger.send(:named_formatter, formatter).new
97
+ end
98
+
173
99
  end
174
100
  end
175
101
  end
@@ -7,51 +7,53 @@ end
7
7
  # Send log messages to Bugsnag
8
8
  #
9
9
  # Example:
10
- # SemanticLogger.add_appender(SemanticLogger::Appender::Bugsnag.new)
10
+ # SemanticLogger.add_appender(appender: :bugsnag)
11
11
  #
12
12
  class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
13
- # Create Appender
13
+ # Create Bugsnag Error / Exception Appender
14
14
  #
15
15
  # Parameters
16
16
  # level: [:trace | :debug | :info | :warn | :error | :fatal]
17
17
  # Override the log level for this appender.
18
18
  # Default: :error
19
19
  #
20
+ # formatter: [Object|Proc]
21
+ # An instance of a class that implements #call, or a Proc to be used to format
22
+ # the output from this appender
23
+ # Default: Use the built-in formatter (See: #call)
24
+ #
20
25
  # filter: [Regexp|Proc]
21
26
  # RegExp: Only include log messages where the class name matches the supplied.
22
27
  # regular expression. All other messages will be ignored.
23
28
  # Proc: Only include log messages where the supplied Proc returns true
24
29
  # The Proc must return true or false.
25
30
  def initialize(options = {}, &block)
26
- options = {level: options} unless options.is_a?(Hash)
27
- @options = options.dup
28
- level = @options.delete(:level) || :error
29
- filter = @options.delete(:filter)
31
+ # Backward compatibility
32
+ options = {level: options} unless options.is_a?(Hash)
33
+ options = options.dup
34
+ options[:level] = :error unless options.has_key?(:level)
30
35
 
31
- raise 'Bugsnag only supports :info, :warn, or :error log levels' unless [:info, :warn, :error].include?(level)
36
+ raise 'Bugsnag only supports :info, :warn, or :error log levels' unless [:info, :warn, :error].include?(options[:level])
32
37
 
33
38
  # Replace the Bugsnag logger so that we can identify its log messages and not forward them to Bugsnag
34
39
  Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] }
35
- super(level, &block)
40
+
41
+ super(options, &block)
36
42
  end
37
43
 
38
44
  # Returns [Hash] of parameters to send to Bugsnag.
39
- def default_formatter
40
- Proc.new do |log|
41
- h = log.to_h
42
- h[:severity] = log_level(log)
43
- h.delete(:time)
44
- h.delete(:exception)
45
- h
46
- end
45
+ def call(log, logger)
46
+ h = log.to_h
47
+ h[:severity] = log_level(log)
48
+ h.delete(:time)
49
+ h.delete(:exception)
50
+ h
47
51
  end
48
52
 
49
53
  # Send an error notification to Bugsnag
50
54
  def log(log)
51
55
  # Only log if level is warn, or error.
52
56
  return false if (level_index > (log.level_index || 0)) ||
53
- # We don't want to send fatal as those are already captured by Bugsnag.
54
- #(log.level == :fatal) ||
55
57
  # Ignore logs coming from Bugsnag itself
56
58
  (log.name == 'Bugsnag') ||
57
59
  # Filtered out?
@@ -75,7 +77,15 @@ class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
75
77
 
76
78
  private
77
79
 
80
+ # Bugsnag supports: error, warning or info
78
81
  def log_level(log)
79
- log.level == :warn ? 'warning' : log.level.to_s
82
+ case log.level
83
+ when :error, :fatal
84
+ 'error'
85
+ when :warn
86
+ 'warning'
87
+ else
88
+ 'info'
89
+ end
80
90
  end
81
91
  end
@@ -2,15 +2,10 @@ require 'date'
2
2
  # Forward all log messages to Elasticsearch.
3
3
  #
4
4
  # Example:
5
- # appender = SemanticLogger::Appender::Elasticsearch.new(
6
- # url: 'http://localhost:9200'
5
+ # SemanticLogger.add_appender(
6
+ # appender: :elasticsearch,
7
+ # url: 'http://localhost:9200'
7
8
  # )
8
- #
9
- # # Optional: Exclude health_check log entries
10
- # appender.filter = Proc.new { |log| log.message !~ /(health_check|Not logged in)/}
11
- #
12
- # SemanticLogger.add_appender(appender)
13
- #
14
9
  class SemanticLogger::Appender::Elasticsearch < SemanticLogger::Appender::Http
15
10
  attr_accessor :index, :type
16
11
 
@@ -31,6 +26,11 @@ class SemanticLogger::Appender::Elasticsearch < SemanticLogger::Appender::Http
31
26
  # Override the log level for this appender.
32
27
  # Default: SemanticLogger.default_level
33
28
  #
29
+ # formatter: [Object|Proc]
30
+ # An instance of a class that implements #call, or a Proc to be used to format
31
+ # the output from this appender
32
+ # Default: Use the built-in formatter (See: #call)
33
+ #
34
34
  # filter: [Regexp|Proc]
35
35
  # RegExp: Only include log messages where the class name matches the supplied.
36
36
  # regular expression. All other messages will be ignored.
@@ -38,7 +38,7 @@ class SemanticLogger::Appender::Elasticsearch < SemanticLogger::Appender::Http
38
38
  # The Proc must return true or false.
39
39
  def initialize(options, &block)
40
40
  options = options.dup
41
- @index = options.delete(:index) || "semantic_logger"
41
+ @index = options.delete(:index) || 'semantic_logger'
42
42
  @type = options.delete(:type) || 'log'
43
43
  options[:url] ||= 'http://localhost:9200'
44
44