nexus_semantic_logger 1.0.2 → 1.3.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: 4f41cfcb762aa97a9c9e03abe6ec14570b5a9a90121c0df24b620105541be5c6
4
- data.tar.gz: b9eb8d732937fa6ee5dcf6a64a616dbdb2e4800b734156db001807cde9735c7a
3
+ metadata.gz: 6d90e3661ba7e5c82b2e1777d465df8f88617a3ad8287f8d0b9bdd461f0729a6
4
+ data.tar.gz: 1217216fdf855b72558510e52a50f0308c10b3e07ccbc80369fb228f0fe51040
5
5
  SHA512:
6
- metadata.gz: 6505a0e3c84b133a8bb2fc3151959645dbf536977c5b6eb224d99f42c77066923c59e1f4d860f09f362b3b025e9d2cf97e5e1eb22cc8014230a3d8abd2d2144c
7
- data.tar.gz: e1ff91e0a80205c43b3b5f32c296d122ab77ec40a9a7541d85bcb9421762006cdb2050cd8b937b9341e32ec07ecd9accfae74a3de68d8507e52bf8535024c754
6
+ metadata.gz: a4261cc18604aade1ebd48efcd2cbb680ee26da22c366bcb544c786d42bffdad1a57ec2249f53347f1bcb5dadd2b0c13ff20f8699a7e30131e1e85fb7f1d2244
7
+ data.tar.gz: f2ea77247cc5e769e1dc7706595b85dc62179ceef8d05f11d78904632cd6cb39c837d64e401e278edf52333a75552dc6de41634f8b6862ac26155d528de9397b
data/.rubocop.yml CHANGED
@@ -1,6 +1,10 @@
1
1
  inherit_gem:
2
2
  rubocop-shopify: rubocop.yml
3
3
 
4
+ Style/ClassVars:
5
+ Enabled: false
6
+ Style/ConditionalAssignment:
7
+ Enabled: false
4
8
  Style/GlobalVars:
5
9
  Enabled: false
6
10
  Style/FrozenStringLiteralComment:
data/README.md CHANGED
@@ -1,3 +1,57 @@
1
1
  # nexus_semantic_logger
2
2
 
