-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: OpenTelemetry.logger_provider API, ProxyLoggers, Configuration, and Instrument Registry #1725
feat: OpenTelemetry.logger_provider API, ProxyLoggers, Configuration, and Instrument Registry #1725
Conversation
Create a registry for loggers to make sure a logger with an identical name and version is created only once and reused
When OTLP logs exporter not installed, rescue the error, emit a message and set the exporter to nil.
…pentelemetry-ruby into logs-configuration-patch
# @return [ProxyLogger] | ||
def initialize | ||
super | ||
@mutex = Mutex.new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a mutex here? We don't have it for the proxy tracer. I believe we can remove this because the delegate is set from proxy logger provider, which synchronizes access using its mutex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question! I don't think we need it here. I was copying the setup in the ProxyMeter and didn't cross-reference what was going on with the ProxyTracer.
Should we remove the mutex from the ProxyMeter too?
def delegate=(meter) | |
@mutex.synchronize do | |
if @delegate.nil? | |
@delegate = meter | |
@instrument_registry.each_value { |instrument| instrument.upgrade_with(meter) } | |
else | |
OpenTelemetry.logger.warn 'Attempt to reset delegate in ProxyMeter ignored.' | |
end | |
end | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to align the three. For the purposes of this PR we can remove it from the proxy logger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Updated in 9e2b8ee
@@ -34,14 +39,21 @@ def initialize(resource: OpenTelemetry::SDK::Resources::Resource.create) | |||
# | |||
# @return [OpenTelemetry::SDK::Logs::Logger] | |||
def logger(name:, version: nil) | |||
version ||= '' | |||
if @stopped |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this case necessary? I ask because it differs from what we're doing in the TracerProvider
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a minute since I wrote this, but I believe I did it to adhere to this part of the shutdown protocol:
Shutdown
MUST be called only once for eachLoggerProvider
instance. After
the call toShutdown
, subsequent attempts to get aLogger
are not allowed.
SDKs SHOULD return a valid no-opLogger
for these calls, if possible.
There's similar verbiage for the Trace SDK.
I'm not sure if we adhere to this part of the Trace spec elsewhere. Maybe this part does the job well enough? But I'm not sure if that would sufficiently covers an attempt to get a tracer after shutdown.
opentelemetry-ruby/sdk/lib/opentelemetry/sdk/trace/tracer_provider.rb
Lines 72 to 75 in a1f1629
if @stopped | |
OpenTelemetry.logger.warn('calling Tracer#shutdown multiple times.') | |
return Export::FAILURE | |
end |
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the other piece of the puzzle (for traces) is here:
opentelemetry-ruby/sdk/lib/opentelemetry/sdk/trace/tracer_provider.rb
Lines 146 to 167 in a1f1629
if result.recording? && !@stopped | |
trace_flags = result.sampled? ? OpenTelemetry::Trace::TraceFlags::SAMPLED : OpenTelemetry::Trace::TraceFlags::DEFAULT | |
context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, trace_flags: trace_flags, tracestate: result.tracestate) | |
attributes = attributes&.merge(result.attributes) || result.attributes.dup | |
Span.new( | |
context, | |
parent_context, | |
parent_span, | |
name, | |
kind, | |
parent_span_id, | |
@span_limits, | |
@span_processors, | |
attributes, | |
links, | |
start_timestamp, | |
@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 |
My interpretation of the spec is that after calling shutdown on a tracer provider all tracers issued by it, past or future, must be non-operational. That is, they will create no-op spans from there on out. They do not necessarily need to be an instance of a no-op tracer, if that makes sense.
I think we need to ensure that all loggers return early from on_emit
after shutdown
is called, then it doesn't really matter what kind of logger we return from the logger provider. For consistency, we can follow what we're doing for tracing. I'm open to other considerations though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't thought about it that way! Thanks for breaking that down. I've updated the code to use this approach. See: 06e4b05
Previously, a no-op Logger was returned when LoggerProvider#logger was called after the provider was stopped. Now, when the provider is stopped, the on_emit method will return early and not emit any log records. This more closely follows the behavior in the TracerProvider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR has a few different features that are all somewhat related:
OpenTelemetry.logger_provider
OpenTelemetry::Internal::ProxyLoggerProvider
andOpenTelemetry::Internal::ProxyLogger
classes for defaults.OTEL_LOGS_EXPORTER
. The options available areconsole
,none
, andotlp
. The OTLP exporter option will fail gracefully unless the yet to be releasedopentelemetry-exporter-otlp-logs
gem is available. This takes the ConfigurationPatch approach, similar to feat: Update metrics configuration patch #1548Closes #1699
Closes #1702