class NewRelic::Agent::Instrumentation::MongodbCommandSubscriber

Constants

COLLECTION
ERROR_KEYS
LOCALHOST
MONGODB
UNKNOWN

Public Instance Methods

completed(event) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 34
def completed(event)
  begin
    return unless NewRelic::Agent::Tracer.tracing_enabled?

    segment = segments.delete(event.operation_id)
    return unless segment

    # operations that succeed but have errors return CommandSucceeded
    # with an error_key that is populated with error specifics
    if error_key = error_key_present?(event)
      # taking the last error as there can potentially be many
      attributes = event.reply[error_key][-1]
      segment.notice_error(Mongo::Error.new('%s (%s)' % [attributes['errmsg'], attributes['code']]))

    # failing commands return a CommandFailed event with an error message
    # in the form of "% (%s)" for the message and code
    elsif event.is_a?(Mongo::Monitoring::Event::CommandFailed)
      segment.notice_error(Mongo::Error.new(event.message))
    end
    segment.finish
  rescue Exception => e
    log_notification_error('completed', e)
  end
end
Also aliased as: succeeded, failed
error_key_present?(event) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 26
def error_key_present?(event)
  if reply = event.reply
    ERROR_KEYS.detect { |key| reply[key] }
  end
rescue
  false
end
failed(event)
Alias for: completed
started(event) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 14
def started(event)
  begin
    return unless NewRelic::Agent::Tracer.tracing_enabled?

    segments[event.operation_id] = start_segment(event)
  rescue Exception => e
    log_notification_error('started', e)
  end
end
succeeded(event)
Alias for: completed

Private Instance Methods

collection(event) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 88
def collection(event)
  event.command[COLLECTION] || event.command[:collection] || event.command.values.first
end
generate_statement(event) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 101
def generate_statement(event)
  NewRelic::Agent::Datastores::Mongo::EventFormatter.format(
    event.command_name,
    event.database_name,
    event.command
  )
end
host_from_address(address) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 112
def host_from_address(address)
  if unix_domain_socket?(address.host)
    LOCALHOST
  else
    address.host
  end
rescue => e
  NewRelic::Agent.logger.debug("Failed to retrieve Mongo host: #{e}")
  UNKNOWN
end
log_notification_error(event_type, error) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 92
def log_notification_error(event_type, error)
  NewRelic::Agent.logger.error("Error during MongoDB #{event_type} event:")
  NewRelic::Agent.logger.log_exception(:error, error)
end
operation(command_name) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 79
def operation(command_name)
  # from 2.0 to 2.5, :findandmodify was the command_name
  if command_name == :findandmodify
    :findAndModify
  else
    command_name
  end
end
port_path_or_id_from_address(address) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 123
def port_path_or_id_from_address(address)
  if unix_domain_socket?(address.host)
    address.host
  else
    address.port
  end
rescue => e
  NewRelic::Agent.logger.debug("Failed to retrieve Mongo port_path_or_id: #{e}")
  UNKNOWN
end
segments() click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 97
def segments
  @segments ||= {}
end
start_segment(event) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 64
def start_segment(event)
  host = host_from_address(event.address)
  port_path_or_id = port_path_or_id_from_address(event.address)
  segment = NewRelic::Agent::Tracer.start_datastore_segment(
    product: MONGODB,
    operation: operation(event.command_name),
    collection: collection(event),
    host: host,
    port_path_or_id: port_path_or_id,
    database_name: event.database_name
  )
  segment.notice_nosql_statement(generate_statement(event))
  segment
end
unix_domain_socket?(host) click to toggle source
# File lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb, line 134
def unix_domain_socket?(host)
  host.start_with?(NewRelic::SLASH)
end