=encoding utf8

=head1 NAME

OpenTelemetry::Instrumentation::LWP::UserAgent - OpenTelemetry instrumentation for LWP::UserAgent

=head1 SYNOPSIS

    use OpenTelemetry::Instrumentation 'LWP::UserAgent';

    # Or pass options to the instrumentation
    use OpenTelemetry::Instrumentation 'LWP::UserAgent' => {
        request_headers  => [ ... ],
        response_headers => [ ... ],
    };

    LWP::UserAgent->new->get('https://metacpan.org');

=head1 DESCRIPTION

This module can be used to instrument code using L<LWP::UserAgent> to generate
trace data using the L<OpenTelemetry> API. See L<OpenTelemetry::Instrumentation>
for more details.

This is one of the core instrumentations shipped with the base L<OpenTelemetry>
distribution.

The instrumentation provided by this module wraps around
L<LWP::UserAgent/simple_request> to automatically generate telemetry data for
every request that goes through that code path.

=head2 Attributes

Spans generated by this instrumentation will record the following attributes:

=over

=item C<http.request.body.size>

Set to the size of the return value of
L<< "content" in HTTP::Request|HTTP::Request/$r->content >>, as reported by
L<length|https://perldoc.perl.org/functions/length>. If this does not return a
truthy value, then this attribute will not be set.

=item C<http.request.header>

The instrumentation can be configured to store the value of specific request
headers under this key (see L</request_headers> for more details). When
configured to do so, requested headers will be read from the default headers
configured with this client, and from the headers set for this specific request.

Headers will be stored as they are found, with their names normalised to
lowercase and any hyphens (C<->) converted to underscores (C<_>). The stored
values will be coerced to arrayrefs, as per
L<the semantic convention documentation|https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md>.

=item C<http.resend_count>

Set to the number of redirects that were performed when executing this
request. Note that although the OpenTelemetry specification requires this
to include retries, this currently only includes the number of redirects.

=item C<http.response.body.size>

Set to the value of the Content-Length header received in the response. If
this header was not set, this attribute will not be recorded.

=item C<http.response.header>

The instrumentation can be configured to store the value of specific response
headers under this key (see L</response_headers> for more details). When
configured to do so, requested headers will be read from the headers received
in the response.

Headers will be stored as they are found, with their names normalised to
lowercase and any hyphens (C<->) converted to underscores (C<_>). The stored
values will be coerced to arrayrefs, as per
L<the semantic convention documentation|https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md>.

=item C<http.response.status_code>

Set to the status code of the response, as reported by
L<< "code" in HTTP::Response|HTTP::Response/$r->code >>.

=item C<http.request.method>

Set to the HTTP method of the request, as reported by
L<< "method" in HTTP::Response|HTTP::Response/$r->method >>.

=item C<network.protocol.name>

Unconditionally set to "http".

=item C<network.protocol.version>

Unconditionally set to "1.1".

=item C<network.transport>

Unconditionally set to "tcp".

=item C<server.address>

Set to the host of the URL, as reported by
L<< "host" in URI|URI/$uri->host >>.

=item C<server.port>

Set to the port of the URL, as reported by
L<< "port" in URI|URI/$uri->port >>.

=item C<url.full>

Set to the full URL, with the
L<userinfo|https://www.rfc-editor.org/rfc/rfc3986#section-3.2.1>
portion redacted (if it exists) in order to minimise the risk of leaking
sensitive information. If present, the userinfo will be rendered as
C<REDACTED:REDACTED>.

=item C<user_agent.original>

Set to the value returned by L<LWP::UserAgent/agent>.

=back

=head1 CONFIGURATION

=head2 request_headers

This instrumentation can be configured to store specific request headers with
every generated span. In order to do so, set this key to an array reference
with the name of the request headers you want as strings.

The strings will be matched case-insensitively to the header names, and hyphens
and underscores will be treated indistinctly. Otherwise, names will be matched
literally.

Matching headers will be stored as span attributes under the
C<http.request.header> namespace, as described in
L<the semantic convention documentation|https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-request-and-response-headers>.

=head2 response_headers

This instrumentation can be configured to store specific response headers with
every generated span. In order to do so, set this key to an array reference
with the name of the response headers you want as strings.

The strings will be matched case-insensitively to the header names, and hyphens
and underscores will be treated indistinctly. Otherwise, names will be matched
literally.

Matching headers will be stored as span attributes under the
C<http.response.header> namespace, as described in
L<the semantic convention documentation|https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-request-and-response-headers>.

=head2 SEE ALSO

=over

=item L<HTTP::Request>

=item L<HTTP::Response>

=item L<LWP::UserAgent>

=item L<OpenTelemetry>

=item L<OpenTelemetry::Instrumentation>

=item L<OpenTelemetry::Instrumentation::HTTP::Tiny>

=item L<URI>

=back

=head1 COPYRIGHT

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.
