Class: Appsignal::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/appsignal/transaction.rb,
lib/appsignal/transaction/base_backend.rb,
lib/appsignal/transaction/extension_backend.rb,
lib/appsignal/transaction/opentelemetry_backend.rb,
sig/appsignal.rbs

Constant Summary collapse

HTTP_REQUEST =

Returns:

  • (String)
"http_request"
BACKGROUND_JOB =

Returns:

  • (String)
"background_job"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.complete_current!void

This method returns an undefined value.

Complete the currently active transaction and unset it as the active transaction.



161
162
163
164
165
166
167
168
169
# File 'lib/appsignal/transaction.rb', line 161

def complete_current!
  current.complete
rescue => e
  Appsignal.internal_logger.error(
    "Failed to complete transaction ##{current.transaction_id}. #{e.message}"
  )
ensure
  clear_current_transaction!
end

.create(namespace, opentelemetry_context: nil, opentelemetry_scope: nil, opentelemetry_kind: nil, opentelemetry_relationship: nil) ⇒ Object

Create a new transaction and set it as the currently active transaction.

@param namespace — Namespace of the to be created transaction.

@param opentelemetry_kind — In collector mode, the OpenTelemetry span kind: one of :server, :consumer, :producer or :internal. Defaults to :server.

@param opentelemetry_relationship — In collector mode, how an incoming opentelemetry_context relates to this transaction's span: one of :parent, :link, :both or :none. Defaults to :parent.

@param opentelemetry_context — In collector mode, an incoming OpenTelemetry trace context to relate this transaction's span to.

@param opentelemetry_scope — In collector mode, the OpenTelemetry instrumentation scope to record this transaction's spans under, given as a [name, version] pair. Defaults to the AppSignal scope.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/appsignal/transaction.rb', line 49

def create(
  namespace,
  opentelemetry_context: nil,
  opentelemetry_scope: nil,
  opentelemetry_kind: nil,
  opentelemetry_relationship: nil
)
  # Reset the transaction if it was already completed but not cleared
  if Thread.current[:appsignal_transaction]&.completed?
    Thread.current[:appsignal_transaction] = nil
  end

  if Thread.current[:appsignal_transaction].nil?
    # If not, start a new transaction
    set_current_transaction(
      Appsignal::Transaction.new(
        namespace,
        :opentelemetry_context => opentelemetry_context,
        :opentelemetry_scope => opentelemetry_scope,
        :opentelemetry_kind => opentelemetry_kind,
        :opentelemetry_relationship => opentelemetry_relationship
      )
    )
  else
    transaction = current
    # Otherwise, log the issue about trying to start another transaction
    Appsignal.internal_logger.warn(
      "Trying to start new transaction, but a transaction " \
        "with id '#{transaction.transaction_id}' is already running. " \
        "Using transaction '#{transaction.transaction_id}'."
    )

    # And return the current transaction instead
    transaction
  end
end

.currentAppsignal::Transaction, Appsignal::Transaction::NilTransaction

Returns currently active transaction or a NilTransaction if none is active.

@see .current?

Returns:



144
145
146
# File 'lib/appsignal/transaction.rb', line 144

def current
  Thread.current[:appsignal_transaction] || NilTransaction.new
end

.current?Boolean

Returns if any transaction is currently active or not. A NilTransaction is not considered an active transaction.

@see .current

Returns:

  • (Boolean)


153
154
155
# File 'lib/appsignal/transaction.rb', line 153

def current?
  current && !current.nil_transaction?
end

Instance Method Details

#add_breadcrumb(category, action, message = "", metadata = {}, time = Time.now.utc) ⇒ Object

Add breadcrumbs to the transaction.

@param category — category of breadcrumb e.g. "UI", "Network", "Navigation", "Console".

@param action — name of breadcrumb e.g "The user clicked a button", "HTTP 500 from http://blablabla.com"

@param message — optional message in string format

@param metadata — key/value metadata in <string, string> format

@param time — time of breadcrumb, should respond to .to_i defaults to Time.now.utc

@see Appsignal.add_breadcrumb

@see https://docs.appsignal.com/ruby/instrumentation/breadcrumbs.html — Breadcrumb reference



716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
# File 'lib/appsignal/transaction.rb', line 716