3
3
  Configures a [semantic_logger](https://rubygems.org/gems/rails_semantic_logger) as required for NexusMods components.
4
+
5
+ ## Telemetry
6
+
7
+ As well as providing a semantic logger, this gem handles datadog telemetry associated with the logging approach:
8
+
9
+ * logs
10
+ * traces
11
+ * metrics
12
+ * statsd is automatically attached to datadog runtime metrics and may also be used for custom metrics.
13
+
14
+ ### Sending metrics
15
+
16
+ Ensure the metric name is in the format: `nexus.{component}.{major}.{minor}`
17
+
18
+ Where _major and minor_ are specific to the component logic e.g. `nexus.uploads.clamscan.pass`
19
+
20
+ For example, to increment a count:
21
+
22
+ ```
23
+ NexusSemanticLogger.metrics.increment('nexus.users.registration.complete')
24
+ ```
25
+
26
+ # Local gem development
27
+
28
+ Steps to run this gem from local sources in one the nexus 'staged build' rails components:
29
+
30
+ ## Copy gem sources to component
31
+
32
+ ```
33
+ cd ~/legacy/users
34
+ cp -r ../nexus_semantic_logger .
35
+ ```
36
+
37
+ ## Adjust component Dockerfile to include gem sources
38
+
39
+ Within stage 1, append a COPY after the Gemfile copy:
40
+
41
+ ```
42
+ COPY --chown=nexus:nexus Gemfile* ./
43
+ COPY --chown=nexus:nexus nexus_semantic_logger/ ./nexus_semantic_logger/
44
+ ```
45
+
46
+ Within stage 2, append a COPY after the bundle copy:
47
+
48
+ ```
49
+ COPY --from=stage1 /usr/local/bundle /usr/local/bundle
50
+ COPY --from=stage1 /app/nexus_semantic_logger/ /app/nexus_semantic_logger/
51
+ ```
52
+
53
+ ## Adjust Gemfile to use local path
54
+
55
+ ```
56
+ gem 'nexus_semantic_logger', :path => "/app/nexus_semantic_logger"
57
+
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+ require 'rails_semantic_logger'
3
+
4
+ module NexusSemanticLogger
5
+ class AppenderFilter
6
+ def self.filter_lambda
7
+ -> (log) {
8
+ # log API see https://logger.rocketjob.io/log_struct.html
9
+ # and lib/semantic_logger/levels.rb
10
+ # level: :trace=>0, :debug=>1, :info=>2, :warn=>3, :error=>4, :fatal=>5
11
+ current_log_level = SemanticLogger::Levels.index(env_names_default_level)
12
+
13
+ # Names allow overriding the level that will be appended,
14
+ # else the global level is used to determine appending.
15
+ append = false
16
+ if log.name.in?(env_names_trace)
17
+ append = true
18
+ elsif log.name.in?(env_names_debug)
19
+ append = log.level_index >= 1
20
+ elsif log.name.in?(env_names_info)
21
+ append = log.level_index >= 2
22
+ elsif log.name.in?(env_names_warn)
23
+ append = log.level_index >= 3
24
+ elsif log.name.in?(env_names_error)
25
+ append = log.level_index >= 4
26
+ elsif log.name.in?(env_names_fatal)
27
+ append = log.level_index >= 5
28
+ else
29
+ append = log.level_index >= current_log_level
30
+ end
31
+ append
32
+ }
33
+ end
34
+
35
+ def self.env_names_default_level
36
+ @@names_default_level ||= ENV.fetch('LOG_NAMES_DEFAULT_LEVEL', Rails.application.config.log_level)
37
+ end
38
+
39
+ def self.env_names_trace
40
+ @@names_trace ||= fetch_env_names('LOG_NAMES_TRACE')
41
+ end
42
+
43
+ def self.env_names_debug
44
+ @@names_debug ||= fetch_env_names('LOG_NAMES_DEBUG')
45
+ end
46
+
47
+ def self.env_names_info
48
+ @@names_info ||= fetch_env_names('LOG_NAMES_INFO')
49
+ end
50
+
51
+ def self.env_names_warn
52
+ @@names_warn ||= fetch_env_names('LOG_NAMES_WARN')
53
+ end
54
+
55
+ def self.env_names_error
56
+ @@names_error ||= fetch_env_names('LOG_NAMES_ERROR')
57
+ end
58
+
59
+ def self.env_names_fatal
60
+ @@names_fatal ||= fetch_env_names('LOG_NAMES_FATAL')
61
+ end
62
+
63
+ def self.flush
64
+ @@names_default_level = nil
65
+ @@names_trace = nil
66
+ @@names_debug = nil
67
+ @@names_info = nil
68
+ @@names_warn = nil
69
+ @@names_error = nil
70
+ @@names_fatal = nil
71
+ end
72
+
73
+ def self.fetch_env_names(var)
74
+ ENV.fetch(var, '').split(',').to_set
75
+ end
76
+ end
77
+ end
@@ -33,7 +33,10 @@ module NexusSemanticLogger
33
33
  # Default logging is stdout in datadog compatible JSON.
34
34
  config.rails_semantic_logger.format = NexusSemanticLogger::DatadogFormatter.new(service)
35
35
  config.rails_semantic_logger.add_file_appender = false
36
- config.semantic_logger.add_appender(io: $stdout, formatter: config.rails_semantic_logger.format)
36
+ dd_appender = config.semantic_logger.add_appender(io: $stdout, formatter: config.rails_semantic_logger.format)
37
+ dd_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda
38
+
39
+ NexusSemanticLogger::DatadogTracer.new(service)
37
40
 
38
41
  logger.info('SemanticLogger initialised.', level: config.log_level)
39
42
  end
@@ -44,13 +47,19 @@ module NexusSemanticLogger
44
47
 
45
48
  # Change default logging to coloured logging on stdout.
46
49
  config.semantic_logger.clear_appenders!
47
- config.semantic_logger.add_appender(io: $stdout, formatter: :color)
48
- if ENV['DD_AGENT_HOST'].present? && ENV['DD_AGENT_PORT'].present?
50
+ color_appender = config.semantic_logger.add_appender(io: $stdout, formatter: :color)
51
+ color_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda
52
+
53
+ if ENV['DD_AGENT_HOST'].present? && ENV['DD_AGENT_LOGGING_PORT'].present?
49
54
  # Development logs can be sent to datadog via a TCP logging endpoint on a local agent.
50
55
  # Each port is assigned a particular service.
51
56
  # See https://logger.rocketjob.io/appenders.html
52
- config.semantic_logger.add_appender(appender: :tcp, server: "#{ENV['DD_AGENT_HOST']}:#{ENV['DD_AGENT_PORT']}",
53
- formatter: config.rails_semantic_logger.format)
57
+ dd_appender = config.semantic_logger.add_appender(
58
+ appender: :tcp,
59
+ server: "#{ENV['DD_AGENT_HOST']}:#{ENV['DD_AGENT_LOGGING_PORT']}",
60
+ formatter: config.rails_semantic_logger.format
61
+ )
62
+ dd_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda
54
63
  end
55
64
 
56
65
  logger.info('SemanticLogger initialised in development.', level: config.log_level)
@@ -59,7 +68,8 @@ module NexusSemanticLogger
59
68
  def self.test(config)
60
69
  # Use human readable coloured output for logs when running tests.
61
70
  config.semantic_logger.clear_appenders!
62
- config.semantic_logger.add_appender(io: $stdout, formatter: :color)
71
+ color_appender = config.semantic_logger.add_appender(io: $stdout, formatter: :color)
72
+ color_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda
63
73
  end
64
74
  end
65
75
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ require 'singleton'
3
+
4
+ module NexusSemanticLogger
5
+ # Application wide location to get datadog objects.
6
+ # dogstatsd-ruby maintains its own queue and thread for flushing, so the client code should never create its
7
+ # own statsd instance.
8
+ class DatadogSingleton
9
+ include Singleton
10
+ attr_accessor :statsd, :tags
11
+
12
+ def flush
13
+ statsd&.flush(sync: Rails.env.development?) # Force flush sync in development, speed up checks.
14
+ end
15
+
16
+ def increment(metric_name)
17
+ statsd&.increment(metric_name, tags: tags)
18
+ flush
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ require 'datadog/statsd'
3
+ require 'ddtrace'
4
+
5
+ module NexusSemanticLogger
6
+ class DatadogTracer
7
+ def initialize(service)
8
+ Datadog.configure do |c|
9
+ if ENV['DD_AGENT_HOST'].present?
10
+ # To enable runtime metrics collection, set `true`. Defaults to `false`
11
+ # You can also set DD_RUNTIME_METRICS_ENABLED=true to configure this.
12
+ c.runtime_metrics.enabled = true
13
+
14
+ # Configure DogStatsD instance for sending runtime metrics.
15
+ # By default, runtime metrics from the application are sent to the Datadog Agent with DogStatsD on port 8125.
16
+ datadog_singleton = DatadogSingleton.instance
17
+ datadog_singleton.statsd = Datadog::Statsd.new(ENV['DD_AGENT_HOST'], 8125)
18
+ datadog_singleton.tags = ["env:#{Rails.env}", "service:#{service}"]
19
+ c.runtime_metrics.statsd = datadog_singleton.statsd
20
+
21
+ # Tracer requires configuration to a datadog agent via DD_AGENT_HOST.
22
+ dd_force_tracer_val = ENV.fetch('DD_FORCE_TRACER', false)
23
+ dd_force_tracer = dd_force_tracer_val.present? && dd_force_tracer_val.to_s == 'true'
24
+ c.tracer(enabled: Rails.env.production? || dd_force_tracer, env: Rails.env)
25
+ end
26
+
27
+ c.use(:rails, service_name: service)
28
+
29
+ c.logger.level = Logger::WARN # ddtrace info logging is too verbose.
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module NexusSemanticLogger
3
- # Leave this as 1.0.2 in order for CI process to replace with the tagged version.
4
- VERSION = '1.0.2'
3
+ # Leave this as 1.3.0 in order for CI process to replace with the tagged version.
4
+ VERSION = '1.3.0'
5
5
  end
@@ -1,6 +1,13 @@
1
1
  # frozen_string_literal: true
2
+ require 'nexus_semantic_logger/appender_filter'
2
3
  require 'nexus_semantic_logger/application'
3
4
  require 'nexus_semantic_logger/datadog_formatter'
5
+ require 'nexus_semantic_logger/datadog_singleton'
6
+ require 'nexus_semantic_logger/datadog_tracer'
4
7
 
5
8
  module NexusSemanticLogger
9
+ # Get application wide object for sending metrics.
10
+ def metrics
11
+ DatadogSingleton.instance
12
+ end
6
13
  end
@@ -16,5 +16,6 @@ Gem::Specification.new do |spec|
16
16
  spec.add_dependency('amazing_print', '~> 1.4.0')
17
17
  spec.add_dependency('rails_semantic_logger', '~> 4.10.0')
18
18
  spec.add_dependency('net_tcp_client', '~> 2.2.0') # For TCP logging.
19
+ spec.add_dependency('dogstatsd-ruby', '~> 5.4.0') # For custom application metrics.
19
20
  spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
20
21
  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.0.2
4
+ version: 1.3.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-07-05 00:00:00.000000000 Z
11
+ date: 2022-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.2.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: dogstatsd-ruby
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 5.4.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 5.4.0
55
69
  description:
56
70
  email: john.harris@nexusmods.com
57
71
  executables: []
@@ -63,8 +77,11 @@ files:
63
77
  - Gemfile
64
78
  - README.md
65
79
  - lib/nexus_semantic_logger.rb
80
+ - lib/nexus_semantic_logger/appender_filter.rb
66
81
  - lib/nexus_semantic_logger/application.rb
67
82
  - lib/nexus_semantic_logger/datadog_formatter.rb
83
+ - lib/nexus_semantic_logger/datadog_singleton.rb
84
+ - lib/nexus_semantic_logger/datadog_tracer.rb
68
85
  - lib/nexus_semantic_logger/version.rb
69
86
  - nexus_semantic_logger.gemspec
70
87
  homepage:
@@ -85,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
102
  - !ruby/object:Gem::Version
86
103
  version: '0'
87
104
  requirements: []
88
- rubygems_version: 3.3.17
105
+ rubygems_version: 3.3.21
89
106
  signing_key:
90
107
  specification_version: 4
91
108
  summary: semantic_logger usage for nexus