github.com/waldiirawan/apm-agent-go/v2@v2.2.2/docs/custom-instrumentation.asciidoc (about)

     1  [[custom-instrumentation]]
     2  === Custom instrumentation
     3  
     4  To report on the performance of transactions served by your application, use the Go
     5  agent's <<api,API>>. Instrumentation refers to modifying your application code to report a:
     6  
     7   - <<custom-instrumentation-transactions,Transaction>> - A top-level operation in your application,
     8  such as an HTTP or RPC request.
     9   - <<custom-instrumentation-spans,Span within a transaction>> - An operation within a transaction,
    10  such as a database query, or a request to another service.
    11   - <<custom-instrumentation-errors,Error>> - May refer to Go errors or panics.
    12  
    13  To report these, use a <<tracer-api,apm.Tracer>> -- typically
    14  `apm.DefaultTracer()`, which is configured via environment variables. In the code
    15  examples below, we will refer to `apm.DefaultTracer()`. Please refer to the <<api, API documentation>>
    16  for a more thorough description of the types and methods.
    17  
    18  [[custom-instrumentation-transactions]]
    19  ==== Transactions
    20  
    21  To report a transaction, call <<tracer-api-start-transaction, apm.DefaultTracer().StartTransaction>>
    22  with the transaction name and type. This returns a `Transaction` object; the transaction
    23  can be customized with additional context before you call its `End` method to indicate
    24  that the transaction has completed. Once the transaction's `End` method is called, it
    25  will be enqueued for sending to the Elastic APM server, and made available to the APM app.
    26  
    27  [source,go]
    28  ----
    29  tx := apm.DefaultTracer().StartTransaction("GET /api/v1", "request")
    30  defer tx.End()
    31  ...
    32  tx.Result = "HTTP 2xx"
    33  tx.Context.SetLabel("region", "us-east-1")
    34  ----
    35  
    36  The agent supports sampling transactions: non-sampled transactions will be still be
    37  reported, but with limited context and without any spans. To determine whether a
    38  transaction is sampled, use the `Transaction.Sampled` method; if it returns false,
    39  you should avoid unnecessary storage or processing required for setting transaction
    40  context.
    41  
    42  Once you have started a transaction, you can include it in a `context` object for
    43  propagating throughout the application. See <<custom-instrumentation-propagation, context propagation>>
    44  for more details.
    45  
    46  [source,go]
    47  ----
    48  ctx = apm.ContextWithTransaction(ctx, tx)
    49  ----
    50  
    51  [[custom-instrumentation-spans]]
    52  ==== Spans
    53  
    54  To report an operation within a transaction, use <<transaction-start-span, Transaction.StartSpan>>
    55  or <<apm-start-span, apm.StartSpan>> to start a span given a transaction or a `context`
    56  containing a transaction, respectively. Like a transaction, a span has a name and a type. A span can have a parent span within the same transaction. If the context provided to `apm.StartSpan`
    57  contains a span, then that will be considered the parent. See <<custom-instrumentation-propagation, context propagation>>
    58  for more details.
    59  
    60  [source,go]
    61  ----
    62  span, ctx := apm.StartSpan(ctx, "SELECT FROM foo", "db.mysql.query")
    63  defer span.End()
    64  ----
    65  
    66  `Transaction.StartSpan` and `apm.StartSpan` will always return a non-nil `Span`, even if the
    67  transaction is nil. It is always safe to defer a call to the span's End method. If setting the span's
    68  context would incur significant overhead, you may want to check if the span is dropped first, by calling
    69  the `Span.Dropped` method.
    70  
    71  [[custom-instrumentation-errors]]
    72  ==== Panic recovery and errors
    73  
    74  To recover panics and report them along with your transaction, use the
    75  <<tracer-recovered, Tracer.Recovered>> method in a recovery function. There are also methods for reporting
    76  non-panic errors: <<tracer-new-error, Tracer.NewError>>, <<tracer-new-error-log, Tracer.NewErrorLog>>, and
    77  <<apm-captureerror, apm.CaptureError>>.
    78  
    79  [source,go]
    80  ----
    81  defer func() {
    82  	if v := recover(); v != nil {
    83  		e := apm.DefaultTracer().Recovered()
    84  		e.SetTransaction(tx) // or e.SetSpan(span)
    85  		e.Send()
    86  	}
    87  }()
    88  ----
    89  
    90  See the <<error-api, Error API>> for details and examples of the other methods.