def add_breadcrumb(category, action, message = "",  = {}, time = Time.now.utc)
  unless .is_a? Hash
    Appsignal.internal_logger.error "add_breadcrumb: Cannot add breadcrumb. " \
      "The given metadata argument is not a Hash."
    return
  end

  # The backend owns how breadcrumbs are stored: the agent backend buffers
  # them and flushes at completion, the OpenTelemetry backend emits each as a
  # span event right away (by completion its target span has finished).
  @backend.add_breadcrumb(
    :time => time.to_i,
    :category => category,
    :action => action,
    :message => message,
    :metadata => 
  )
end

#add_custom_data(data) ⇒ void Also known as: set_custom_data

This method returns an undefined value.

Add custom data to the transaction.

@param data — Custom data to add to the transaction.

@see Helpers::Instrumentation#add_custom_data

@see https://docs.appsignal.com/guides/custom-data/sample-data.html — Sample data guide

Parameters:



697
698
699
# File 'lib/appsignal/transaction.rb', line 697

def add_custom_data(data)
  @custom_data.add(data)
end

#add_function_parameters(given_params = nil, &block) ⇒ void

This method returns an undefined value.

Add the function parameters to the transaction.

These are the arguments a background job or function was called with. In collector mode they map to the function parameters attribute. In agent mode they are the transaction's params.

Behaves like #add_params: merges when called multiple times, and a block takes precedence over the argument.

@param given_params — The parameters to add to the transaction.

@see #add_request_payload

Parameters:

  • given_params (?(::Hash[String, Object] | ::Array[Object]), nil) (defaults to: nil)


529
530
531
# File 'lib/appsignal/transaction.rb', line 529

def add_function_parameters(given_params = nil, &block)
  params_data(:function_parameters).add(given_params, &block)
end

#add_headers(given_headers = nil, &block) ⇒ void Also known as: set_headers

This method returns an undefined value.

Add headers to the transaction.

@param given_headers — A hash containing headers.

@see Helpers::Instrumentation#add_headers

@see https://docs.appsignal.com/guides/custom-data/sample-data.html — Sample data guide

Parameters:

  • given_headers (::Hash[String, Object], nil) (defaults to: nil)


661
662
663
# File 'lib/appsignal/transaction.rb', line 661

def add_headers(given_headers = nil, &block)
  @headers.add(given_headers, &block)
end

#add_opentelemetry_attributes(attributes = {}) ⇒ void

This method returns an undefined value.

Add OpenTelemetry attributes to the span AppSignal is currently recording.

In collector mode, AppSignal records a transaction as an OpenTelemetry span, and every instrumented event as a child span. This adds attributes to whichever of those spans is open right now: the innermost event started by Helpers::Instrumentation#instrument, or the transaction's own span when no event is open.

Use this to describe what is being instrumented in OpenTelemetry's own terms, following the OpenTelemetry semantic conventions where they apply. Attributes have no equivalent outside collector mode, so this does nothing when collector mode is not active.

@param attributes — Attributes to add to the current span. Values that are not a String, Integer, Float or boolean are converted to a String. Nothing is added when this is nil or empty.

Describing a database query

Appsignal.instrument("query.my_database") do
  Appsignal::Transaction.current.add_opentelemetry_attributes(
    "db.system.name" => "mysql"
  )
  run_the_query
end

@see https://opentelemetry.io/docs/specs/semconv/ — OpenTelemetry semantic conventions

Parameters:

  • attributes (::Hash[String, Object], nil) (defaults to: {})


853
854
855
856
857
# File 'lib/appsignal/transaction.rb', line 853

def add_opentelemetry_attributes(attributes = {})
  return if attributes.nil? || attributes.empty?

  @backend.set_attributes(attributes)
end

#add_params(given_params = nil, &block) ⇒ void Also known as: set_params

This method returns an undefined value.

Add parameters to the transaction.

When this method is called multiple times, it will merge the request parameters.

When both the given_params and a block is given to this method, the block is leading and the argument will not be used.

@param given_params — The parameters to set on the transaction.

@see Helpers::Instrumentation#add_params

@see https://docs.appsignal.com/guides/custom-data/sample-data.html — Sample data guide

Parameters:

  • given_params (?(::Hash[String, Object] | ::Array[Object]), nil) (defaults to: nil)


434
435
436
437
# File 'lib/appsignal/transaction.rb', line 434

def add_params(given_params = nil, &block)
  warn_params_deprecation
  params_data(:params).add(given_params, &block)
end

#add_query_parameters(given_params = nil, &block) ⇒ void

This method returns an undefined value.

