nexus_semantic_logger 1.7.3 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fb8608fc5db931115c7c1398607eff97e56745183939261b1993ea10004e10e
4
- data.tar.gz: 9b326b54b65bcd45a0f5a8fef49e4d0b0112710028996afcb957ff0113aae8ff
3
+ metadata.gz: 71ea65404e5b4980ffa32eda0d91588142cd2571252117f1f651f566f506bb98
4
+ data.tar.gz: ade58c1fcc429f832d26ed23786d859068cefb6e33a1f7b5b32d2627de999c91
5
5
  SHA512:
6
- metadata.gz: f5d864a434d1499e2b0880b55f5969e2f0856e2625d9e20db54387b01610fea866cc09191276f2c2f5ff1601927f4a2a7140f42ca70993cf6f5c5499753c055e
7
- data.tar.gz: 240f197160c496ac997ae2c5cd33a672d656b6bf6280318e7926d5cb593ecac40f794316a9090dfa7984273bff9ed987cf6ef689e20591a62690dd3b40b971c5
6
+ metadata.gz: 0d488c447d1e7f14c49a0c33ff0ee79ff512346ea17557c68a91e4b204dd37d9bdafb04383ed4db1c7c2c71d15273a9375c49c1e031a9a710e2345b34f143db9
7
+ data.tar.gz: 3712bf027d2fc5668c3a593d8cbd79457aef86d69a19e5602bfe4929ba301e14f6ce9006680acfbf4ce777ba5ae42f18ee45cdb6fded3a3fa4d1e0f8c284479b
data/README.md CHANGED
@@ -9,7 +9,44 @@ As well as providing a semantic logger, this gem handles datadog telemetry assoc
9
9
  * logs
10
10
  * traces
11
11
  * metrics
12
- * statsd is automatically attached to datadog runtime metrics and may also be used for custom metrics.
12
+ * statsd is automatically attached to datadog runtime metrics and may also be used for custom metrics.
13
+
14
+ ### Customise log level per logger
15
+
16
+ For example, to show debug logging for `MySubscriber` while having all other logs on info.
17
+
18
+ ```
19
+ # The log level must be set to the lowest level which can be dynamically controlled.
20
+ LOG_LEVEL=DEBUG
21
+ # The default level for filtered logs.
22
+ LOG_NAMES_DEFAULT_LEVEL=INFO
23
+ # Per level overrides for filtered logs.
24
+ LOG_NAMES_DEBUG=MySubscriber
25
+ ```
26
+
27
+ * Customised log names are available for each level e.g. `LOG_NAMES_TRACE`
28
+ * Log names are matched on prefix.
29
+ * Multiple log names are supported via comma separated values.
30
+
31
+ ### Changing log level dynamically
32
+
33
+ The default level for filtered logs (`LOG_NAMES_DEFAULT_LEVEL`) may be changed on a running instance with the `WINCH`
34
+ signal. This cycles through the available levels `[trace debug info warn error fatal]`.
35
+
36
+ Note that you cannot dynamically enable a level lower than the `LOG_LEVEL`. Instead the env var must be adjusted and the
37
+ instance restarted.
38
+
39
+ Send signal: `pkill --signal WINCH --count --full "^puma.*"`
40
+
41
+ Instance output: `WINCH signal changed LOG_NAMES_DEFAULT_LEVEL from debug to info`
42
+
43
+ ### Querying current log level
44
+
45
+ The `SYS` signal will print the levels used by the running instance.
46
+
47
+ Send signal: `pkill --signal SYS --count --full "^puma.*"`
48
+
49
+ Instance output: `SYS signal reports LOG_LEVEL=debug LOG_NAMES_DEFAULT_LEVEL=warn`
13
50
 
14
51
  ### Sending metrics
15
52
 
@@ -32,8 +32,12 @@ module NexusSemanticLogger
32
32
  }
33
33
  end
34
34
 
35
+ def self.env_level
36
+ @@level ||= ENV.fetch('LOG_LEVEL', Rails.application.config.log_level).downcase
37
+ end
38
+
35
39
  def self.env_names_default_level
36
- @@names_default_level ||= ENV.fetch('LOG_NAMES_DEFAULT_LEVEL', Rails.application.config.log_level)
40
+ @@names_default_level ||= ENV.fetch('LOG_NAMES_DEFAULT_LEVEL', Rails.application.config.log_level).downcase
37
41
  end
38
42
 
39
43
  def self.env_names_trace
