ruby的opentelemetry的resource
TL;DR
- resource用于描述“产生otel数据的实体”的一些属性
- 可以通过
OTEL_RESOURCE_ATTRIBUTES
配置额外的resource属性 - 也可以在配置sdk时,通过
c.resource = OpenTelemetry::SDK::Resources::Resource.create({})
添加属性 - 还有
c.service_name=
和c.service_version=
OpenTelemetry::SDK.configure
所配置的resource,会用来创建TracerProvider
,然后TracerProvider
产生span时,会使用这个resource
什么是resource
- Resource SDK | OpenTelemetry
- Configuring OpenTelemetry in Ruby | Scout APM Blog
- resource用于描述“产生otel数据的实体”的一些属性
环境变量OTELRESOURCEATTRIBUTES
搜索
OTEL_RESOURCE_ATTRIBUTES
,可见位于 opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/resources/resource.rb打印其调用栈
def telemetry_sdk
+ pp caller
resource_attributes = {
# ...
}
resource_pairs = ENV['OTEL_RESOURCE_ATTRIBUTES']
return create(resource_attributes) unless resource_pairs.is_a?(String)
# ...
create(resource_attributes)
end
得
[".../opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/resources/resource.rb:34:in `default'",
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry/exporter/zipkin/transformer.rb:37:in `'",
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry/exporter/zipkin/transformer.rb:12:in `'",
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry/exporter/zipkin/transformer.rb:10:in `'",
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry/exporter/zipkin/transformer.rb:9:in `'",
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry/exporter/zipkin/transformer.rb:8:in `'",
# ...
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry/exporter/zipkin.rb:25:in `'",
# ...
".../opentelemetry-exporter-zipkin-0.21.0/lib/opentelemetry-exporter-zipkin.rb:7:in `'",
# ...
".../bundler.rb:114:in `require'",
".../config/application.rb:16:in `'",
# ...
"bin/rails:4:in `'"]
回到代码
# opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/resources/resource.rb
def default
@default ||= create(SemanticConventions::Resource::SERVICE_NAME => 'unknown_service').merge(process).merge(telemetry_sdk).merge(service_name_from_env)
end
def process
resource_attributes = {
SemanticConventions::Resource::PROCESS_PID => Process.pid,
# ...
}
create(resource_attributes)
end
def telemetry_sdk
resource_attributes = {
# ...
}
resource_pairs = ENV['OTEL_RESOURCE_ATTRIBUTES']
return create(resource_attributes) unless resource_pairs.is_a?(String)
# ...
create(resource_attributes)
end
def service_name_from_env
service_name = ENV['OTEL_SERVICE_NAME']
create(SemanticConventions::Resource::SERVICE_NAME => service_name) unless service_name.nil?
end
可见resource在创建时会收集进程ID、环境变量(如
OTEL_RESOURCE_ATTRIBUTES
)添加属性
除了用
OTEL_RESOURCE_ATTRIBUTES
配置属性,还可以在配置sdk时,手动merge。例如:OpenTelemetry::SDK.configure do |c|
c.add_span_processor(
# ...
)
c.resource = OpenTelemetry::SDK::Resources::Resource.create({
OpenTelemetry::SemanticConventions::Resource::SERVICE_NAMESPACE => 'tracing',
# ...
})
end
源码如下,虽然是
=
,但其实是merge
# opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/configurator.rb
module OpenTelemetry
module SDK
class Configurator
def initialize
# ...
@resource = Resources::Resource.default
end
def resource=(new_resource)
@resource = @resource.merge(new_resource)
end
end
end
end
其他修改方式
观察configurator的代码,发现还有
service_name=
和service_version=
# opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/configurator.rb
def service_name=(service_name)
self.resource = OpenTelemetry::SDK::Resources::Resource.create(
OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => service_name
)
end
def service_version=(service_version)
self.resource = OpenTelemetry::SDK::Resources::Resource.create(
OpenTelemetry::SemanticConventions::Resource::SERVICE_VERSION => service_version
)
end
resource的使用
configurator执行时,会用resource创建
TracerProvider
# opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/configurator.rb
def configure
# ...
OpenTelemetry.tracer_provider = tracer_provider
install_instrumentation
end
private
def tracer_provider
@tracer_provider ||= Trace::TracerProvider.new(resource: @resource)
end
然后
TracerProvider
产生span时,会使用这个resource# opentelemetry-sdk-1.2.0/lib/opentelemetry/sdk/trace/tracer_provider.rb
def internal_start_span(name, kind, attributes, links, start_timestamp, parent_context, instrumentation_scope) # rubocop:disable Metrics/MethodLength
# ...
if result.recording? && !@stopped
# ...
Span.new(
# ...
@resource,
instrumentation_scope
)
else
OpenTelemetry::Trace.non_recording_span(OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, tracestate: result.tracestate))
end
end