opentelemetry-specification icon indicating copy to clipboard operation
opentelemetry-specification copied to clipboard

SDK forces OTLP exporter when OTEL_TRACES_EXPORTER is undefined

Open weyert opened this issue 2 years ago • 9 comments

What are you trying to achieve? I am trying to get the none behaviour when OTEL_TRACES_EXPORTER is not defined but currently it forces the OTLP-exporter instead which is unexpected.

What did you expect to see? I would like to be able to control the expected behaviour when the environment variable OTEL_TRACES_EXPORTER is not defined. I would like to have a no-op exporter in this case

Additional context. I am using Google Tracing using their exporter and when I am developing and not happen to have the OTEL_TRACES_EXPORTER environment variable defined the Node SDK for OpenTelemetry for JavaScript is forces unexpectedly OTLP exporter instead of a no-op exporter.

I think it would be useful to no force OTLP-exporter when the environment variable is not defined or to offer a built-in noop-exporter that can be used as a fallback.

weyert avatar Dec 05 '22 14:12 weyert

Spec: https://github.com/open-telemetry/opentelemetry-specification/blob/150451d4257be3d4673c7fcbf50fca7fb557d346/specification/sdk-environment-variables.md?plain=1#L255

vmarchaud avatar Dec 05 '22 14:12 vmarchaud

Related: https://github.com/open-telemetry/opentelemetry-specification/issues/2520

My current understanding is that this is an "implicit" requirement based on what @vmarchaud quoted.

On the specific question you asked:

I think it would be useful to no force OTLP-exporter when the environment variable is not defined or to offer a built-in noop-exporter that can be used as a fallback.

From a developer's perspective this would be the right default, but for an operations' perspective the current default is much better (my telemetry gets send to a local collector OOTB, nothing to worry about)

I am wondering if there's a middle ground, like "do OTLP, but if it is not available print telemetry to the console"?

svrnm avatar Dec 05 '22 16:12 svrnm

I understand it is part of the spec but I think it would be nice to be able disable it and make it behave like none. For now, I have written a custom span exporter that doesn't do anything but in my opinion that shouldn't be necessary:

import { ExportResultCode } from '@opentelemetry/core'
import type { ExportResult } from '@opentelemetry/core'
import { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'

export class NoopSpanExporter implements SpanExporter {
  /**
   * Indicates if the exporter has been "shutdown."
   */
  protected _stopped = false

  export(_spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {
    if (this._stopped) {
      return resultCallback({
        code: ExportResultCode.FAILED,
        error: new Error('Exporter has been stopped'),
      })
    }

    setTimeout(() => resultCallback({ code: ExportResultCode.SUCCESS }), 0).unref()
  }

  shutdown(): Promise<void> {
    this._stopped = true
    return Promise.resolve()
  }
}

weyert avatar Dec 05 '22 16:12 weyert

Maybe the SDKs should support the option - OTEL_TRACES_EXPORTER=no-op, or some new disable flag. I agree that the default of otlp is very useful.

osherv avatar Dec 05 '22 18:12 osherv

Only useful when you use otel-collector or a tracing backend that supports it. A popular tracing backend like Google Trace doesn't support as far as I am aware off.

You would need to read the documentation to find out that tracing is defaulting to the otlp-backend instead of doing nothing.

weyert avatar Dec 05 '22 18:12 weyert

Maybe the SDKs should support the option - OTEL_TRACES_EXPORTER=no-op, or some new disable flag.

Its possible to use use OTEL_TRACES_EXPORTER=none right now

vmarchaud avatar Dec 05 '22 18:12 vmarchaud

Maybe the SDKs should support the option - OTEL_TRACES_EXPORTER=no-op, or some new disable flag.

Its possible to use use OTEL_TRACES_EXPORTER=none right now

oh oki

osherv avatar Dec 05 '22 18:12 osherv

I think that the combination of default settings of OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 and OTEL_TRACES_EXPORTER=otlp is quite problematic if you are building an application that anyone who is not in the OpenTelemetry ecosystem will use. Namely, the SDK will auto-setup itself on their machines, then it will complain repeatedly about being unable to export (often without specifying exactly where or what it even is). This is kinda a bad UX for people who may not know what OpenTelemetry is and/or don't intend to use it.

It seems much less onerous to just set the OTEL_TRACES_EXPORTER=otlp environment variable if exporting traces is desired.

For this reason, I wind up including something like this every time I instrument a new app (PHP edition, but it also has a Haskell edition):

        // Kinda a hack: if you are not exporting traces, disable the
        // OpenTelemetry SDK altogether, since it will otherwise default to
        // exporting to localhost:4317 over OTLP, which is a quite unreasonable
        // default.
        if (getenv('OTEL_TRACES_EXPORTER') === false) {
            putenv('OTEL_SDK_DISABLED=true');
            assert(Sdk::isDisabled());
            return;
        }

lf- avatar May 05 '23 05:05 lf-

I concur that the default settings as described in the spec seem to create a situation that could lead to user confusion if implemented exactly as specified in the spec.

Since the default exporter relies on an external service to function and will write errors to standard out (or some other logging mechanism) when it fails. While each individual default makes sense in isolation, the end result of these decisions combined creates a problematic user experience where you get an error from a component you may not even know was present.

The SDK defaults to on (makes sense), the default exporter is otlp (makes sense), and the default endpoint for otlp is localhost:4318 (makes sense). But there's no user input to make sure that tracing should have been enabled to begin with.

I'm not sure what the best change for this would be. Maybe the SDK should default to off and be explicitly enabled? Maybe OTEL_TRACES_EXPORTER should have an additional option auto that has a specified behavior and that should be the default? I'm working with buildkit right now and the default behavior there is to detect if OTEL_TRACES_EXPORTER has been specified or if the endpoint has been set. If one of these is true, it will enable tracing. If there are no environment variables related to OTEL, it leaves it off. This doesn't seem to follow the current specification though.

jsternberg avatar Mar 07 '24 21:03 jsternberg

https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md is declared stable, so I do not believe that this can be accomplished. @open-telemetry/technical-committee please take a look and decide if this has to be rejected?

svrnm avatar May 06 '24 09:05 svrnm

Discussed in the 5/15 TC meeting. The default behavior is by design and we don't have any intention of changing it to allow for different defaults. Closing.

jack-berg avatar May 15 '24 15:05 jack-berg