Skip to content

Commit

Permalink
Merge pull request #342 from tsloughter/cut-1.0.0
Browse files Browse the repository at this point in the history
Cut 1.0.0
  • Loading branch information
tsloughter authored Jan 4, 2022
2 parents 1b90aa7 + 1a42d7f commit f12732d
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 110 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## 1.0.0 - 2022-01-03

### [SDK]

#### Fixed

- [SDK will continue to try initializing exporter if it fails to resolve startup
ordering issues](https://github.com/open-telemetry/opentelemetry-erlang/pull/338)
- [elixir span docs: fix reference to attributes
type](https://github.com/open-telemetry/opentelemetry-erlang/pull/336)

### [API]

#### Fixed

- [events: accept map for attributes on an event](https://github.com/open-telemetry/opentelemetry-erlang/pull/335)

### [Exporter]

#### Added
Expand Down
142 changes: 80 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,81 @@ OpenTelemetry
[![EEF Observability WG project](https://img.shields.io/badge/EEF-Observability-black)](https://github.com/erlef/eef-observability-wg)
![Build Status](https://github.com/open-telemetry/opentelemetry-erlang/workflows/Common%20Test/badge.svg)

OpenTelemetry distributed tracing framework for Erlang.
[OpenTelemetry](https://opentelemetry.io/) distributed tracing framework for
Erlang and Elixir.

Requires OTP 21.3 or above.
These applications implement version 1.8.0 of the [OpenTelemetry
Specification](https://github.com/open-telemetry/opentelemetry-specification),
see the [spec compliance
matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md)
for a list of features supported.

## Requirements

- OTP 21.3+

If using the Elixir API:

- Elixir 1.8+

## Contacting Us

We hold weekly meetings. See details at [community page](https://github.com/open-telemetry/community#special-interest-groups).

We use [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-erlang/discussions) for support or general questions. Feel free to drop us a line.
We use [GitHub
Discussions](https://github.com/open-telemetry/opentelemetry-erlang/discussions)
for support or general questions. Feel free to drop us a line.

We are also present in the #otel-erlang-elixir channel in the [CNCF
slack](https://slack.cncf.io/). Please join us for more informal discussions.

You can also find us in the #opentelemetry channel on [Elixir Slack](https://elixir-slackin.herokuapp.com/).
You can also find us in the #opentelemetry channel on [Elixir
Slack](https://elixir-slackin.herokuapp.com/).

## Design

The [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification) defines a language library as having 2 components, the API and the SDK. The API must not only define the interfaces of any implementation in that language but also be able to function as a noop implementation of the tracer. The SDK is the default implementation of the API that must be optional.
The [OpenTelemetry
specification](https://github.com/open-telemetry/opentelemetry-specification)
defines a language library as having 2 components, the API and the SDK. The API
must not only define the interfaces of any implementation in that language but
also be able to function as a noop implementation of the tracer. The SDK is the
default implementation of the API that must be optional.

When instrumenting a project your application should only depend on the
[OpenTelemetry API](https://hex.pm/packages/opentelemetry_api) application,
found in directory `apps/opentelemetry_api` of this repo which is published as
the hex package [opentelemetry_api](https://hex.pm/packages/opentelemetry_api).

This repository is the Erlang's SDK implementation and should be included in the final release and configured to setup the sampler, span processors and span exporters.
The SDK implementation, found under `apps/opentelemetry` and hex package
[opentelemetry](https://hex.pm/packages/opentelemetry), should be included in an
OTP Release along with an exporter.

## Usage

### Hex Dependencies

It is recommended to use the versions published on hex.pm for [OpenTelemetry
API](https://hex.pm/packages/opentelemetry_api), [OpenTelemetry
SDK](https://hex.pm/packages/opentelemetry) and the [OpenTelemetry
Exporter](https://hex.pm/packages/opentelemetry_exporter).

### Git Dependencies

Because the OpenTelemetry OTP Applications are kept in a single repository,
under the directory `apps`, either [rebar3's](https://rebar3.org) `git_subdir`
(rebar 3.14 or above is required) or
[mix's](](https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html))
`sparse` feature must be used when using as Git dependencies in a project. The
blocks below shows how in rebar3 and mix the git repo for the API and/or SDK
Applications can be used.
Example of Release configuration in `rebar.config`:

``` erlang
{opentelemetry_api, {git_subdir,
"http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"}, "apps/opentelemetry_api"}}
{opentelemetry, {git_subdir,
"http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"}, "apps/opentelemetry"}}
```
{relx, [{release, {my_instrumented_release, "0.1.0"},
[opentelemetry_exporter,
{opentelemetry, temporary},
my_instrumented_app]},

``` elixir
{:opentelemetry_api, github: "open-telemetry/opentelemetry-erlang", sparse:
"apps/opentelemetry_api", override: true},
{:opentelemetry, github: "open-telemetry/opentelemetry-erlang", sparse: "apps/opentelemetry", override: true},
...]}.
```

The `override: true` is required because the SDK Application, `opentelemetry`, has
the API in its `deps` list of its `rebar.config` as a hex dependency and this will
clash when `mix` tries to resolve the dependencies and fail without the
override. `override: true` is also used on the SDK because the
`opentelemetry_exporter` application depends on it and the API as hex deps so if
it is included the override is necessary.

### Including in Release
Example configuration for [mix's Release
task](https://hexdocs.pm/mix/Mix.Tasks.Release.html):

In an Erlang project add `opentelemetry_exporter` and `opentelemetry` as the
first elements of the release's applications:
``` elixir
def project do
[
releases: [
my_instrumented_release: [
applications: [:runtime_tools, :opentelemetry_exporter, {:opentelemetry, :temporary}, :my_instrumented_app]
],

``` erlang
{relx, [{release, {<name>, <version>},
[opentelemetry_exporter,
{opentelemetry, temporary},
<your applications>]},
...]}.
...
]
]
end
```

In the above example `opentelemetry_exporter` is first to ensure all of its
Expand All @@ -93,23 +92,42 @@ the processes started by the root supervisor to leave it up to the end user
whether they want the crash or shutdown or `opentelemetry` to be ignored or
cause the shutdown of the rest of the applications in the release.

Doing the same for an Elixir project would be:
## Git Dependencies

``` elixir
def project do
[
...
releases: [
<name>: [
applications: [:opentelemetry_exporter, opentelemetry: :temporary]
],
While it is recommended to use the Hex packages for the
[API](https://hex.pm/packages/opentelemetry_api),
[SDK](https://hex.pm/packages/opentelemetry) and [OTLP
exporter](https://hex.pm/packages/opentelemetry_exporter), there are times
depending on the git repo is necessary. Because the OpenTelemetry OTP
Applications are kept in a single repository, under the directory `apps`, either
[rebar3's](https://rebar3.org) `git_subdir` (rebar 3.14 or above is required) or
[mix's](https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html)
`sparse` feature must be used when using as Git dependencies in a project. The
blocks below shows how in rebar3 and mix the git repo for the API and/or SDK
Applications can be used.

...
]
]
end
``` erlang
{opentelemetry_api, {git_subdir, "http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"}, "apps/opentelemetry_api"}},
{opentelemetry, {git_subdir, "http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"},
"apps/opentelemetry"}},
{opentelemetry_exporter, {git_subdir, "http://github.com/open-telemetry/opentelemetry-erlang", {branch, "main"}, "apps/opentelemetry_exporter"}}
```

``` elixir
{:opentelemetry_api, github: "open-telemetry/opentelemetry-erlang", sparse:
"apps/opentelemetry_api", override: true},
{:opentelemetry, github: "open-telemetry/opentelemetry-erlang", sparse:
"apps/opentelemetry", override: true},
{:opentelemetry_exporter, github: "open-telemetry/opentelemetry-erlang", sparse: "apps/opentelemetry_exporter", override: true}
```

The `override: true` is required because the SDK Application, `opentelemetry`, has
the API in its `deps` list of its `rebar.config` as a hex dependency and this will
clash when `mix` tries to resolve the dependencies and fail without the
override. `override: true` is also used on the SDK because the
`opentelemetry_exporter` application depends on it and the API as hex deps so if
it is included the override is necessary.

## Benchmarks

Running benchmarks is done with [benchee](https://github.com/bencheeorg/benchee). Benchmark functions are in modules under `samples/`. To run them open a rebar3 shell in the `bench` profile:
Expand Down
2 changes: 1 addition & 1 deletion apps/opentelemetry/rebar.config
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
{erl_opts, [debug_info]}.
{deps, [{opentelemetry_api, "~> 1.0.0-rc.4"}]}.
{deps, [{opentelemetry_api, "~> 1.0.0"}]}.
54 changes: 19 additions & 35 deletions apps/opentelemetry_api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,14 @@
[![EEF Observability WG project](https://img.shields.io/badge/EEF-Observability-black)](https://github.com/erlef/eef-observability-wg)
[![Hex.pm](https://img.shields.io/hexpm/v/opentelemetry)](https://hex.pm/packages/opentelemetry_api)

This is the API portion of [OpenTelemetry](https://opentelemetry.io/) for Erlang and Elixir Applications.
This is the API portion of [OpenTelemetry](https://opentelemetry.io/) for Erlang
and Elixir Applications, implementing the API portion of [the specification](https://github.com/open-telemetry/opentelemetry-specification).

This is a library, it does not start any processes, and should be the only OpenTelemetry dependency of Erlang/Elixir Applications.

The end user of your Application can then choose to include the [OpenTelemetry implementation](https://github.com/open-telemetry/opentelemetry-erlang) Application. If the implementation Application is not in the final release the OpenTelemetry instrumentation will all be no-ops. This means no processes started, no ETS tables created and nothing added to the process dictionary.

This separation is done so you should feel comfortable instrumenting your Erlang/Elixir Application with OpenTelemetry and not worry that a complicated dependency is being forced on your users.
This is a library, it does not start any processes, and should be the only
OpenTelemetry dependency of Erlang/Elixir Applications.

## Use

When instrumenting an Application to be used as a dependency of other projects it is best practice to register a `Tracer` with a name and a version using the Application's name and version. This should be the name and version of the Application that has the `opentelemetry` calls being written in it, not the name of the Application it might be being used to instrument. For example, an [Elli](https://github.com/elli-lib/elli) middleware to add tracing to the Elli HTTP server would *not* be named `elli`, it would be the name of the middleware Application, like `opentelemetry_elli`.

Registration is done through a single process and uses a [persistent_term](https://erlang.org/doc/man/persistent_term.html), so should be done only once per-Application. Updating a registration is allowed, so updating the version on a release upgrade can, and should, be done, but will involve the performance penalty of updating a [persistent_term](https://erlang.org/doc/man/persistent_term.html).

Naming the `Tracers` provides additional metadata on spans and allows the user of your Application to disable the traces from the dependency if it is needed.

### Dependency in Elixir

``` elixir
def deps do
[
{:opentelemetry_api, "~> 0.6.0"}
]
end
```

### Helper Macros for Application Tracers

There are both Erlang and Elixir macros that make use of the current module's
name to lookup a Named Tracer -- a Named Tracer is created for each Application
loaded in the system at start time -- for you and can be used for Trace and Span
Expand Down Expand Up @@ -63,24 +43,28 @@ end

### Including the OpenTelemetry SDK

For traces to actually be tracked, propagated and exported, the [opentelemetry](https://github.com/open-telemetry/opentelemetry-erlang) Application must be included as a dependency of your project, likely as part of a [Release](https://erlang.org/doc/design_principles/release_structure.html) and not as a dependency of an individual Application within the Release.

See the [Using section](https://github.com/open-telemetry/opentelemetry-erlang#using) of the [OpenTelemetry-Erlang](https://github.com/open-telemetry/opentelemetry-erlang) repository for details.
When only the API is available at runtime a no-op Tracer is used and no Traces
are exported. The [OpenTelemetry SDK](https://hex.pm/packages/opentelemetry)
provides the functionality of Tracers, Span Processors and Exporters and should
be included as part of a
[Release](https://erlang.org/doc/design_principles/release_structure.html) and
not as a dependency of any individual Application.

### Exporters

Exporters can be found as separate Applications on Github under the [OpenTelemetry Beam Organization](https://github.com/opentelemetry-beam).
Included in the same [Github
repo](https://github.com/open-telemetry/opentelemetry-erlang) as the API and SDK are an exporter for the [OpenTelemetry Protocol
(OTLP)](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md)
and [Zipkin](https://zipkin.io/):

- [OpenTelemetry Protocol](https://hex.pm/packages/opentelemetry_exporter)
- [Zipkin](https://hex.pm/packages/opentelemetry_zipkin)
- [OpenTelemetry Collector](https://hex.pm/packages/opentelemetry_exporter)

### HTTP Integrations

- [Elli](https://hex.pm/packages/opentelemetry_elli)

### Database Client Integration
### Integrations

- [Ecto](https://hex.pm/packages/opentelemetry_ecto)
Instrumentations of many popular Erlang and Elixir projects can be found in the
[contrib repo](https://github.com/open-telemetry/opentelemetry-erlang-contrib)
and on [hex.pm](https://hex.pm) under the [OpenTelemetry organization](https://hex.pm/orgs/opentelemetry).

## Contributing

Expand Down
2 changes: 1 addition & 1 deletion apps/opentelemetry_api/src/opentelemetry_api.app.src
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{application, opentelemetry_api,
[{description, "OpenTelemetry API"},
{vsn, "1.0.0-rc.4.1"},
{vsn, "1.0.0"},
{registered, []},
{applications,
[kernel,
Expand Down
17 changes: 12 additions & 5 deletions apps/opentelemetry_exporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
The OpenTelemetry Protocol exporter for use with the [OpenTelemetry
Collector](https://github.com/open-telemetry/opentelemetry-collector). The
version of this Application does not track the supported version of the
OpenTelemetry Protocol (OTLP) . The currently used version of the [OTLP protobufs
OpenTelemetry Protocol (OTLP). The currently used version of the [OTLP protobufs
is v0.11.0](https://github.com/open-telemetry/opentelemetry-proto/tree/v0.11.0).

Currently only supports the Tracer protocol using either GRPC or Protobuffers over HTTP1.1.
Expand All @@ -12,7 +12,8 @@ Currently only supports the Tracer protocol using either GRPC or Protobuffers ov

### Options to Batch Processor

Easiest way to setup is to add configuration for the batch processor in OpenTelemetry application environment.
Exporter configuration can be done as arguments to the batch processor in
the OpenTelemetry application environment.

For an Erlang release in `sys.config`:

Expand All @@ -25,7 +26,8 @@ For an Erlang release in `sys.config`:
headers => [{"x-honeycomb-dataset", "experiments"}]}}}}]}]}
```

The default protocol is `http_protobuf`, to override this and use grpc add `protocol` to the config map:
The default protocol is `http_protobuf`, to override this and use grpc add
`protocol` to the config map:

``` erlang
{opentelemetry,
Expand All @@ -48,6 +50,9 @@ config :opentelemetry, :processors,

### Application Environment

Alternatively the `opentelemetry_exporter` Application can be configured itself.
Available configuration keys:

- `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.
Expand Down Expand Up @@ -75,8 +80,7 @@ config :opentelemetry_exporter,
otlp_endpoint: "https://api.honeycomb.io:443",
otlp_headers: [{"x-honeycomb-dataset", "experiments"}]
```



The default SSL options for HTTPS requests are set using
[tls_certificate_check](https://hex.pm/packages/tls_certificate_check). This
package also provides the [CA certificates from Mozilla](https://curl.se/docs/caextract.html).
Expand All @@ -91,6 +95,9 @@ for more information on securing HTTP requests in Erlang.

### OS Environment

Lastly, configuring the exporter can be done with OS environment variables,
which take precedence:

- `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.
Expand Down
4 changes: 2 additions & 2 deletions apps/opentelemetry_exporter/rebar.config
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{erl_opts, [debug_info]}.
{deps, [{grpcbox, ">= 0.0.0"},
{tls_certificate_check, "~> 1.11"},
{opentelemetry, "~> 1.0.0-rc.4"},
{opentelemetry_api, "~> 1.0.0-rc.4"}]}.
{opentelemetry, "~> 1.0"},
{opentelemetry_api, "~> 1.0"}]}.

{grpc, [{protos, ["opentelemetry-proto/opentelemetry/proto/collector/trace/v1"]},
{gpb_opts, [{module_name_prefix, "opentelemetry_exporter_"},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{application, opentelemetry_exporter,
[{description, "OpenTelemetry Protocol Exporter"},
{vsn, "1.0.0-rc.4"},
{vsn, "1.0.0"},
{registered, []},
{applications,
[kernel,
Expand Down
4 changes: 2 additions & 2 deletions apps/opentelemetry_zipkin/rebar.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{erl_opts, [debug_info]}.
{deps, [{opentelemetry, "~> 1.0.0-rc.4"},
{opentelemetry_api, "~> 1.0.0-rc.4"}]}.
{deps, [{opentelemetry, "~> 1.0"},
{opentelemetry_api, "~> 1.0"}]}.

{profiles, [{test, [{erl_opts, [nowarn_export_all]}]},

Expand Down
2 changes: 1 addition & 1 deletion docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ set -e

rebar3 compile
rebar3 edoc
version=1.0.0-rc.4
version=1.0.0

ex_doc "opentelemetry" $version "_build/default/lib/opentelemetry/ebin" \
--source-ref v${version} \
Expand Down

0 comments on commit f12732d

Please sign in to comment.