module Datadog::Contrib::ActionPack::ActionController::Instrumentation

Instrumentation for ActionController components

Public Instance Methods

exception_controller?(payload) click to toggle source
# File lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb, line 76
def exception_controller?(payload)
  exception_controller_class = Datadog.configuration[:action_pack][:exception_controller]
  controller = payload.fetch(:controller)
  headers = payload.fetch(:headers)

  # If no exception controller class has been set,
  # guess whether this is an exception controller from the headers.
  if exception_controller_class.nil?
    !headers[:request_exception].nil?
  # If an exception controller class has been specified,
  # check if the controller is a kind of the exception controller class.
  elsif exception_controller_class.is_a?(Class) || exception_controller_class.is_a?(Module)
    controller <= exception_controller_class
  # Otherwise if the exception controller class is some other value (like false)
  # assume that this controller doesn't handle exceptions.
  else
    false
  end
end
finish_processing(payload) click to toggle source
# File lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb, line 38
def finish_processing(payload)
  # retrieve the tracing context and the latest active span
  tracing_context = payload.fetch(:tracing_context)
  span = tracing_context[:dd_request_span]
  return unless span && !span.finished?

  begin
    # We repeat this in both start and at finish because the resource may have changed during the request
    try_setting_rack_request_resource(payload, span.resource)

    # Set analytics sample rate
    Utils.set_analytics_sample_rate(span)

    # Measure service stats
    Contrib::Analytics.set_measured(span)

    # Associate with runtime metrics
    Datadog.runtime_metrics.associate_with_span(span)

    span.set_tag(Ext::TAG_ROUTE_ACTION, payload.fetch(:action))
    span.set_tag(Ext::TAG_ROUTE_CONTROLLER, payload.fetch(:controller))

    exception = payload[:exception_object]
    if exception.nil?
      # [christian] in some cases :status is not defined,
      # rather than firing an error, simply acknowledge we don't know it.
      status = payload.fetch(:status, '?').to_s
      span.status = 1 if status.start_with?('5')
    elsif Utils.exception_is_error?(exception)
      span.set_error(exception)
    end
  ensure
    span.finish
  end
rescue StandardError => e
  Datadog.logger.error(e.message)
end
start_processing(payload) click to toggle source
# File lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb, line 17
def start_processing(payload)
  # trace the execution
  tracer = Datadog.configuration[:action_pack][:tracer]
  service = Datadog.configuration[:action_pack][:controller_service]
  type = Datadog::Ext::HTTP::TYPE_INBOUND
  span = tracer.trace(
    Ext::SPAN_ACTION_CONTROLLER,
    service: service,
    span_type: type,
    resource: "#{payload.fetch(:controller)}##{payload.fetch(:action)}",
  )

  # attach the current span to the tracing context
  tracing_context = payload.fetch(:tracing_context)
  tracing_context[:dd_request_span] = span

  try_setting_rack_request_resource(payload, span.resource)
rescue StandardError => e
  Datadog.logger.error(e.message)
end
try_setting_rack_request_resource(payload, resource) click to toggle source
# File lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb, line 96
def try_setting_rack_request_resource(payload, resource)
  # Set the resource name of the Rack request span unless this is an exception controller.
  unless payload.fetch(:exception_controller?)
    rack_request_span = payload.fetch(:env)[Datadog::Contrib::Rack::TraceMiddleware::RACK_REQUEST_SPAN]
    rack_request_span.resource = resource if rack_request_span
  end
end