@@ -61,6 +65,7 @@ module NexusSemanticLogger
61
65
  end
62
66
 
63
67
  def self.flush
68
+ @@level = nil
64
69
  @@names_default_level = nil
65
70
  @@names_trace = nil
66
71
  @@names_debug = nil
@@ -73,5 +78,40 @@ module NexusSemanticLogger
73
78
  def self.fetch_env_names(var)
74
79
  ENV.fetch(var, '').split(',').to_set
75
80
  end
81
+
82
+ # Change LOG_LEVEL and LOG_NAMES_DEFAULT_LEVEL on a running process by sending signals.
83
+ # Each signal rotates through the levels, wrapping around.
84
+ # Based on SemanticLogger.add_signal_handler.
85
+ # Note that USR1/USR2 are already used by puma. WINCH/SYS should be unused these days.
86
+ def self.add_signal_handler(log_names_level_signal = "WINCH", info_signal = "SYS")
87
+ if log_names_level_signal
88
+ Signal.trap(log_names_level_signal) do
89
+ current_level = env_names_default_level
90
+ next_level = get_next_log_level(current_level)
91
+ @@names_default_level = next_level
92
+ puts "#{log_names_level_signal} signal changed LOG_NAMES_DEFAULT_LEVEL from #{current_level} to #{next_level}"
93
+ rescue => err
94
+ puts "Error handling signal #{log_names_level_signal}: #{err}"
95
+ puts err.backtrace
96
+ end
97
+ end
98
+
99
+ if info_signal
100
+ Signal.trap(info_signal) do
101
+ current_level = env_names_default_level
102
+ puts "#{info_signal} signal reports LOG_LEVEL=#{env_level} LOG_NAMES_DEFAULT_LEVEL=#{current_level}"
103
+ rescue => err
104
+ puts "Error handling signal #{info_signal}: #{err}"
105
+ puts err.backtrace
106
+ end
107
+ end
108
+ end
109
+
110
+ def self.get_next_log_level(current_log_level)
111
+ current_log_level_index = SemanticLogger::Levels.index(current_log_level)
112
+ next_log_level_index = current_log_level_index + 1
113
+ next_log_level_index = 0 if next_log_level_index >= SemanticLogger::Levels.all_levels.size
114
+ SemanticLogger::Levels.level(next_log_level_index)
115
+ end
76
116
  end
77
117
  end
@@ -35,9 +35,12 @@ module NexusSemanticLogger
35
35
  config.rails_semantic_logger.add_file_appender = false
36
36
  dd_appender = config.semantic_logger.add_appender(io: $stdout, formatter: config.rails_semantic_logger.format)
37
37
  dd_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda
38
+ NexusSemanticLogger::AppenderFilter.add_signal_handler
38
39
 
39
40
  NexusSemanticLogger::DatadogTracer.new(service)
40
41
 
42
+ SemanticLogger.on_log(NexusSemanticLogger::LoggerMetricsSubscriber.new)
43
+
41
44
  logger.info('SemanticLogger initialised.', level: config.log_level)
42
45
 
43
46
  config.after_initialize do
@@ -17,7 +17,7 @@ module NexusSemanticLogger
17
17
  # @param [String] metric Metric name.
18
18
  # @param [Array<String>] tags Additional tags.
19
19
  def increment(metric, tags: [])
20
- statsd&.increment(metric, tags: global_tags + tags)
20
+ statsd&.increment(metric, tags: combine_tags(tags))
21
21
  flush
22
22
  end
23
23
 
@@ -25,7 +25,7 @@ module NexusSemanticLogger
25
25
  # @param [String] metric Metric name.
26
26
  # @param [Array<String>] tags Additional tags.
27
27
  def decrement(metric, tags: [])
28
- statsd&.decrement(metric, tags: global_tags + tags)
28
+ statsd&.decrement(metric, tags: combine_tags(tags))
29
29
  flush
30
30
  end
31
31
 
@@ -34,7 +34,7 @@ module NexusSemanticLogger
34
34
  # @param [Integer] ms Timing in milliseconds.
35
35
  # @param [Array<String>] tags Additional tags.
36
36
  def timing(metric, ms, tags: [])
37
- statsd&.timing(metric, ms, tags: global_tags + tags)
37
+ statsd&.timing(metric, ms, tags: combine_tags(tags))
38
38
  flush
39
39
  end
40
40
 
@@ -43,7 +43,7 @@ module NexusSemanticLogger
43
43
  # @param [Numeric] value Distribution value.
