-
Notifications
You must be signed in to change notification settings - Fork 897
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
Support additional validation of keys and values #1490
Comments
#504 already covers span/link/event/resource attributes as well as metric labels. I suppose we will want to have the same or similar defaults and mechanism for configuring it also for baggage. |
From the code walkthrough for our implementation: INTRODUCTION XYZ Corp is adopting OpenTelemetry (https://github.com/open-telemetry/opentelemetry-specification) for context propagation (https://medium.com/jaegertracing/embracing-context-propagation-7100b9b6029a). OpenTelemetry supports traces (the entire set of calls from the first to the last), and spans (one call in the trace). OpenTelemetry also helpfully provides a way to attach "baggage" to the context that propagates through OpenTelemetry context mechanisms. (This baggage is not associated directly with any traces or spans, nor is it propagated with them, unless the appropriate propagator is enabled.) The baggage consists of a map of key/value pairs. Baggage can hold anything (up to defined limits, https://w3c.github.io/baggage/#limits). Unfortunately, with 100s of services, and without some governance, a ubiquitously available and untyped key/value map will quickly degenerate into a free-for-all dumping ground, and could even exceed the maximum sizes, bringing all festivities to a halt. This wiki documents how we plan to avoid having that happen at XYZ Corp. REQUIREMENTS
SCHEMA We are constraining the key/value pairs in the baggage to conform to a schema. Schema File The schema is defined in a text file. Each line in the schema file defines the schema for one key/value pair. The keys are simply unique names, for example "uuid" or "route". The values are constrained by regular expressions. The regular expressions are fully-specified, meaning they start with a '^' and end with a '$'. (If one or both of those are missing, they are automatically added.) The keys and regular expressions are separated by a colon. For example:
There is no need to constrain the keys (other than making sure they are unique) because OpenTelemetry makes sure they are not null or empty (or will once open-telemetry/opentelemetry-java#2948 is fixed). Loading At startup, the schema file is loaded from a resource on the classpath, parsed, and turned into an XyzBaggageSchema object:
For each line in the schema file, the parser:
The XyzBaggageKeyValueDefinition constructor performs some more work:
BUILDER We are implementing a custom baggage builder, XyzBaggageBuilder, in order to validate that only allowed fields are set:
Yes, this can be easily defeated with reflection, but by the time we are done with the end-to-end implementation, creating and populating baggage will be handled in the API gateway code, and developers outside that team will never need to see the baggage creation. Unfortunately, we have to implement our custom builder by composition, because the base BaggageBuilder is a static class that refers to fields we can't access in a non-nested subclass:
Ideally we could just register a custom validator with BaggageBuilder and not have to subclass at all, and we filed enhancement requests for that (open-telemetry/opentelemetry-java#2935 and #1490), but there's no guarantee it will ever happen. Similar to the non-custom BaggageBuilder, our custom baggage builder has static creator methods, but in our case there are two: one for when there is no existing baggage, and one for when there is existing baggage (both of our methods require an XyzBaggageSchema):
(It's safe to call the one with existingBaggage even when that is null, because the constructor returns right away for nulls.) When the existingBaggage is not null, its contents are copied to the builder held by composition in the XyzBaggageBuilder.
USAGE XyzBaggageBuilderTest.testWhileDemonstratingUseWithHeaders demonstrates how we envision our custom builder being used:
MISCELLANEOUS CODE There are only two other classes in the implementation:
|
Just one clarification/misconception I saw in your writeup:
This is not true. What OpenTelemetry does is to provide a way to attach Baggage to the context which propagates through the OpenTelemetry context mechanisms. This baggage is not associated directly with any spans or traces, nor is it propagated with them, unless the appropriate propagator is enabled. |
If you look at all of the above from the standpoint of developer friendliness, really all we need are two things:
|
Thank you for the clarification! I updated our walkthrough to be more precise. |
For long-running services, we might add an invalidation mechanism, so the service rereads the schema file and updates the in-memory schema. |
In some cases regular expressions might not be powerful/flexible enough, so it would be nice if a validator could be specified (or discovered). |
We also considered imposing the constraints in our custom publisher, but it feels wrong to wait to the publish step before throwing an exception. We want to flag it at the point of (mis)use. |
As discussed in open-telemetry/opentelemetry-java#2935, we need to restrict the keys and values in our baggage, to avoid having it become an untyped free-for-all dumping-ground, and to keep it from exceeding the size limits).
It seems like this would be a nice thing to add to the specification, so all implementations support it.
The text was updated successfully, but these errors were encountered: