Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve exporter module documentation and readme #292

Merged
merged 5 commits into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions apps/opentelemetry_exporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ The OpenTelemetry Protocol exporter for use with the [OpenTelemetry Collector](h

Currently only supports the Tracer protocol using either GRPC or Protobuffers over HTTP1.1. Metrics are to come soon.

## Using
## Configuration

### Options to Batch Processor

Easiest way to setup is to add configuration for the batch processor in OpenTelemetry application environment.

Expand All @@ -16,7 +18,9 @@ For an Erlang release in `sys.config`:
{opentelemetry,
[{processors,
[{otel_batch_processor,
#{exporter => {opentelemetry_exporter, #{endpoints => [{http, "localhost", 9090, []}]}}}}]}]}
#{exporter => {opentelemetry_exporter, #{endpoints =>
["http://localhost:9090"],
headers => [{"x-honeycomb-dataset", "experiments"}]}}}}]}]}
```

The default protocol is `http_protobuf`, to override this and use grpc add `protocol` to the config map:
Expand All @@ -26,18 +30,56 @@ The default protocol is `http_protobuf`, to override this and use grpc add `prot
[{processors,
[{otel_batch_processor,
#{exporter => {opentelemetry_exporter, #{protocol => grpc,
endpoints => [{http, "localhost", 9090, []}]}}}}]}]}
endpoints => ["http://localhost:9090"],
headers => [{"x-honeycomb-dataset", "experiments"}]}}}}]}]}
```

An Elixir release uses `releases.exs`:

``` elixir
config :opentelemetry, :processors,
otel_batch_processor: %{
exporter: {:opentelemetry_exporter, %{endpoints: [{:http, 'localhost', 9090, []}]}}
exporter: {:opentelemetry_exporter, %{endpoints: ["http://localhost:9090"],
headers: [{"x-honeycomb-dataset", "experiments"}]}}
}
```

### Application Environment

- `otlp_endpoint`: The URL to send traces and metrics to, for traces the path `v1/traces` is appended to the path in the URL.
- `otlp_traces_endpoint`: URL to send only traces to. This takes precedence for exporting traces and the path of the URL is kept as is, no suffix is appended.
- `otlp_headers`: List of additional headers (`[{unicode:chardata(), unicode:chardata()}]`) to add to export requests.
- `otlp_traces_headers`: Additional headers (`[{unicode:chardata(), unicode:chardata()}]`) to add to only trace export requests.


``` erlang
{opentelemetry_exporter,
[{otlp_endpoint, "https://api.honeycomb.io:443"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be good to add a note that SSL options aren't provided with this config. There's a new way to configure them and we could point out to https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/ssl for ways to safely configure it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I need to update the actual module to accept SSL args first though? And then it'd be based on these docs? https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/inets

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought #266 accomplished that already

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for grpc. Looks like httpc never got any update.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah damn. Then yeah it'd need similar support. I guess we can't hold back the PR for this though, and it'd be better tracked as a follow-up. Approving with the assumption the typespec in the other comment will be handled.

{otlp_headers, [{"x-honeycomb-dataset", "experiments"}]}]}
```

An Elixir release uses `releases.exs`:

``` elixir
config :opentelemetry_exporter,
otlp_endpoint: "https://api.honeycomb.io:443",
otlp_headers: [{"x-honeycomb-dataset", "experiments"}]
```

### OS Environment

- `OTEL_EXPORTER_OTLP_ENDPOINT`: The URL to send traces and metrics to, for traces the path `v1/traces` is appended to the path in the URL.
- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`: URL to send only traces to. This takes precedence for exporting traces and the path of the URL is kept as is, no suffix is appended.
- `OTEL_EXPORTER_OTLP_HEADERS`: List of additional headers to add to export requests.
- `OTEL_EXPORTER_OTLP_TRACES_HEADERS`: Additional headers to add to only trace export requests.

Example usage of setting the environment variables:
```
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://api.honeycomb.io:443
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_TRACES_HEADERS=x-honeycomb-team=<HONEYCOMB API TOKEN>,x-honeycomb-dataset=experiments
```

## Contributing

This project uses a submodule during developement, it is not needed if the application is being used as a dependency, so be sure to clone with the option `recurse-submodules`:
Expand Down
41 changes: 31 additions & 10 deletions apps/opentelemetry_exporter/src/opentelemetry_exporter.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@
%% for exporting traces and the path of the URL is kept as is, no suffix is
%% appended.
%% </li>
%% <li>`otlp_headers': Additional headers to add to export requests.</li>
%% <li>`otlp_headers': List of additional headers (`[{unicode:chardata(), unicode:chardata()}]') to add to export requests.</li>
%% <li>
%% `otlp_traces_headers': Additional headers to add to only trace export %% requests.
%% `otlp_traces_headers': Additional headers (`[{unicode:chardata(), unicode:chardata()}]') to add to only trace export requests.
%% </li>
%% </ul>
%%
%% There also corresponding OS environment variables can also set those
%% configuration values:
%%
%% <ul>
%% <li>`OTEL_EXPORTER_OTLP_ENDPOINT'</li>
%% <li>`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'</li>
%% <li>`OTEL_EXPORTER_OTLP_HEADERS'</li>
%% <li>`OTEL_EXPORTER_OTLP_TRACES_HEADERS'</li>
%% <li>`OTEL_EXPORTER_OTLP_ENDPOINT': The URL to send traces and metrics to, for traces the path `v1/traces' is appended to the path in the URL.</li>
%% <li>`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT': URL to send only traces to. This takes precedence for exporting traces and the path of the URL is kept as is, no suffix is appended.</li>
%% <li>`OTEL_EXPORTER_OTLP_HEADERS': List of additional headers to add to export requests.</li>
%% <li>`OTEL_EXPORTER_OTLP_TRACES_HEADERS': Additional headers to add to only trace export requests.</li>
%% </ul>
%%
%% @end
Expand All @@ -53,10 +53,12 @@
shutdown/1]).

%% for testing
-ifdef(TEST).
-export([to_proto_by_instrumentation_library/1,
to_proto/1,
endpoints/1,
merge_with_environment/1]).
-endif.

-include_lib("kernel/include/logger.hrl").
-include_lib("opentelemetry_api/include/opentelemetry.hrl").
Expand All @@ -69,15 +71,34 @@
-define(DEFAULT_PORT, 4317).
-define(DEFAULT_TRACES_PATH, "v1/traces").

-record(state, {protocol :: grpc | http_protobuf | http_json,
-type headers() :: [{unicode:chardata(), unicode:chardata()}].
-type scheme() :: http | https | "http" | "https" | <<"http">> | <<"https">>.
tsloughter marked this conversation as resolved.
Show resolved Hide resolved
-type host() :: unicode:chardata().
-type endpoint() :: uri_string:uri_string() | uri_string:uri_map() | #{scheme := scheme(),
host := host(),
port => integer(),
ssl_options => []}.
-type protocol() :: grpc | http_protobuf | http_json.

-type opts() :: #{endpoints => [endpoint()],
headers => headers(),
protocol => protocol()}.

-export_type([opts/0,
headers/0,
endpoint/0,
protocol/0]).

-record(state, {protocol :: protocol(),
channel_pid :: pid() | undefined,
headers :: [{unicode:chardata(), unicode:chardata()}],
headers :: headers(),
grpc_metadata :: map() | undefined,
endpoints :: [uri_string:uri_map()]}).

%% @doc Initialize the exporter based on the provided configuration.
init(Opts0) ->
Opts1 = merge_with_environment(Opts0),
-spec init(opts()) -> {ok, #state{}}.
init(Opts) ->
Opts1 = merge_with_environment(Opts),
Endpoints = endpoints(maps:get(endpoints, Opts1, ?DEFAULT_ENDPOINTS)),
Headers = headers(maps:get(headers, Opts1, [])),
case maps:get(protocol, Opts1, http_protobuf) of
Expand Down