NAME
Mojolicious::Plugin::OpenTelemetry - Use OpenTelemetry in your Mojolicious app
SYNOPSIS
use Mojolicious::Lite -signatures;
plugin OpenTelemetry => {
# Passed to OpenTelemetry::Trace::TracerProvider->tracer
tracer => {
name => 'my_app', # defaults to OTEL_SERVICE_NAME or moniker
version => '1.234', # optional
},
};
# Will generate a span named
# GET /static/url
get '/static/url' => sub ( $c, @ ) {
$c->render( text => 'OK' );
};
# Will use placeholders for reduced span cardinality
# POST /url/with/:placeholder
post '/url/with/:placeholder' => sub ( $c, @ ) {
$c->render( text => 'OK' );
};
# Use it also with async actions!
get '/async' => sub ( $c, @ ) {
$c->ua->get_p('https://httpbin.org/delay/1')
->then( sub {
$c->render( json => shift->result->json );
});
};
# Errors will be correctly captured in the span
get '/error' => sub ( $c, @ ) {
die 'oops';
};
app->start;
DESCRIPTION
This plugin allows a Mojolicious application to automatically generate telemetry data using the OpenTelemetry API. The plugin will wrap around any endpoint actions, and capture telemetry data about it on a OpenTelemetry::Trace::Span object.
METHODS
Mojolicious::Plugin::OpenTelemetry inherits all methods from Mojolicious::Plugin and implements the following new ones.
register
$plugin->register(
Mojolicious->new,
{
tracer => \%tracer_args,
},
);
Registers this plugin in a Mojolicious application.
When registered, this plugin will install a wrapper around any endpoint action (as described in "around_action" in Mojolicious). Actions that are not endpoints will be unaffected.
Before the action is executed, a server span will be created and injected into the current context, together with any propagation data retrieved from the incoming request headers by the currently installed propagator.
The value of the tracer
parameter passed on registration will be used to obtain a tracer via "tracer" in OpenTelemetry::Trace::TracerProvider. Setting this is optional. If no value is set, the value will be read from the "OTEL_SERVICE_NAME" environment variable, or from the app's moniker, will be used as the default name, but all other values will be left unspecified.
The name of the generated span will be derived from the current request method, and the stringified endpoint of the matching route, as in GET /foo/:bar
, to reduce the span cardinality.
The span will be created with the following attributes, which will therefore be available for any sampling decision.
http.request.method
-
Set to the request method. It will be the same value that was concatenated to the route in the span's name.
network.protocol.version
-
Set to the request version.
url.path
-
Set to the path of the request URL. This will be the raw path, without using any placeholders. It will not include the query string.
url.scheme
-
Set to the scheme of the request URL.
http.route
-
Set to the stringified endpoint of the matching route. This will use placeholders, and will be the same value that was concatenated to the method in the span's name.
client.address
-
Set to the remote address of the transaction. This will respect the value set in the
X-Forwarded-For
header, if any. client.port
-
Set to the remote port of the transaction.
server.address
-
Set to the host portion of the
host
value in the leftmost entry in theForwarded
header, falling back to the value of theX-Forwarded-Proto
header, or to the value of theHost
header if no other is set. The host portion is the part before an optional port number.See the semantic conventions entry for this attribute for more details on this logic.
If no value could be determined, this attribute will not be present.
server.port
-
Set to the port number in the
host
value in the leftmost entry in theForwarded
header, falling back to the value of theX-Forwarded-Proto
header, or to the value of theHost
header if no other is set.See the semantic conventions entry for this attribute for more details on this logic.
The port number in these is optional. If none is set, or none could be determined, this attribute will not be present.
user_agent.original
-
Set to the value of the user agent header. If not set, this attribute will not be present.
url.query
-
Set to the query of the request URL, if present. If the URL had no query parameters, this attribute will not be present.
The attributes described below will be set in the span once the action is completed, but will not be available for the sampler.
error.type
-
If an error is encountered during the execution of the action, this attribute will be set to the package name of the error (as reported by "ref"), or the value
string
if the error is not blessed into any package.If there were no errors, this attribute will not be present.
http.response.status_code
-
Set to the status code of the response. If an error was encountered during the execution of the action, this will be set to
500
.
The span will be unconditionally ended after the action has completed, and the status will be set to an error status if the response result in a server error (any HTTP status greater than or equal to 500).
If an exception is raised during the execution of the action, this will be caught and the description of the error status will be based on the message in that exception (otherwise no description will be set). The description will contain the first line of the exception body, minus any trailing markers of where the error took place, with the aim to make it safe to be exposed without leaking too much internal information.
Any exceptions caught by this integration will be re-thrown to be handled downstream.
LIMITATIONS
Routes generated with under are NOT currently instrumented. The code in the generated route will in effect run before the span is created, when no valid span is present in the context (unless one has been added by you).
That said, the final routes that execute (ie. the ones that are under the generated one) will correctly execute in a context with a span.
SEE ALSO
- Mojolicious
- Mojolicious::Plugin
- OpenTelemetry
- OpenTelemetry::Context
- OpenTelemetry::Constants
- OpenTelemetry::Trace::Span
- OpenTelemetry::Trace::Tracer
- OpenTelemetry::Trace::TracerProvider
COPYRIGHT AND LICENSE
This software is copyright (c) 2023 by José Joaquín Atria.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.