Module: Dash0::OpenTelemetry::Resource::ServiceNameFallback

Extended by:
ServiceNameFallback
Included in:
ServiceNameFallback
Defined in:
lib/dash0/opentelemetry/resource/service_name_fallback.rb

Overview

Resource detector that provides a fallback service.name when none has been configured, derived from the application's own identity.

Because the distribution boots at interpreter startup via RUBYOPT, the program name is usually the wrapper the container runs (bundle, puma, rackup), not the application. Sampling that would report every Ruby service under the same meaningless name, so instead we read the app's identity from its project files, best signal first:

1. `config/application.rb` / `config/app.rb` `module <Name>` — Rails, Hanami
2. `config.ru` — the `run <AppClass>` target or an inline app class
 (modular Sinatra, Roda, plain Rack, single-file Rails)
3. the entry script name, when it is not a known wrapper

When none of these yields a name (e.g. a classic Sinatra app run through a wrapper), we return nil and let the SDK's unknown_service stand — honest absence beats a wrapper's name.

The fallback is skipped when a service name is already configured via OTEL_SERVICE_NAME or a service.name in OTEL_RESOURCE_ATTRIBUTES, or when opted out with DASH0_AUTOMATIC_SERVICE_NAME=false.

OpenTelemetry::SDK must be loaded before detect is called.

Constant Summary collapse

AUTOMATIC_SERVICE_NAME_ENV =
'DASH0_AUTOMATIC_SERVICE_NAME'
SERVICE_NAME_KEY =
'service.name'
APP_MODULE_FILES =

Files whose top-level module <Name> names the application (Rails, Hanami).

['config/application.rb', 'config/app.rb'].freeze
CONFIG_RU =
'config.ru'
PROJECT_MARKERS =

Any of these in a directory marks it as a plausible application root.

(APP_MODULE_FILES + [CONFIG_RU, 'Gemfile']).freeze
MAX_ROOT_WALK =

How far up from the working directory to look for the application root.

4
MAX_CONFIG_BYTES =

Config files are tiny; cap the read so a pathological file can't stall boot.

64 * 1024
WRAPPER_EXECUTABLES =

Program names that are wrappers/launchers rather than the application, so they carry no service identity and must not be used as a name.

%w[
  bundle bundler rake rackup ruby irb spring rails
  puma unicorn thin falcon sidekiq resque foreman
].freeze
FRAMEWORK_GENERICS =

A run <X> / class < <X> target whose leading constant is one of these is a framework generic (run Rails.application, run Sinatra::Application), not the app's own name, so it is not a usable signal.

%w[Rails Sinatra Hanami Rack].freeze

Instance Method Summary collapse

Instance Method Details

#detectObject

The detector interface: the only public method.



61
62
63
64
65
66
# File 'lib/dash0/opentelemetry/resource/service_name_fallback.rb', line 61

def detect
  attributes = {}
  name = fallback_service_name
  attributes[SERVICE_NAME_KEY] = name if name
  ::OpenTelemetry::SDK::Resources::Resource.create(attributes)
end