44
44
  # @param [Array<String>] tags Additional tags.
45
45
  def distribution(metric, value, tags: [])
46
- statsd&.distribution(metric, value, tags: global_tags + tags)
46
+ statsd&.distribution(metric, value, tags: combine_tags(tags))
47
47
  flush
48
48
  end
49
49
 
@@ -52,8 +52,18 @@ module NexusSemanticLogger
52
52
  # @param [Numeric] value Gauge value.
53
53
  # @param [Array<String>] tags Additional tags.
54
54
  def gauge(metric, value, tags: [])
55
- statsd&.gauge(metric, value, tags: global_tags + tags)
55
+ statsd&.gauge(metric, value, tags: combine_tags(tags))
56
56
  flush
57
57
  end
58
+
59
+ private
60
+
61
+ # Safely combine the global tags with the supplied tags.
62
+ def combine_tags(tags)
63
+ final_tags = []
64
+ final_tags += global_tags unless global_tags.nil?
65
+ final_tags += tags unless tags.nil?
66
+ final_tags
67
+ end
58
68
  end
59
69
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ require 'semantic_logger'
3
+
4
+ module NexusSemanticLogger
5
+ # Sends SemanticLogger metrics to statsd.
6
+ # This is a candidate to move into the nexus_semantic_logger gem if it becomes widely useful.
7
+ # See https://logger.rocketjob.io/metrics.html
8
+ # Based on https://github.com/reidmorrison/semantic_logger/blob/master/lib/semantic_logger/metric/statsd.rb
9
+ class LoggerMetricsSubscriber < SemanticLogger::Subscriber
10
+ def call(log)
11
+ log(log) if should_log?(log)
12
+ end
13
+
14
+ def log(log)
15
+ metric = log.metric
16
+ tags = log.payload.nil? ? nil : []
17
+ log.payload&.each_pair { |key, value| tags << "#{key}:#{value}" }
18
+ if (duration = log.duration)
19
+ NexusSemanticLogger.metrics.timing(metric, duration, tags: tags)
20
+ else
21
+ amount = (log.metric_amount || 1).round
22
+ if amount.negative?
23
+ NexusSemanticLogger.metrics.decrement(metric, tags: tags)
24
+ else
25
+ NexusSemanticLogger.metrics.increment(metric, tags: tags)
26
+ end
27
+ end
28
+ end
29
+
30
+ # Only forward log entries that contain metrics.
31
+ def should_log?(log)
32
+ # Does not support metrics with dimensions.
33
+ log.metric && !log.dimensions && meets_log_level?(log) && !filtered?(log)
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module NexusSemanticLogger
3
- # Leave this as 1.7.3 in order for CI process to replace with the tagged version.
4
- VERSION = '1.7.3'
3
+ # Leave this as 1.9.0 in order for CI process to replace with the tagged version.
4
+ VERSION = '1.9.0'
5
5
  end
@@ -4,6 +4,7 @@ require 'nexus_semantic_logger/application'
4
4
  require 'nexus_semantic_logger/datadog_formatter'
5
5
  require 'nexus_semantic_logger/datadog_singleton'
6
6
  require 'nexus_semantic_logger/datadog_tracer'
7
+ require 'nexus_semantic_logger/logger_metrics_subscriber'
7
8
 
8
9
  module NexusSemanticLogger
9
10
  # Get application wide object for sending metrics.
@@ -11,3 +12,12 @@ module NexusSemanticLogger
11
12
  DatadogSingleton.instance
12
13
  end
13
14
  end
15
+
16
+ # Patch access to LEVELS array.
17
+ module SemanticLogger
18
+ module Levels
19
+ def self.all_levels
20
+ LEVELS
21
+ end
22
+ end
23
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexus_semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johnathon Harris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-22 00:00:00.000000000 Z
11
+ date: 2022-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print
@@ -112,6 +112,7 @@ files:
112
112
  - lib/nexus_semantic_logger/datadog_singleton.rb
113
113
  - lib/nexus_semantic_logger/datadog_tracer.rb
114
114
  - lib/nexus_semantic_logger/extensions/action_dispatch/debug_exceptions.rb
115
+ - lib/nexus_semantic_logger/logger_metrics_subscriber.rb
115
116
  - lib/nexus_semantic_logger/sneakers_metrics.rb
116
117
  - lib/nexus_semantic_logger/version.rb
117
118
  - nexus_semantic_logger.gemspec