[[api]] == Public API Although most usage is covered automatically, Elastic APM also has a public API that allows custom usage. [float] [[agent-life-cycle]] === Agent life cycle Controlling when the agent starts and stops. [float] [[api-agent-start]] ==== `ElasticAPM.start` To create and start an ElasticAPM agent use `ElasticAPM.start`: [source,ruby] ---- ElasticAPM.start(server_url: 'http://localhost:8200') ---- * `config`: An optional hash or `ElasticAPM::Config` instance with configuration options. See <>. If you are using <> this is done automatically for you. If not see <>. [float] [[api-agent-stop]] ==== `ElasticAPM.stop` Stop the currently running agent. Use this inside `at_exit` in your <> to gracefully shut down. [float] [[api-agent-running]] ==== `ElasticAPM.running?` Returns whether the ElasticAPM Agent is currently running. [float] [[api-agent-agent]] ==== `ElasticAPM.agent` Returns the currently running agent or nil. [float] === Instrumentation [float] [[api-agent-current-transaction]] ==== `ElasticAPM.current_transaction` Returns the current `ElasticAPM::Transaction` or nil. [float] [[api-agent-start_transaction]] ==== `ElasticAPM.start_transaction` Start a _transaction_ eg. an incoming web request or a background job. [source,ruby] ---- # call with block ElasticAPM.start_transaction('Name') do_work # ... ElasticAPM.end_transaction('result') ---- Arguments: * `name`: A name for your transaction. Transactions are grouped by name. **Required**. * `type`: A `type` for your transaction eg. `db.postgresql.sql`. * `context:`: An optional <> used to enrich the transaction with information about the current request. * `traceparent:`: An optional `Traceparent` object for Distributed Tracing. Returns the transaction. [float] [[api-agent-end_transaction]] ==== `ElasticAPM.end_transaction` Ends the currently running transaction. Arguments: * `result`: A `String` result of the transaction, eg. `'success'`. [float] [[api-agent-with_transaction]] ==== `ElasticAPM.with_transaction` Wrap a block in a Transaction, starting and ending around the block [source,ruby] ---- ElasticAPM.transaction 'Do things' do |transaction| do_work # ... transaction.result = 'success' end ---- Arguments: * `name`: A name for your transaction. Transactions are grouped by name. **Required**. * `type`: A `type` for your transaction eg. `db.postgresql.sql`. * `context:`: An optional <> used to enrich the transaction with information about the current request. * `traceparent:`: An optional `Traceparent` object for Distributed Tracing. * `&block`: A block to wrap. Optionally yields the transaction. Returns the return value of the given block. [float] [[api-agent-start_span]] ==== `ElasticAPM.start_span` Start a new span. [source,ruby] ---- ElasticAPM.with_transaction 'Do things' do ElasticAPM.start_span 'Do one of the things' Database.query # ... ElasticAPM.end_span end ---- Arguments: * `name`: A name for your span. **Required**. * `type`: The type of work eg. `db.postgresql.query`. * `context`: An instance of `Span::Context`. * `include_stacktrace`: Whether or not to collect a Stacktrace. * `&block`: An optional block to wrap with the span. The block is passed the span as an optional argument. Returns the created span. [float] [[api-agent-end_span]] ==== `ElasticAPM.end_span` Ends the currently running span. [float] [[api-agent-with_span]] ==== `ElasticAPM.with_span` Wraps a block in a Span. Arguments: * `name`: A name for your span. **Required**. * `type`: The type of work eg. `db.postgresql.query`. * `context`: An instance of `Span::Context`. * `include_stacktrace`: Whether or not to collect a Stacktrace. * `&block`: An optional block to wrap with the span. The block is passed the span as an optional argument. Returns the return value of the given block. [float] [[api-agent-build-context]] ==== `ElasticAPM.build_context` Build a new _Context_ from a Rack `env`. A context provides information about the current request, response, user and more. Arguments: * `rack_env`: An instance of Rack::Env Returns the built context. [float] === Errors [float] [[api-agent-report]] ==== `ElasticAPM.report` Send an `Exception` to Elastic APM. If reported inside a transaction, the context from that will be added. [source,ruby] ---- begin do_a_thing_and_fail rescue Exception => e ElasticAPM.report(e) end ---- Arguments: * `exception`: An instance of `Exception`. **Required**. * `handled`: Whether the error was _handled_ eg. wasn't rescued and was represented to the user. Default: `true`. Returns `[ElasticAPM::Error]`. [float] [[api-agent-report-message]] ==== `ElasticAPM.report_message` Send a custom message to Elastic APM. If reported inside a transaction, the context from that will be added. [source,ruby] ---- ElasticAPM.report_message('This should probably never happen?!') ---- Arguments: * `message`: A custom error string. **Required**. Returns `[ElasticAPM::Error]`. [float] === Context [float] [[api-agent-set-tag]] ==== `ElasticAPM.set_tag` Add a tag to the current transaction. Tags are basic key-value pairs that are indexed in your Elasticsearch database and therefore searchable. [source,ruby] ---- before_action do ElasticAPM.set_tag(:company_id, current_user.company.id) end ---- Arguments: * `key`: A string key. Note that `.`, `*` or `"` will be converted to `_`. * `value`: A string value. Returns the set `value`. WARNING: Be aware that tags are indexed in Elasticsearch. Using too many unique keys will result in *https://www.elastic.co/blog/found-crash-elasticsearch#mapping-explosion[Mapping explosion]*. [float] [[api-agent-set-custom-context]] ==== `ElasticAPM.set_custom_context` Add custom context to the current transaction. Use this to further specify a context that will help you track or diagnose what's going on inside your app. If called several times during a transaction the custom context will be destructively merged with `merge!`. [source,ruby] ---- before_action do ElasticAPM.set_custom_context(company: current_user.company.to_h) end ---- Arguments: * `context`: A hash of JSON-compatible key-values. Can be nested. Returns current custom context. [float] [[api-agent-set-user]] ==== `ElasticAPM.set_user` Add the current user to the current transaction's context. Arguments: * `user`: An object representing the user Returns the given user [float] === Data [float] [[api-agent-add-filter]] ==== `ElasticAPM.add_filter` Provide a filter to transform payloads before sending. Arguments: * `key`: A unique key identifying the filter * `callable`: An object or proc (responds to `.call(payload)`) Return the altered payload. If `nil` is returned all subsequent filters will be skipped and the post request cancelled. Example: [source,ruby] ---- ElasticAPM.add_filter(:filter_pings) do |payload| payload[:transactions]&.reject! do |t| t[:name] == 'PingsController#index' end payload end ---- [float] [[api-transaction]] === Transaction `ElasticAPM.transaction` returns a `Transaction` (if the agent is running). [float] ==== Properties - `name`: String - `type`: String - `result`: String - `trace_id`: String (readonly) [float] [[api-transaction-sampled_]] ==== #sampled? Whether the transaction is _sampled_ eg. it includes stacktraces for its spans. [float] [[api-transaction-ensure_parent_id]] ==== #ensure_parent_id If the transaction does not have a parent-ID yet, calling this method generates a new ID, sets it as the parent-ID of this transaction, and returns it as a `String`. This enables the correlation of the spans the JavaScript Real User Monitoring (RUM) agent creates for the initial page load with the transaction of the backend service. If your service generates the HTML page dynamically, initializing the JavaScript RUM agent with the value of this method allows analyzing the time spent in the browser vs in the backend services. To enable the JavaScript RUM agent, initilialize the RUM agent with the Ruby agent'a current transaction: [source,html] ---- ---- See the {apm-rum-ref}[JavaScript RUM agent documentation] for more information. [float] [[api-span]] === Span [float] ==== Properties - `name`: String - `type`: String [float] [[api-context]] === Context