Note
|
For the best reading experience, please view this documentation at elastic.co |
The public API of the Elastic APM .NET agent lets you customize and manually create spans and transactions, as well as track errors.
The tracer gives you access to the currently active transaction and it enables you to manually start a transaction.
You can access the API by using the static property on the Agent: Elastic.Apm.Agent.Tracer
.
Use this method to create a custom transaction.
Note that in the case of auto-instrumentation, the agent will automatically do this for you. For example, if you have incoming HTTP calls in an ASP.NET Core application, the agent automatically starts a transaction. In these instances, this method is not needed.
It’s important to call void End()
when the transaction has ended.
A best practice is to use the transaction in a try-catch-finally block or to use the CaptureTransaction
method.
Example:
var transaction = Elastic.Apm.Agent
.Tracer.StartTransaction("MyTransaction", ApiConstants.TypeRequest);
try
{
//application code that is captured as a transaction
}
catch (Exception e)
{
transaction.CaptureException(e);
throw;
}
finally
{
transaction.End();
}
Returns the currently active transaction. See the Transaction API to customize the current transaction.
If there is no current transaction,
this method will return null
.
var transaction = Elastic.Apm.Agent.Tracer.CurrentTransaction;
Returns the currently active span. See the Span API to customize the current span.
If there is no current span,
this method will return null
.
var span = Elastic.Apm.Agent.Tracer.CurrentSpan;
This is a convenient method which starts and ends a transaction and captures unhandled exceptions. It has 3 parameters:
-
name
: The name of the transaction -
type
The type of the transaction -
One of the following types which references the code that you want to capture as a transaction:
-
Action
-
Action<ITransaction>
-
Func<T>
-
Func<ITransaction,T>
-
Func<Task>
-
Func<ITransaction,Task>
-
Func<Task<T>>
-
Func<ITransaction,Task<T>>
-
The following code is the equivalent of the previous example with the convenient API. It automatically starts and ends the transaction and reports unhandled exceptions. The t
parameter gives you access to the ITransaction
instance which represents the transaction that you just created.
Elastic.Apm.Agent.Tracer
.CaptureTransaction("TestTransaction", ApiConstants.TypeRequest, (t) =>
{
//application code that is captured as a transaction
});
This API also supports async
methods with the Func<Task>
overloads.
Note
|
The duration of the transaction will be the timespan between the first and the last line of the async lambda expression.
|
Example:
await Elastic.Apm.Agent.Tracer
.CaptureTransaction("TestTransaction", "TestType", async () =>
{
//application code that is captured as a transaction
await Task.Delay(500); //sample async code
});
Note
|
Return value of CaptureTransaction method overloads that accept Task (or Task<T>) is the same Task (or Task<T>) instance as the one passed as the argument so if your application should continue only after the task completes you have to call CaptureTransaction with await keyword.
|
Agent automatically propagates distributed tracing context for the supported technologies (see [supported-networking-client-side-technologies]). If your application communicates over a protocol that is not supported by the agent you can manually propagate distributed tracing context from the caller to the callee side using Public Agent API.
First you serialize distributed tracing context on the caller side:
string outgoingDistributedTracingData =
(Agent.Tracer.CurrentSpan?.OutgoingDistributedTracingData
?? Agent.Tracer.CurrentTransaction?.OutgoingDistributedTracingData)?.SerializeToString();
Then you transfer the resulted string to the callee side
and you continue the trace by passing deserialized distributed tracing context to any of
ITransaction StartTransaction(string name, string type)
or CaptureTransaction
APIs
- all of these APIs have an optional DistributedTracingData
parameter.
For example:
var transaction2 = Agent.Tracer.StartTransaction("Transaction2", "TestTransaction",
DistributedTracingData.TryDeserializeFromString(serializedDistributedTracingData));
A transaction describes an event captured by an Elastic APM agent monitoring a service. Transactions help combine multiple Spans into logical groups, and they are the first Span of a service. More information on Transactions and Spans is available in the {apm-overview-ref-v}/apm-data-model.html[APM data model] documentation.
See ITransaction CurrentTransaction
on how to get a reference of the current transaction.
Note
|
Calling any of the transaction’s methods after void End() has been called is illegal.
You may only interact with a transaction when you have control over its lifecycle.
|
Start and return a new custom span as a child of the given transaction.
It is important to call void End()
when the span has ended or to use the CaptureSpan
method.
A best practice is to use the span in a try-catch-finally block.
Example:
ISpan span = transaction.StartSpan("Select FROM customer",
ApiConstants.TypeDb, ApiConstants.SubtypeMssql, ApiConstants.ActionQuery);
try
{
//execute db query
}
catch(Exception e)
{
span.CaptureException(e);
throw;
}
finally
{
span.End();
}
A flat mapping of user-defined labels with string values.
Tip
|
Before using custom labels, ensure you understand the different types of {apm-overview-ref-v}/metadata.html[metadata] that are available. |
Warning
|
Avoid defining too many user-specified labels. Defining too many unique fields in an index is a condition that can lead to a {ref}/mapping.html#mapping-limit-settings[mapping explosion]. |
Ageny.Tracer
.CaptureTransaction(TransactionName, TransactionType,
transaction =>
{
transaction.Labels["foo"] = "bar";
//application code that is captured as a transaction
});
-
key
: The label key -
value
: The label value
Ends the transaction and schedules it to be reported to the APM Server.
It is illegal to call any methods on a span instance which has already ended.
This also includes this method and ISpan StartSpan(string name, string type, string subType = null, string action = null)
.
Example:
transaction.End();
Note
|
If you use the CaptureTransaction method you must not call void End() .
|
Captures an exception and reports it to the APM server.
Captures a custom error and reports it to the APM server.
This method is typically used when you want to report an error, but you don’t have an Exception
instance.
This is a convenient method which starts and ends a span on the given transaction and captures unhandled exceptions. It has the same overloads as the CaptureTransaction
method.
It has 5 parameters:
-
name
: The name of the span -
type
The type of the span -
One of the following types which references the code that you want to capture as a transaction:
-
Action
-
Action<ITransaction>
-
Func<T>
-
Func<ITransaction,T>
-
Func<Task>
-
Func<ITransaction,Task>
-
Func<Task<T>>
-
Func<ITransaction,Task<T>>
-
-
supType
(optional): The subtype of the span -
action
(optional): The action of the span
The following code is the equivalent of the previous example from the ISpan StartSpan(string name, string type, string subType = null, string action = null)
section with the convenient API. It automatically starts and ends the span and reports unhandled exceptions. The s
parameter gives you access to the ISpan
instance which represents the span that you just created.
ITransaction transaction = Elastic.Apm.Agent.Tracer.CurrentTransaction;
transaction.CaptureSpan("SampleSpan", ApiConstants.TypeDb, (s) =>
{
//execute db query
}, ApiConstants.SubtypeMssql, ApiConstants.ActionQuery);
Similar to the CaptureTransaction
API, this method also supports async
methods with the Func<Task>
overloads.
Note
|
The duration of the span will be the timespan between the first and the last line of the async lambda expression.
|
This example shows you how to track an async
code block that returns a result (Task<T>
) as a span:
ITransaction transaction = Elastic.Apm.Agent.Tracer.CurrentTransaction;
var asyncResult = await transaction.CaptureSpan("Select FROM customer", ApiConstants.TypeDb, async(s) =>
{
//application code that is captured as a span
await Task.Delay(500); //sample async code
return 42;
});
Note
|
Return value of CaptureSpan method overloads that accept Task (or Task<T>) is the same Task (or Task<T>) instance as the one passed as the argument so if your application should continue only after the task completes you have to call CaptureSpan with await keyword.
|
Note
|
Code samples above use Elastic.Apm.Agent.Tracer.CurrentTransaction . In production code you should make sure the CurrentTransaction is not null .
|
You can attach additional context to manually captured transactions.
If you use a web framework for which agent doesn’t capture transactions automatically (see [supported-web-frameworks]),
you can add context related to the captured transaction by setting various properties of transaction’s Context
property.
For example:
Agent.Tracer.CaptureTransaction("MyCustomTransaction",ApiConstants.TypeRequest, (transaction) =>
{
transaction.Context.Request = new Request(myRequestMethod, myRequestUri);
// ... code executing the request
transaction.Context.Response =
new Response { StatusCode = myStatusCode, Finished = wasFinished };
});
A span contains information about a specific code path, executed as part of a transaction.
If for example a database query happens within a recorded transaction, a span representing this database query may be created. In such a case, the name of the span will contain information about the query itself, and the type will hold information about the database type.
Similar to Dictionary<string,string> Labels
on the Transaction API: A flat mapping of user-defined labels with string values.
Tip
|
Before using custom labels, ensure you understand the different types of {apm-overview-ref-v}/metadata.html[metadata] that are available. |
Warning
|
Avoid defining too many user-specified labels. Defining too many unique fields in an index is a condition that can lead to a {ref}/mapping.html#mapping-limit-settings[mapping explosion]. |
transaction.CaptureSpan(SpanName, SpanType,
span =>
{
span.Labels["foo"] = "bar";
//application code that is captured as a span
});
Captures an exception and reports it to the APM server.
Captures a custom error and reports it to the APM server.
This method is typically used when you want to report an error, but you don’t have an Exception
instance.
Ends the span and schedules it to be reported to the APM Server.
It is illegal to call any methods on a span instance which has already ended.
You can attach additional context to manually captured spans.
If you use a database library for which agent doesn’t capture spans automatically (see [supported-data-access-technologies]),
you can add context related to the captured database operation by setting span’s Context.Db
property.
For example:
Agent.Tracer.CurrentTransaction.CaptureSpan("MyDbWrite", ApiConstants.TypeDb, (span) =>
{
span.Context.Db = new Database
{ Statement = myDbStatement, Type = myDbType, Instance = myDbInstance };
// ... code executing the database operation
});
If you use an HTTP library for which agent doesn’t capture spans automatically (see [supported-networking-client-side-technologies]),
you can add context related to the captured HTTP operation by setting span’s Context.Http
property.
For example:
Agent.Tracer.CurrentTransaction.CaptureSpan("MyHttpOperation", ApiConstants.TypeExternal, (span) =>
{
span.Context.Http = new Http
{ Url = myUrl, Method = myMethod };
// ... code executing the HTTP operation
span.Context.Http.StatusCode = myStatusCode;
});