diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c586bd5..ee589a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index d128257b..71b7e4a3 100644 --- a/README.md +++ b/README.md @@ -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, {, }, - [opentelemetry_exporter, - {opentelemetry, temporary}, - ]}, - ...]}. + ... + ] + ] +end ``` In the above example `opentelemetry_exporter` is first to ensure all of its @@ -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: [ - : [ - 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: diff --git a/apps/opentelemetry/rebar.config b/apps/opentelemetry/rebar.config index acfe22f4..408a7dba 100644 --- a/apps/opentelemetry/rebar.config +++ b/apps/opentelemetry/rebar.config @@ -1,2 +1,2 @@ {erl_opts, [debug_info]}. -{deps, [{opentelemetry_api, "~> 1.0.0-rc.4"}]}. +{deps, [{opentelemetry_api, "~> 1.0.0"}]}. diff --git a/apps/opentelemetry_api/README.md b/apps/opentelemetry_api/README.md index 0b4d529e..b09c4fef 100644 --- a/apps/opentelemetry_api/README.md +++ b/apps/opentelemetry_api/README.md @@ -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 @@ -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 diff --git a/apps/opentelemetry_api/src/opentelemetry_api.app.src b/apps/opentelemetry_api/src/opentelemetry_api.app.src index 7c6bb6f3..294fd232 100644 --- a/apps/opentelemetry_api/src/opentelemetry_api.app.src +++ b/apps/opentelemetry_api/src/opentelemetry_api.app.src @@ -1,6 +1,6 @@ {application, opentelemetry_api, [{description, "OpenTelemetry API"}, - {vsn, "1.0.0-rc.4.1"}, + {vsn, "1.0.0"}, {registered, []}, {applications, [kernel, diff --git a/apps/opentelemetry_exporter/README.md b/apps/opentelemetry_exporter/README.md index 8768d9fd..b50308e0 100644 --- a/apps/opentelemetry_exporter/README.md +++ b/apps/opentelemetry_exporter/README.md @@ -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. @@ -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`: @@ -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, @@ -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. @@ -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). @@ -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. diff --git a/apps/opentelemetry_exporter/rebar.config b/apps/opentelemetry_exporter/rebar.config index 87c0f264..0809ab30 100644 --- a/apps/opentelemetry_exporter/rebar.config +++ b/apps/opentelemetry_exporter/rebar.config @@ -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_"}, diff --git a/apps/opentelemetry_exporter/src/opentelemetry_exporter.app.src b/apps/opentelemetry_exporter/src/opentelemetry_exporter.app.src index 86d4c263..b6a4ae9c 100644 --- a/apps/opentelemetry_exporter/src/opentelemetry_exporter.app.src +++ b/apps/opentelemetry_exporter/src/opentelemetry_exporter.app.src @@ -1,6 +1,6 @@ {application, opentelemetry_exporter, [{description, "OpenTelemetry Protocol Exporter"}, - {vsn, "1.0.0-rc.4"}, + {vsn, "1.0.0"}, {registered, []}, {applications, [kernel, diff --git a/apps/opentelemetry_zipkin/rebar.config b/apps/opentelemetry_zipkin/rebar.config index 0f7c5240..18480448 100644 --- a/apps/opentelemetry_zipkin/rebar.config +++ b/apps/opentelemetry_zipkin/rebar.config @@ -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]}]}, diff --git a/docs.sh b/docs.sh index c94324d5..0352066c 100755 --- a/docs.sh +++ b/docs.sh @@ -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} \