Class: NewRelic::Agent::Tracer

Inherits:
Object
  • Object
show all
Defined in:
lib/new_relic/agent/tracer.rb

Overview

This class helps you interact with the current transaction (if it exists), start new transactions/segments, etc.

Class Method Summary collapse

Class Method Details

.current_segmentObject

Returns the currently active segment in the transaction in progress for this thread, or nil if no segment or transaction exists.



207
208
209
210
211
# File 'lib/new_relic/agent/tracer.rb', line 207

def current_segment
  return unless txn = current_transaction

  txn.current_segment
end

.current_span_idObject Also known as: span_id

Returns the id of the current span, or nil if none exists.



57
58
59
60
61
# File 'lib/new_relic/agent/tracer.rb', line 57

def current_span_id
  if span = current_segment
    span.guid
  end
end

.current_trace_idObject Also known as: trace_id

Returns the trace_id of the current_transaction, or nil if none exists.



47
48
49
50
51
# File 'lib/new_relic/agent/tracer.rb', line 47

def current_trace_id
  if txn = current_transaction
    txn.trace_id
  end
end

.current_transactionObject

Returns the transaction in progress for this thread, or nil if none exists.



39
40
41
# File 'lib/new_relic/agent/tracer.rb', line 39

def current_transaction
  state.current_transaction
end

.in_transaction(name: nil, partial_name: nil, category:, options: {}) ⇒ Object

Runs the given block of code in a transaction.

Parameters:

  • name (String) (defaults to: nil)

    reserved for New Relic internal use

  • partial_name (String) (defaults to: nil)

    a meaningful name for this transaction (e.g., blogs/index); the Ruby agent will add a New-Relic-specific prefix

  • category (Symbol)

    :web for web transactions or :background for background transactions

  • options (Hash) (defaults to: {})

    reserved for New Relic internal use



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/new_relic/agent/tracer.rb', line 90

def in_transaction(name: nil,
  partial_name: nil,
  category:,
  options: {})

  finishable = start_transaction_or_segment(
    name: name,
    partial_name: partial_name,
    category: category,
    options: options
  )

  begin
    # We shouldn't raise from Tracer.start_transaction_or_segment, but
    # only wrap the yield to be absolutely sure we don't report agent
    # problems as app errors
    yield
  rescue => exception
    current_transaction.notice_error(exception)
    raise
  ensure
    finishable&.finish
  end
end

.start_datastore_segment(product: nil, operation: nil, collection: nil, host: nil, port_path_or_id: nil, database_name: nil, start_time: nil, parent: nil) ⇒ DatastoreSegment

Creates and starts a datastore segment used to time datastore operations.

Parameters:

  • product (String) (defaults to: nil)

    the datastore name for use in metric naming, e.g. “FauxDB”

  • operation (String) (defaults to: nil)

    the name of the operation (e.g. “select”), often named after the method that’s being instrumented.

  • collection (optional, String) (defaults to: nil)

    the collection name for use in statement-level metrics (i.e. table or model name)

  • host (optional, String) (defaults to: nil)

    the host this database instance is running on

  • port_path_or_id (optional, String) (defaults to: nil)

    TCP port, file path, UNIX domain socket, or other connection-related info

  • database_name (optional, String) (defaults to: nil)

    the name of this database

  • start_time (optional, Time) (defaults to: nil)

    a Time instance denoting the start time of the segment. Value is set by AbstractSegment#start if not given.

  • parent (optional, Segment) (defaults to: nil)

    Use for the rare cases (such as async) where the parent segment should be something other than the current segment

Returns:

  • (DatastoreSegment)

    the newly created segment; you must call finish on it at the end of the code you’re tracing



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/new_relic/agent/tracer.rb', line 288

def start_datastore_segment(product: nil,
  operation: nil,
  collection: nil,
  host: nil,
  port_path_or_id: nil,
  database_name: nil,
  start_time: nil,
  parent: nil)

  product ||= UNKNOWN
  operation ||= OTHER

  segment = Transaction::DatastoreSegment.new(product, operation, collection, host, port_path_or_id, database_name)
  start_and_add_segment(segment, parent)
rescue ArgumentError
  raise
rescue => exception
  log_error('start_datastore_segment', exception)
end

.start_external_request_segment(library:, uri:, procedure:, start_time: nil, parent: nil) ⇒ ExternalRequestSegment

Creates and starts an external request segment using the given library, URI, and procedure. This is used to time external calls made over HTTP.

Parameters:

  • library (String)

    a string of the class name of the library used to make the external call, for example, ‘Net::HTTP’.

  • uri (String, URI)

    indicates the URI to which the external request is being made. The URI should begin with the protocol, for example, ‘github.com’.

  • procedure (String)

    the HTTP method being used for the external request as a string, for example, ‘GET’.

  • start_time (optional, Time) (defaults to: nil)

    a Time instance denoting the start time of the segment. Value is set by AbstractSegment#start if not given.

  • parent (optional, Segment) (defaults to: nil)

    Use for the rare cases (such as async) where the parent segment should be something other than the current segment

Returns:

  • (ExternalRequestSegment)

    the newly created segment; you must call finish on it at the end of the code you’re tracing



335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/new_relic/agent/tracer.rb', line 335

def start_external_request_segment(library:,
  uri:,
  procedure:,
  start_time: nil,
  parent: nil)

  segment = Transaction::ExternalRequestSegment.new(library, uri, procedure, start_time)
  start_and_add_segment(segment, parent)
rescue ArgumentError
  raise
rescue => exception
  log_error('start_external_request_segment', exception)
end

.start_segment(name:, unscoped_metrics: nil, start_time: nil, parent: nil) ⇒ Segment

Creates and starts a general-purpose segment used to time arbitrary code.

Parameters:

  • name (String)

    full name of the segment; the agent will not add a prefix. Third-party users should begin the name with Custom/; e.g., Custom/UserMailer/send_welcome_email

  • unscoped_metrics (optional, String, Array) (defaults to: nil)

    additional unscoped metrics to record using this segment’s timing information

  • start_time (optional, Time) (defaults to: nil)

    a Time instance denoting the start time of the segment. Value is set by AbstractSegment#start if not given.

  • parent (optional, Segment) (defaults to: nil)

    Use for the rare cases (such as async) where the parent segment should be something other than the current segment

Returns:

  • (Segment)

    the newly created segment; you must call finish on it at the end of the code you’re tracing



237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/new_relic/agent/tracer.rb', line 237

def start_segment(name:,
  unscoped_metrics: nil,
  start_time: nil,
  parent: nil)

  segment = Transaction::Segment.new(name, unscoped_metrics, start_time)
  start_and_add_segment(segment, parent)
rescue ArgumentError
  raise
rescue => exception
  log_error('start_segment', exception)
end

.start_transaction_or_segment(name: nil, partial_name: nil, category:, options: {}) ⇒ Object, #finish

Starts a segment on the current transaction (if one exists) or starts a new transaction otherwise.

Parameters:

  • name (String) (defaults to: nil)

    reserved for New Relic internal use

  • partial_name (String) (defaults to: nil)

    a meaningful name for this transaction (e.g., blogs/index); the Ruby agent will add a New-Relic-specific prefix

  • category (Symbol)

    :web for web transactions or :task for background transactions

  • options (Hash) (defaults to: {})

    reserved for New Relic internal use

Returns:

  • (Object, #finish)

    an object that responds to finish; you must call finish on it at the end of the code you’re tracing



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/new_relic/agent/tracer.rb', line 134

def start_transaction_or_segment(name: nil,
  partial_name: nil,
  category:,
  options: {})

  raise ArgumentError, 'missing required argument: name or partial_name' if name.nil? && partial_name.nil?

  if name
    options[:transaction_name] = name
  else
    options[:transaction_name] = Transaction.name_from_partial(
      partial_name,
      category
    )
  end

  if (txn = current_transaction)
    txn.create_nested_segment(category, options)
  else
    Transaction.start_new_transaction(state, category, options)
  end
rescue ArgumentError
  raise
rescue => exception
  log_error('start_transaction_or_segment', exception)
end

.tracing_enabled?Boolean

Returns true unless called from within an NewRelic::Agent.disable_all_tracing block.

Returns:

  • (Boolean)


31
32
33
# File 'lib/new_relic/agent/tracer.rb', line 31

def tracing_enabled?
  state.tracing_enabled?
end

.transaction_sampled?Boolean Also known as: sampled?

Returns a boolean indicating whether the current_transaction is sampled, or nil if there is no current transaction.

Returns:

  • (Boolean)


68
69
70
71
72
73
# File 'lib/new_relic/agent/tracer.rb', line 68

def transaction_sampled?
  txn = current_transaction
  return false unless txn

  txn.sampled?
end