Skip to content

go.opentelemetry.io/otel/semconv breaks backwards compatibility guarantees #7297

@katiehockman

Description

@katiehockman

I understand that this issue has been filed in a few places (#2341, open-telemetry/opentelemetry-go-contrib#4261, #4476) but I'd like to file this one to provide some additional context.

We're designing a common library which is called near the top of main() which performs essential initialization steps such as configuring telemetry and initializing shared state. As is pretty standard procedure, this function will panic if any of the essential steps fail since that means the program is not sufficiently set up to run safely.

One such initialization step is to set up the OTel Metric Provider, with code that looks something like this:

res, err := resource.Merge(
		resource.Default(),
		resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName(cfg.serviceName),
		),
	)

if err != nil {
	return err
}

return metric.NewMeterProvider(metric.WithResource(res))

As others have said in previous issues, if we upgrade the go.opentelemetry.io/otel/sdk/metric version in the go.mod without programmatically changing the name of the go.opentelemetry.io/otel/semconv/v1.**.0 module to match the version it requires, then we will get an error. e.g.

conflicting Schema URL: https://opentelemetry.io/schemas/1.34.0 and https://opentelemetry.io/schemas/1.26.0

If it's just us doing this, and we don't have any users of our library, then that can be mitigated. But we have no control over our users upgrading versions of the otel libraries, and those users have no ability to change our code to also upgrade go.opentelemetry.io/otel/semconv at the same time, which leaves us in a tough spot. So now we are stuck choosing between one of these two options:

  1. Like with any other essential initialization step that failed, we can panic our Init() function.
    1. The risk with this is that a downstream user of our library may have renovate/dependabot set up which automatically upgrades go.opentelemetry.io/otel/sdk/* and doesn't have a test which executes our Init() function, and it won't panic until production, which is of course not safe.
  2. We can log a warning and drop the error.
    1. The risk with this is that there are unknown side effects of a merge error including dropping metrics or overwriting them. If this gets to production where there are monitors or alerts set up which require this metric then it could end up masking real production issues and causing alerts to fire incorrectly or fail to fire when they should.

What's the recommendation here? Or is there a 3rd option I'm not aware of?

The fact that the version name is part of the module name already demonstrates that this is not how Go modules are meant to work and isn't standard operating procedure. This problem stated above is one known reason why this kind of convention isn't supposed to be used in Go.

I'd like to ask that this design be reconsidered to make it easier and safer for clients to use these libraries, and to have this project follow Go's module rules and backwards compatibility guarantees.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginvalidThis doesn't seem right

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions