Module brave

Class ExtraFieldPropagation<K>

  • All Implemented Interfaces:
    Propagation<K>

    public final class ExtraFieldPropagation<K>
    extends java.lang.Object
    implements Propagation<K>
    Allows you to propagate predefined request-scoped fields, usually but not always HTTP headers.

    For example, if you are in a Cloud Foundry environment, you might want to pass the request ID:

    
     // when you initialize the builder, define the extra field you want to propagate
     tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "x-vcap-request-id")
     );
    
     // later, you can tag that request ID or use it in log correlation
     requestId = ExtraFieldPropagation.get("x-vcap-request-id");
    
     // You can also set or override the value similarly, which might be needed if a new request
     ExtraFieldPropagation.get("x-country-code", "FO");
     

    Appropriate usage

    It is generally not a good idea to use the tracing system for application logic or critical code such as security context propagation.

    Brave is an infrastructure library: you will create lock-in if you expose its apis into business code. Prefer exposing your own types for utility functions that use this class as this will insulate you from lock-in.

    While it may seem convenient, do not use this for security context propagation as it was not designed for this use case. For example, anything placed in here can be accessed by any code in the same classloader!

    Passing through alternate trace contexts

    You may also need to propagate an second trace context transparently. For example, when in an Amazon Web Services environment, but not reporting data to X-Ray. To ensure X-Ray can co-exist correctly, pass-through its tracing header like so.

    
     tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "x-amzn-trace-id")
     );
     

    Prefixed fields

    You can also prefix fields, if they follow a common pattern. For example, the following will propagate the field "x-vcap-request-id" as-is, but send the fields "country-code" and "user-id" on the wire as "baggage-country-code" and "baggage-user-id" respectively.

    
     // Setup your tracing instance with allowed fields
     tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactoryBuilder(B3Propagation.FACTORY)
                            .addField("x-vcap-request-id")
                            .addPrefixedFields("baggage-", Arrays.asList("country-code", "user-id"))
                            .build()
     );
    
     // Later, you can call below to affect the country code of the current trace context
     ExtraFieldPropagation.set("country-code", "FO");
     String countryCode = ExtraFieldPropagation.get("country-code");
    
     // Or, if you have a reference to a trace context, use it explicitly
     ExtraFieldPropagation.set(span.context(), "country-code", "FO");
     String countryCode = ExtraFieldPropagation.get(span.context(), "country-code");
     
    • Method Detail

      • current

        @Nullable
        public static java.lang.String current​(java.lang.String name)
        Synonym for get(String)
      • get

        @Nullable
        public static java.lang.String get​(java.lang.String name)
        Returns the value of the field with the specified key or null if not available.

        Prefer get(TraceContext, String) if you have a reference to a span.

      • set

        public static void set​(java.lang.String name,
                               java.lang.String value)
        Sets the current value of the field with the specified key, or drops if not a configured field.

        Prefer set(TraceContext, String, String) if you have a reference to a span.

      • getAll

        public static java.util.Map<java.lang.String,​java.lang.String> getAll()
        Returns a mapping of fields in the current trace context, or empty if there are none.

        Prefer set(TraceContext, String, String) if you have a reference to a span.

      • getAll

        public static java.util.Map<java.lang.String,​java.lang.String> getAll​(TraceContextOrSamplingFlags extracted)
        Returns a mapping of any fields in the extraction result.
      • getAll

        public static java.util.Map<java.lang.String,​java.lang.String> getAll​(TraceContext context)
        Returns a mapping of any fields in the trace context.
      • get

        @Nullable
        public static java.lang.String get​(TraceContext context,
                                           java.lang.String name)
        Returns the value of the field with the specified key or null if not available
      • set

        public static void set​(TraceContext context,
                               java.lang.String name,
                               java.lang.String value)
        Sets the value of the field with the specified key, or drops if not a configured field
      • extraKeys

        public java.util.List<K> extraKeys()
        Returns the extra keys this component can extract. This result is lowercase and does not include any trace context keys.
      • keys

        public java.util.List<K> keys()
        Only returns trace context keys. Extra field names are not returned to ensure tools don't delete them. This is to support users accessing extra fields without Brave apis (ex via headers).
        Specified by:
        keys in interface Propagation<K>
      • injector

        public <C> TraceContext.Injector<C> injector​(Propagation.Setter<C,​K> setter)
        Description copied from interface: Propagation
        Replaces a propagated field with the given value. Saved as a constant to avoid runtime allocations. For example, a setter for an HttpURLConnection would be the method reference URLConnection.addRequestProperty(String, String)
        Specified by:
        injector in interface Propagation<K>
        Parameters:
        setter - invoked for each propagation key to add.