opentelemetry-sdk.cr v0.6.2
OpenTelemetry-SDK
Click through to the Full Generated Documentation for somewhat more complete documentation.
This library implements an OpenTelemetry SDK for Crystal, using the API interfaces defined in the API shard.
As a general rule, naming conventions have been based on the standard glossary of OpenTelementry terms, as found at https://opentelemetry.io/docs/concepts/glossary/
The general architecture of the implementation is guided by this document:
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md
The TL;DR is that a TracerProvider
is used to create a Tracer
. A Span
is created inside of the context of a Tracer
, and one Span
may nest inside of another.
Full Generated Documentation
https://wyhaines.github.io/opentelemetry-sdk.cr/
A lot of documentation needs to be added. PRs would be welcome!
Discord
A Discord community for help and discussion with Crystal OpenTelemetry can be found at:
Installation
-
Add the dependency to your
shard.yml
:dependencies: opentelemetry-sdk: github: wyhaines/opentelemetry-sdk.cr
-
Run
shards install
Usage
require "opentelemetry-sdk"
Global Tracer Provider
The most common pattern for usage is to have a single global TracerProvider
that is configured early in the program's execution. One may create an explicit configuration block, which will configure a globally held TracerProvider
:
OpenTelemetry.configure do |config|
config.service_name = "my_app_or_library"
config.service_version = "1.1.1"
config.exporter = OpenTelemetry::Exporter.new(variant: :stdout)
end
One may also provision a TracerProvider
object directly:
tracer_provider = OpenTelemetry.tracer_provider("my_app_or_library", "1.1.1")
tracer_provider = OpenTelemetry.tracer_provider do |tracer|
tracer.service_name = "my_app_or_library"
tracer.service_version = "1.1.1"
end
This allows multiple providers with different configuration to be created:
provider_a = OpenTelemetry::TracerProvider.new("my_app_or_library", "1.1.1")
provider_a.exporter = OpenTelemetry::Exporter.new(variant: :stdout)
provider_b = OpenTelementry::TracerProvider.new do |config|
config.service_name = "my_app_or_library"
config.service_version = "1.1.1"
config.exporter = OpenTelemetry::Exporter.new(variant: :stdout)
end
All TracerProvider
configuration done in this way will respect OpenTelemetry SDK conventions for environment variable based configuration. Configuration delivered via environment variables supercedes configuration delivered in code. For example:
environment variables
OTEL_SERVICE_NAME="FIB ON COMMAND"
OTEL_SERVICE_VERSION="1.1.1"
OTEL_TRACES_EXPORTER="stdout"
OTEL_TRACES_SAMPLER=traceidratio
OTEL_TRACES_SAMPLER_ARG="0.10"
configuration code
OpenTelemetry.configure do |config|
config.service_name = "Fibonacci Server"
config.service_version = Fibonacci::VERSION
config.exporter = OpenTelemetry::Exporter.new(variant: :http) do |exporter|
exporter = exporter.as(OpenTelemetry::Exporter::Http)
exporter.endpoint = "https://otlp.nr-data.net:4318/v1/traces"
headers = HTTP::Headers.new
headers["api-key"] = ENV["NEW_RELIC_LICENSE_KEY"]?.to_s
exporter.headers = headers
end
end
In the above code, the code specifies a default set of configuration, which includes setting up an exporter to send traces to New Relic. The environment variable based configuration will override that configuration, however, and will instead setup a Stdout exporter with a sampler that only sends 10% of the traces to the exporter.
If one knows that one will be depending on environment variable based configuration, the initial configuration of the OpenTelemetry library can be simplified down to:
OpenTelemetry.configure
The SDK will support the full range of environment variable based configuration (https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md), but currently only a minimal subset is supported:
- OTEL_SERVICE_NAME
- OTEL_SERVICE_VERSION
- OTEL_SCHEMA_URL
- OTEL_TRACES_SAMPLER
- OTEL_TRACES_SAMPLER_ARG
- OTEL_TRACES_EXPORTER
Getting a Tracer From a Provider Object
Most typically, when using a default TracerProvider
, the SDK will be leveraged to produce a Tracer like so:
OpenTelemetry.tracer.in_span("I am a span") do |span|
span.set_attribute("key1", "value1")
span.set_attribute("key2", "value2")
span.set_attribute("key3", "value3")
do_some_work
end
If one wishes to override the configuration held by a TracerProvider
when creating a Tracer
, new configuration can be provided in the #tracer
method call:
tracer = provider_a.tracer("microservice foo", "1.2.3") # Override the configuration
tracer = provider_a.tracer do |tracer|
tracer.service_name = "microservice foo"
tracer.service_version = "1.2.3"
end
This new configuration only applies to the specific Tracer
instance created. It does not alter the TracerProvider
configuration.
Creating Spans Using a Tracer
tracer.in_span("request") do |span|
span.set_attribute("verb", "GET")
span.set_attribute("url", "http://example.com/foo")
span.add_event("dispatching to handler")
tracer.in_span("handler") do |child_span|
child_span.add_event("handling request")
tracer.in_span("db") do |child_span|
child_span.add_event("querying database")
end
end
end
Development
If you want to help with development, fork this repo. Do your work in a branch inside your fork, and when it is ready (and has specs), submit a PR. See Contributing below.
If you have a question or find an issue, you can start a discussion or create an issue.
Contributing
- Fork it (https://github.com/wyhaines/opentelemetry-sdk.cr/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Kirk Haines - creator and maintainer
opentelemetry-sdk.cr
- 8
- 1
- 1
- 5
- 10
- about 1 month ago
- May 2, 2022
Apache License 2.0
Sun, 17 Nov 2024 21:01:39 GMT