class NewRelic::Agent::Transaction::DatastoreSegment

Constants

NEWLINE
UNKNOWN

Attributes

collection[R]
database_name[RW]
host[R]
nosql_statement[R]
operation[R]
port_path_or_id[R]
product[R]
record_sql[RW]
sql_statement[R]

Public Class Methods

new(product, operation, collection = nil, host = nil, port_path_or_id = nil, database_name = nil, start_time = nil) click to toggle source
Calls superclass method
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 19
def initialize(product, operation, collection = nil, host = nil, port_path_or_id = nil, database_name = nil, start_time = nil)
  @product = product
  @operation = operation
  @collection = collection
  @sql_statement = nil
  @nosql_statement = nil
  @record_sql = true
  set_instance_info(host, port_path_or_id)
  @database_name = database_name&.to_s
  super(Datastores::MetricHelper.scoped_metric_for(product, operation, collection),
        nil,
        start_time)
end

Public Instance Methods

_notice_sql(sql, config = nil, explainer = nil, binds = nil, name = nil) click to toggle source

@api private

# File lib/new_relic/agent/transaction/datastore_segment.rb, line 64
def _notice_sql(sql, config = nil, explainer = nil, binds = nil, name = nil)
  return unless record_sql?

  @sql_statement = Database::Statement.new(sql, config, explainer, binds, name, host, port_path_or_id, database_name)
end
notice_nosql_statement(nosql_statement) click to toggle source

Method for simplifying attaching non-SQL data statements to a transaction. For instance, Mongo or CQL queries, Memcached or Redis keys would all be appropriate data to attach as statements.

Data passed to this method is NOT obfuscated by New Relic, so please ensure that user information is obfuscated if the agent setting ‘transaction_tracer.record_sql` is set to `obfuscated`

@param [String] nosql_statement text of the statement to capture.

@note THERE ARE SECURITY CONCERNS WHEN CAPTURING STATEMENTS!

This method will properly ignore statements when the user has turned
off capturing queries, but it is not able to obfuscate arbitrary data!
To prevent exposing user information embedded in captured queries,
please ensure all data passed to this method is safe to transmit to
New Relic.
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 87
def notice_nosql_statement(nosql_statement)
  return unless record_sql?

  @nosql_statement = Database.truncate_query(nosql_statement)
  nil
end
notice_sql(sql) click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 58
def notice_sql(sql)
  _notice_sql(sql)
  nil
end
record_metrics() click to toggle source
Calls superclass method
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 94
def record_metrics
  @unscoped_metrics = Datastores::MetricHelper.unscoped_metrics_for(product, operation, collection, host, port_path_or_id)
  super
end
set_instance_info(host = nil, port_path_or_id = nil) click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 33
def set_instance_info(host = nil, port_path_or_id = nil)
  port_path_or_id = port_path_or_id.to_s if port_path_or_id
  host_present = host && !host.empty?
  ppi_present = port_path_or_id && !port_path_or_id.empty?

  host = NewRelic::Agent::Hostname.get_external(host) if host_present

  case
  when host_present && ppi_present
    @host = host
    @port_path_or_id = port_path_or_id

  when host_present && !ppi_present
    @host = host
    @port_path_or_id = UNKNOWN

  when !host_present && ppi_present
    @host = UNKNOWN
    @port_path_or_id = port_path_or_id

  else
    @host = @port_path_or_id = nil
  end
end

Private Instance Methods

add_backtrace_parameter() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 122
def add_backtrace_parameter
  return unless duration >= Agent.config[:'transaction_tracer.stack_trace_threshold']

  params[:backtrace] = caller.join(NEWLINE)
end
add_database_name_parameter() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 116
def add_database_name_parameter
  params[:database_name] = database_name if database_name
end
add_instance_parameters() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 111
def add_instance_parameters
  params[:host] = host if host
  params[:port_path_or_id] = port_path_or_id if port_path_or_id
end
notice_sql_statement() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 128
def notice_sql_statement
  params[:sql] = sql_statement
  NewRelic::Agent.instance.sql_sampler.notice_sql_statement(sql_statement.dup, name, duration)
end
notice_statement() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 133
def notice_statement
  params[:statement] = nosql_statement
end
record_span_event() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 141
def record_span_event
  # don't record a span event if the transaction is ignored
  return if transaction.ignore?

  aggregator = ::NewRelic::Agent.agent.span_event_aggregator
  priority = transaction.priority

  aggregator.record(priority: priority) do
    SpanEventPrimitive.for_datastore_segment(self)
  end
end
record_sql?() click to toggle source
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 137
def record_sql?
  transaction_state.is_sql_recorded? && @record_sql
end
segment_complete() click to toggle source
Calls superclass method
# File lib/new_relic/agent/transaction/datastore_segment.rb, line 101
def segment_complete
  notice_sql_statement if sql_statement
  notice_statement if nosql_statement
  add_instance_parameters
  add_database_name_parameter
  add_backtrace_parameter

  super
end