=encoding UTF-8

=head1 NAME

OpenTelemetry::Trace::Tracer - A span factory for OpenTelemetry

=head1 SYNOPSIS

    use OpenTelemetry;

    my $provider = OpenTelemetry->tracer_provider;
    my $tracer   = $provider->tracer;

    # Create a span for manual use
    my $span = $tracer->create_span(%args);

    # Or execute code within a span (experimental)
    $tracer->in_span( my_span => sub ( $span, $context ) {
        ...
    });

=head1 DESCRIPTION

A tracer is responsible for creating L<OpenTelemetry::Trace::Span> objects.

=head1 METHODS

=head2 create_span

    $span = $tracer->create_span(
        attributes => $attributes // {},
        kind       => $span_kind  // $internal,
        links      => $links      // [],
        name       => $name,      // 'empty',
        parent     => $context    // undef,
        start      => $timestamp  // time,
    )

Creates an L<OpenTelemetry::Trace::Span> instance associated with this trace.

Takes a list of key / value pairs. Of these, the only one that callers are
I<always> expected to provide is the span name: not doing so may result in
a warning being logged and a placeholder name will be used instead. All other
keys are optional and can be used to further specify the span.

Note that even though the majority of these can be set after a span's
creation, it's always recommended to set these on creation if possible, since
this is the only time when they are guaranteed to be available for any
behaviours that may depend on them (eg. span sampling).

Spans can have zero or more child spans, which represent causally related
operations. These can be created by passing a
L<OpenTelemetry::Context> that holds the parent span as the value for the
C<parent> parameter. If no parent is set, or if the provided context does not
contain a span, the created span is considered a I<root span>. Typically, a
trace will only have one root span.

Spans can also have links to other spans, including those that belong to a
different trace. These can be set on span creation via the C<links> parameter,
which must hold a reference to an array of hashes. The hashes should have a
C<context> key set to the L<OpenTelemetry::Trace::SpanContext> of the span to
link to, and an optional C<attributes> key set to a hashref of attributes
to set on the link.

It is the responsibility of the user to make sure that every span that has
been created is ended (via a call to its L<end|OpenTelemetry::Trace::Span/end>
method).

=head2 in_span

    # Experimental
    $return = $tracer->in_span(
        $span_name,
        %span_arguments,
        sub ( $span, $context ) { ...; $return },
    );

This method is currently experimental.

Takes a string as the first argument and a subroutine reference as the last
argument, and executes the code in that reference within a span using the
string as its name. The subroutine reference will receive the created span and
the current context (containing the span) as arguments. The span is guaranteed
to be ended after execution of the subroutine ends by any means.

The status of the span will be set automatically at the end of the block
either to an Ok status (if the subroutine ended without error) or to Error
otherwise. In the latter case, the first line of the stringified error will be
set as the description, after removing any code context data (ie. the " at
script.pl line 123." that is added automatically by Perl). This can be avoided
by manually ending the span if needed.

Any additional parameters passed to this method between the span name and the
code reference will be passed as-is to the call to L</create_span> made when
creating the span. Note that the name provided as the first argument is
mandatory and will take precedence over any name set in these additional
parameters.

This method returns whatever the executed code reference returns.

=head1 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.
