Last active
November 23, 2021 21:05
-
-
Save stevenharman/c375529f1c3ddbdc7886a66a2ea275e5 to your computer and use it in GitHub Desktop.
A very thin wrapper for consistently configuring Ruby components for exporting OpenTelemetry tracing to Honeycomb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Telemetry.configure do |c| | |
c.component = ENV.fetch("COMPONENT_NAME") | |
c.environment = ENV.fetch("APP_ENV") | |
c.deployment_environment = ENV.fetch("DEPLOYMENT_ENVIRONMENT") | |
c.honeycomb_api_key = ENV.fetch("HONEYCOMB_API_KEY", nil) | |
c.honeycomb_dataset = ENV.fetch("HONEYCOMB_DATASET", nil) | |
# This is delegating through to `OpenTelemetry::SDK::Configurator#use_all` | |
c.use_all("OpenTelemetry::Instrumentation::Sidekiq" => {span_naming: :job_class}) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module Telemetry | |
ENV_SERVICE_VERSION = "HEROKU_RELEASE_VERSION" # Depends on Feature: https://devcenter.heroku.com/articles/dyno-metadata | |
ENV_HONEYCOMB_API_KEY = "HONEYCOMB_API_KEY" | |
ENV_HONEYCOMB_DATASET = "HONEYCOMB_DATASET" | |
VERSION = "0.9.0-beta" | |
def self.tracer(name = "telemetry-ruby", version = Telemetry::VERSION) | |
OpenTelemetry.tracer_provider.tracer(name, version) | |
end | |
def self.configure | |
c = Configuration.new | |
yield(c) if block_given? | |
c.configure | |
end | |
class Configuration | |
extend Forwardable | |
# Delegate the public API of SDK's Configurator to allow an escape hatch for more advanced configuration needs. | |
delegate [:logger, :logger=, :error_handler, :resource=, :service_name=, :service_version=, :use, :use_all, :add_span_processor] => :sdk_config | |
attr_accessor :component, :version | |
attr_accessor :honeycomb_api_key, :honeycomb_dataset | |
attr_reader :deployment_environment, :environment | |
def initialize(sdk_config: OpenTelemetry::SDK::Configurator.new) | |
@sdk_config = sdk_config | |
end | |
def configure(env: ENV) | |
self.honeycomb_api_key = env.fetch(ENV_HONEYCOMB_API_KEY, nil) | |
self.honeycomb_dataset = env.fetch(ENV_HONEYCOMB_DATASET, nil) | |
self.environment = "development" | |
self.deployment_environment = environment | |
sdk_config.service_version = env.fetch(ENV_SERVICE_VERSION, "v0-dev") | |
yield(self) if block_given? | |
sdk_config.service_name = "#{component} - #{deployment_environment}" | |
sdk_config.resource = OpenTelemetry::SDK::Resources::Resource.create( | |
"service.component" => component, | |
OpenTelemetry::SemanticConventions::Resource::DEPLOYMENT_ENVIRONMENT => deployment_environment | |
) | |
enable_honeycomb if honeycomb_api_key.present? && honeycomb_dataset.present? | |
enable_development_mode if development? | |
enable_test_mode if test? | |
sdk_config.configure | |
rescue | |
# This error handling is roughly equivalent to what the OpenTelementry::SDK itself does. | |
# see: https://github.com/open-telemetry/opentelemetry-ruby/blob/9428b4e7df915f6bf062445fa6de7fb921cc7a44/sdk/lib/opentelemetry/sdk.rb#L67-L72 | |
begin | |
raise OpenTelemetry::SDK::ConfigurationError | |
rescue OpenTelemetry::SDK::ConfigurationError => e | |
OpenTelemetry.handle_error(exception: e, message: "unexpected configuration error due to #{e.cause}") | |
end | |
end | |
def deployment_environment=(value) | |
@deployment_environment = String(value) | |
end | |
def environment=(value) | |
@environment = String(value) | |
end | |
private | |
attr_reader :sdk_config | |
def enable_development_mode | |
console_exporter = OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new | |
add_span_processor(OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(console_exporter)) | |
end | |
def enable_honeycomb | |
oltp_exporter = OpenTelemetry::Exporter::OTLP::Exporter.new( | |
endpoint: "https://api.honeycomb.io:443/v1/traces", | |
headers: { | |
"x-honeycomb-team" => honeycomb_api_key, | |
"x-honeycomb-dataset" => honeycomb_dataset | |
}, | |
compression: "gzip" | |
) | |
batch_processor = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(oltp_exporter) | |
sdk_config.add_span_processor(batch_processor) | |
end | |
def enable_test_mode | |
in_memory_exporter = OpenTelemetry::SDK::Trace::Export::InMemorySpanExporter.new(recording: false) | |
sdk_config.add_span_processor(OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(in_memory_exporter)) | |
# Quiet the Info/Warn log lines generated by #use_all | |
# There must be a better way to do this so we don't have to silence warnings. | |
sdk_config.logger.level = Logger::ERROR | |
end | |
def development? | |
environment == "development" | |
end | |
def test? | |
environment == "test" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment