=encoding UTF-8

=head1 NAME

OpenTelemetry::Guides::Exporters - Process and export your OpenTelemetry data

=head1 DESCRIPTION

This page talks about the tools and processes used for sending telemetry data
to OpenTelemetry-enabled backends. For information on how to generate that
data, from your own code or your dependencies, see L<OpenTelemetry::Guides::Instrumentation> and
L<OpenTelemetry::Guides::Libraries> respectively.

=head1 EXPORTING TELEMETRY

Send telemetry to the OpenTelemetry Collector to make sure it's exported
correctly. Using the Collector in production environments is a best practice.
To visualise your telemetry, export it to a backend such as
L<Jaeger|https://jaegertracing.io>,
L<Zipkin|https://zipkin.io>,
L<Prometheus|https://prometheus.io>,
or a L<vendor-specific|https://opentelemetry.io/ecosystem/vendors> backend.

=head2 OTLP

To send trace data to a OTLP endpoint (like the
L<collector|https://opentelemetry.io/docs/collector> or
L<Jaeger|https://jaegertracing.io>) you'll want to use an exporter package,
such as L<OpenTelemetry::Exporter::OTLP> and configure it to send that data
wherever it needs to go.

Let's use the example from L<OpenTelemetry::Guides::Quickstart>. In that case,
we got the traces exported to STDOUT because we executed it with the
C<OTEL_TRACES_EXPORTER> environment variable set to C<console>. But we can
change that.

We'll need to install some additional dependencies. We'll need the exporter
itself, and since this example is running on L<Mojolicious> we will also need
to install L<IO::Async::Loop::Mojo> so the batch span processor used by the
OTLP exporter hooks into the Mojolicious event loop.

    cpanm \
        OpenTelemetry::Exporter::OTLP \
        IO::Async::Loop::Mojo

Before we execute the code, we'll also need to set up something that can
receive the OTLP traffic generated by the exporter. For this, we can use
L<collector example|hittps://github.com/jjatria/perl-opentelemetry/tree/main/examples/collector>
in this distribution which has a "docker compose" stack with an OpenTelemetry
Collector that prints any telemetry it receives to the console, and is
connected to a Jaeger and a Prometheus instance:

    git clone https://github.com/jjatria/perl-opentelemetry
    cd perl-opentelemetry/examples/collector
    docker compose up

By default traces are sent to an OTLP endpoint listening on localhost:4318.
You can change the endpoint by setting the
L<OTEL_EXPORTER_OTLP_ENDPOINT|OpenTelemetry::SDK/OTEL_EXPORTER_OTLP_ENDPOINT>
environment variable accordingly (we can use the default value). We'll also
set a L<OTEL_SERVICE_NAME|OpenTelemetry::SDK/OTEL_SERVICE_NAME> so the
exporter knows the source of the traces, and set
L<OTEL_BSP_MAX_EXPORT_BATCH_SIZE|OpenTelemetry::SDK/OTEL_BSP_MAX_EXPORT_BATCH_SIZE>
to 1 so we export every request to the collector as it comes (note that you
probably don't want to do this in production). Finally, we'll set
L<IO_ASYNC_LOOP/IO::Async::Loop> to C<Mojo> to specify which event loop
implementation to use:

    OTEL_SERVICE_NAME=dice \
    OTEL_BSP_MAX_EXPORT_BATCH_SIZE=1 \
    IO_ASYNC_LOOP=Mojo \
    ./Dice daemon

Making requests to L<http://localhost:3000/roll> should now generate trace
data that you can examine by going to L<http://localhost:16686>.

=head1 WHAT NEXT?

This document described how to export telemetry data generated by your
application to a backend for further processing. If you want to read about
generating that data from your own code you should read
L<OpenTelemetry::Guides::Instrumentation>, or
L<OpenTelemetry::Guides::Libraries> if you want to generate it from a library
on CPAN.

=head1 COPYRIGHT AND LICENSE

This document is copyright (c) 2024 by José Joaquín Atria.

It is based on the original OpenTelemetry documentation for Ruby which is
(c) OpenTelemetry Authors and available at
L<https://opentelemetry.io/docs/languages/ruby>. It has been modified to
fit the Perl implementation.

This is free software; you can redistribute it and/or modify it under the same
terms as the Perl 5 programming language system itself.