Add the query parameters to the transaction.

These are the parameters parsed from an incoming request's query string. In collector mode they map to their own attribute, separate from the request payload and the function parameters. In agent mode they are the transaction's params.

Behaves like #add_params: merges when called multiple times, and a block takes precedence over the argument.

@param given_params — The parameters to add to the transaction.

@see #add_request_payload

Parameters:

  • given_params (?(::Hash[String, Object] | ::Array[Object]), nil) (defaults to: nil)


566
567
568
# File 'lib/appsignal/transaction.rb', line 566

def add_query_parameters(given_params = nil, &block)
  params_data(:query_parameters).add(given_params, &block)
end

#add_request_payload(given_params = nil, &block) ⇒ void

This method returns an undefined value.

Add the request payload to the transaction.

These are the parameters of an incoming request, such as the query string and the request body. In collector mode they map to the request payload attribute. In agent mode they are the transaction's params.

Behaves like #add_params: merges when called multiple times, and a block takes precedence over the argument.

@param given_params — The parameters to add to the transaction.

@see #add_function_parameters

Parameters:

  • given_params (?(::Hash[String, Object] | ::Array[Object]), nil) (defaults to: nil)


493
494
495
# File 'lib/appsignal/transaction.rb', line 493

def add_request_payload(given_params = nil, &block)
  params_data(:request_payload).add(given_params, &block)
end

#add_session_data(given_session_data = nil, &block) ⇒ void Also known as: set_session_data

This method returns an undefined value.

Add session data to the transaction.

When this method is called multiple times, it will merge the session data.

When both the given_session_data and a block is given to this method, the block is leading and the argument will not be used.

@param given_session_data — A hash containing session data.

@see Helpers::Instrumentation#add_session_data

@see https://docs.appsignal.com/guides/custom-data/sample-data.html — Sample data guide

Parameters:

  • given_session_data (::Hash[String, Object], nil) (defaults to: nil)


622
623
624
# File 'lib/appsignal/transaction.rb', line 622

def add_session_data(given_session_data = nil, &block)
  @session_data.add(given_session_data, &block)
end

#add_tags(given_tags = {}) ⇒ void Also known as: set_tags

This method returns an undefined value.

Add tags to the transaction.

When this method is called multiple times, it will merge the tags.

@param given_tags — Collection of tags.

@see Helpers::Instrumentation#add_tags

@see https://docs.appsignal.com/ruby/instrumentation/tagging.html — Tagging guide

Parameters:

  • given_tags (::Hash[String, Object]) (defaults to: {})


600
601
602
# File 'lib/appsignal/transaction.rb', line 600

def add_tags(given_tags = {})
  @tags.merge!(given_tags)
end

#set_action(action) ⇒ void

This method returns an undefined value.

Set an action name for the transaction.

An action name is used to identify the location of a certain sample; error and performance issues.

@param action — the action name to set.

@see Appsignal::Helpers::Instrumentation#set_action

Parameters:

  • action (String)


745
746
747
748
749
750
# File 'lib/appsignal/transaction.rb', line 745

def set_action(action)
  return unless action

  @action = action
  @backend.set_action(action)
end

#set_namespace(namespace) ⇒ void

This method returns an undefined value.

Set the namespace for this transaction.

Useful to split up parts of an application into certain namespaces. For example: http requests, background jobs and administration panel controllers.

Note: The "http_request" namespace gets transformed on AppSignal.com to "Web" and "background_job" gets transformed to "Background".

@param namespace — namespace name to use for this transaction.

transaction.set_namespace("background")

@see Appsignal::Helpers::Instrumentation#set_namespace

@see https://docs.appsignal.com/guides/namespaces.html — Grouping with namespaces guide

Parameters:

  • namespace (String)


793
794
795
796
797
798
# File 'lib/appsignal/transaction.rb', line 793

def set_namespace(namespace)
  return unless namespace

  @namespace = namespace
  @backend.set_namespace(namespace)
end

#set_queue_start(start) ⇒ void

This method returns an undefined value.

Set queue start time for transaction.

@param start — Queue start time in milliseconds.

Parameters:

  • start (Integer)


808
809
810
811
812
813
814
# File 'lib/appsignal/transaction.rb', line 808

def set_queue_start(start)
  return unless start

  @backend.set_queue_start(start)
rescue RangeError
  Appsignal.internal_logger.warn("Queue start value #{start} is too big")
end