module Epsagon

Constants

DEFAULT_BACKEND
DEFAULT_IGNORE_DOMAINS
MUTABLE_CONF_KEYS

Public Instance Methods

add_ignored_key(key) click to toggle source
# File lib/epsagon.rb, line 62
def add_ignored_key(key)
  get_config[:ignored_keys].push(key).uniq
end
epsagon_confs(configurator) click to toggle source

config opentelemetry with epsaon extensions:

# File lib/epsagon.rb, line 104
def epsagon_confs(configurator)
  otel_resource = {
    'application' => get_config[:app_name],
    'epsagon.version' => EpsagonConstants::VERSION,
    'epsagon.metadata_only' => get_config[:metadata_only]
  }.merge(set_ecs_metadata)

  configurator.resource = OpenTelemetry::SDK::Resources::Resource.telemetry_sdk.merge(
    OpenTelemetry::SDK::Resources::Resource.create(otel_resource)
  )

  configurator.use 'EpsagonSinatraInstrumentation', { epsagon: get_config }
  configurator.use 'EpsagonNetHTTPInstrumentation', { epsagon: get_config }
  configurator.use 'EpsagonFaradayInstrumentation', { epsagon: get_config }
  configurator.use 'EpsagonAwsSdkInstrumentation', { epsagon: get_config }
  configurator.use 'EpsagonRailsInstrumentation', { epsagon: get_config }
  configurator.use 'OpenTelemetry::Instrumentation::Sidekiq', { epsagon: get_config }
  configurator.use 'EpsagonPostgresInstrumentation', { epsagon: get_config }
  configurator.use 'EpsagonResqueInstrumentation', { epsagon: get_config }


  if get_config[:debug]
    configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
      OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
    )
  end

  configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
    exporter: OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
                                                            'x-epsagon-token' => get_config[:token]
                                                          },
                                                          endpoint: get_config[:backend],
                                                          insecure: get_config[:insecure] || false)
  )
end
get_config() click to toggle source
# File lib/epsagon.rb, line 70
def get_config
  @@epsagon_config ||= {
    metadata_only: ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false',
    debug: ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true',
    token: ENV['EPSAGON_TOKEN'] || '',
    app_name: ENV['EPSAGON_APP_NAME'] || '',
    max_attribute_size: ENV['EPSAGON_MAX_ATTRIBUTE_SIZE'] || 5000,
    backend: ENV['EPSAGON_BACKEND'] || DEFAULT_BACKEND,
    ignore_domains: ENV['EPSAGON_IGNORE_DOMAINS']&.split(',') || DEFAULT_IGNORE_DOMAINS,
    ignored_keys: ENV['EPSAGON_IGNORED_KEYS']&.split(',') || []
  }
end
init(**args) click to toggle source
# File lib/epsagon.rb, line 35
def init(**args)
  get_config.merge!(args)
  validate(get_config)
  OpenTelemetry::SDK.configure
  @@initialized = true
end
remove_ignored_key(key) click to toggle source
# File lib/epsagon.rb, line 66
def remove_ignored_key(key)
  get_config[:ignored_keys].delete(key)
end
set_config(**args) click to toggle source
# File lib/epsagon.rb, line 52
def set_config(**args)
  unless args.keys.all? {|a| MUTABLE_CONF_KEYS.include?(a)}
    raise ArgumentError.new("only #{MUTABLE_CONF_KEYS.to_a} are mutable after `Epsagon.init`")
  end
  Epsagon.init unless @@initialized
  new_conf = get_config.merge(args)
  validate(new_conf)
  @@epsagon_config = new_conf
end
set_ecs_metadata() click to toggle source
# File lib/epsagon.rb, line 83
def set_ecs_metadata
  metadata_uri = ENV['ECS_CONTAINER_METADATA_URI']
  return {} if metadata_uri.nil?

  response = Net::HTTP.get(URI(metadata_uri))
  ecs_metadata = JSON.parse(response)
  arn = Arn.parse(ecs_metadata['Labels']['com.amazonaws.ecs.task-arn'])

  {
    'aws.account_id' => arn.account,
    'aws.region' => arn.region,
    'aws.ecs.cluster' => ecs_metadata['Labels']['com.amazonaws.ecs.cluster'],
    'aws.ecs.task_arn' => ecs_metadata['Labels']['com.amazonaws.ecs.task-arn'],
    'aws.ecs.container_name' => ecs_metadata['Labels']['com.amazonaws.ecs.container-name'],
    'aws.ecs.task.family' => ecs_metadata['Labels']['com.amazonaws.ecs.task-definition-family'],
    'aws.ecs.task.revision' => ecs_metadata['Labels']['com.amazonaws.ecs.task-definition-version']
  }
end
validate(config) click to toggle source
# File lib/epsagon.rb, line 42
def validate(config)
  Util.validate_value(config, :metadata_only, 'Must be a boolean') {|v| !!v == v}
  Util.validate_value(config, :debug, 'Must be a boolean') {|v| !!v == v}
  Util.validate_value(config, :token, 'Must be a valid Epsagon token') {|v| (v.is_a? String) && (v.size > 10) }
  Util.validate_value(config, :app_name, 'Must be a String') {|v| (v.is_a? String) && (v.size > 0) }
  Util.validate_value(config, :max_attribute_size, 'Must be an Integer') {|v| v.is_a? Integer}
  Util.validate_value(config, :ignore_domains, 'Must be iterable') {|v| v.respond_to?(:each)}
  Util.validate_value(config, :ignored_keys, 'Must be iterable') {|v| v.respond_to?(:each)}
end