From af2fc054e7cbf72004601052bb7359cbc6fdf1f8 Mon Sep 17 00:00:00 2001 From: John Harris <john.harris@nexusmods.com> Date: Wed, 20 Jul 2022 13:34:08 +0100 Subject: [PATCH] feat: add dogstatsd support --- lib/nexus_semantic_logger.rb | 2 ++ lib/nexus_semantic_logger/application.rb | 6 ++-- .../datadog_singleton.rb | 15 +++++++++ lib/nexus_semantic_logger/datadog_tracer.rb | 33 +++++++++++++++++++ nexus_semantic_logger.gemspec | 1 + 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 lib/nexus_semantic_logger/datadog_singleton.rb create mode 100644 lib/nexus_semantic_logger/datadog_tracer.rb diff --git a/lib/nexus_semantic_logger.rb b/lib/nexus_semantic_logger.rb index b7f2a0a..6867bf4 100644 --- a/lib/nexus_semantic_logger.rb +++ b/lib/nexus_semantic_logger.rb @@ -2,6 +2,8 @@ require 'nexus_semantic_logger/appender_filter' require 'nexus_semantic_logger/application' require 'nexus_semantic_logger/datadog_formatter' +require 'nexus_semantic_logger/datadog_singleton' +require 'nexus_semantic_logger/datadog_tracer' module NexusSemanticLogger end diff --git a/lib/nexus_semantic_logger/application.rb b/lib/nexus_semantic_logger/application.rb index 67314f6..de5f4ae 100644 --- a/lib/nexus_semantic_logger/application.rb +++ b/lib/nexus_semantic_logger/application.rb @@ -36,6 +36,8 @@ module NexusSemanticLogger dd_appender = config.semantic_logger.add_appender(io: $stdout, formatter: config.rails_semantic_logger.format) dd_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda + NexusSemanticLogger::DatadogTracer.new(service) + logger.info('SemanticLogger initialised.', level: config.log_level) end @@ -48,13 +50,13 @@ module NexusSemanticLogger color_appender = config.semantic_logger.add_appender(io: $stdout, formatter: :color) color_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda - if ENV['DD_AGENT_HOST'].present? && ENV['DD_AGENT_PORT'].present? + if ENV['DD_AGENT_HOST'].present? && ENV['DD_AGENT_LOGGING_PORT'].present? # Development logs can be sent to datadog via a TCP logging endpoint on a local agent. # Each port is assigned a particular service. # See https://logger.rocketjob.io/appenders.html dd_appender = config.semantic_logger.add_appender( appender: :tcp, - server: "#{ENV['DD_AGENT_HOST']}:#{ENV['DD_AGENT_PORT']}", + server: "#{ENV['DD_AGENT_HOST']}:#{ENV['DD_AGENT_LOGGING_PORT']}", formatter: config.rails_semantic_logger.format ) dd_appender.filter = NexusSemanticLogger::AppenderFilter.filter_lambda diff --git a/lib/nexus_semantic_logger/datadog_singleton.rb b/lib/nexus_semantic_logger/datadog_singleton.rb new file mode 100644 index 0000000..4edf497 --- /dev/null +++ b/lib/nexus_semantic_logger/datadog_singleton.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +require 'singleton' + +module NexusSemanticLogger + # Application wide location to get datadog objects. + # Can be moved to its own gem in future, and there is scope to make the usage code even leaner. + class DatadogSingleton + include Singleton + attr_accessor :statsd, :tags + + def flush + statsd&.flush(sync: Rails.env.development?) # Force flush sync in development, speed up checks. + end + end +end diff --git a/lib/nexus_semantic_logger/datadog_tracer.rb b/lib/nexus_semantic_logger/datadog_tracer.rb new file mode 100644 index 0000000..1b3665a --- /dev/null +++ b/lib/nexus_semantic_logger/datadog_tracer.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true +require 'datadog/statsd' +require 'ddtrace' + +module NexusSemanticLogger + class DatadogTracer + def initialize(service) + Datadog.configure do |c| + if ENV['DD_AGENT_HOST'].present? + # To enable runtime metrics collection, set `true`. Defaults to `false` + # You can also set DD_RUNTIME_METRICS_ENABLED=true to configure this. + c.runtime_metrics.enabled = true + + # Configure DogStatsD instance for sending runtime metrics. + # By default, runtime metrics from the application are sent to the Datadog Agent with DogStatsD over port 8125. + datadog_singleton = DatadogSingleton.instance + datadog_singleton.statsd = Datadog::Statsd.new(ENV['DD_AGENT_HOST'], 8125) + datadog_singleton.tags = ["env:#{Rails.env}", "service:#{service}"] + c.runtime_metrics.statsd = datadog_singleton.statsd + + # Tracer requires configuration to a datadog agent via DD_AGENT_HOST. + dd_force_tracer_val = ENV.fetch('DD_FORCE_TRACER', false) + dd_force_tracer = dd_force_tracer_val.present? && dd_force_tracer_val.to_s == 'true' + c.tracer(enabled: Rails.env.production? || dd_force_tracer, env: Rails.env) + end + + c.use(:rails, service_name: service) + + c.logger.level = Logger::WARN # ddtrace info logging is too verbose. + end + end + end +end diff --git a/nexus_semantic_logger.gemspec b/nexus_semantic_logger.gemspec index 5a4a960..6fd50e8 100644 --- a/nexus_semantic_logger.gemspec +++ b/nexus_semantic_logger.gemspec @@ -16,5 +16,6 @@ Gem::Specification.new do |spec| spec.add_dependency('amazing_print', '~> 1.4.0') spec.add_dependency('rails_semantic_logger', '~> 4.10.0') spec.add_dependency('net_tcp_client', '~> 2.2.0') # For TCP logging. + spec.add_dependency('dogstatsd-ruby', '~> 5.4.0') # For custom application metrics. spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0') end -- GitLab