All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.opencensus.trace.propagation.TextFormat Maven / Gradle / Ivy

There is a newer version: 0.31.1
Show newest version
/*
 * Copyright 2017, OpenCensus Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.opencensus.trace.propagation;

import io.opencensus.common.ExperimentalApi;
import io.opencensus.internal.Utils;
import io.opencensus.trace.SpanContext;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

/*>>>
import org.checkerframework.checker.nullness.qual.NonNull;
*/

/**
 * Injects and extracts {@link SpanContext trace identifiers} as text into carriers that travel
 * in-band across process boundaries. Identifiers are often encoded as messaging or RPC request
 * headers.
 *
 * 

When using http, the carrier of propagated data on both the client (injector) and server * (extractor) side is usually an http request. Propagation is usually implemented via library- * specific request interceptors, where the client-side injects span identifiers and the server-side * extracts them. * *

Example of usage on the client: * *

{@code
 * private static final Tracer tracer = Tracing.getTracer();
 * private static final TextFormat textFormat = Tracing.getPropagationComponent().getTextFormat();
 * private static final TextFormat.Setter setter = new TextFormat.Setter() {
 *   public void put(HttpURLConnection carrier, String key, String value) {
 *     carrier.setRequestProperty(field, value);
 *   }
 * }
 *
 * void makeHttpRequest() {
 *   Span span = tracer.spanBuilder("Sent.MyRequest").startSpan();
 *   try (Scope s = tracer.withSpan(span)) {
 *     HttpURLConnection connection =
 *         (HttpURLConnection) new URL("http://myserver").openConnection();
 *     textFormat.inject(span.getContext(), connection, httpURLConnectionSetter);
 *     // Send the request, wait for response and maybe set the status if not ok.
 *   }
 *   span.end();  // Can set a status.
 * }
 * }
* *

Example of usage on the server: * *

{@code
 * private static final Tracer tracer = Tracing.getTracer();
 * private static final TextFormat textFormat = Tracing.getPropagationComponent().getTextFormat();
 * private static final TextFormat.Getter getter = ...;
 *
 * void onRequestReceived(HttpRequest request) {
 *   SpanContext spanContext = textFormat.extract(request, getter);
 *   Span span = tracer.spanBuilderWithRemoteParent("Recv.MyRequest", spanContext).startSpan();
 *   try (Scope s = tracer.withSpan(span)) {
 *     // Handle request and send response back.
 *   }
 *   span.end()
 * }
 * }
* * @since 0.11 */ @ExperimentalApi public abstract class TextFormat { private static final NoopTextFormat NOOP_TEXT_FORMAT = new NoopTextFormat(); /** * The propagation fields defined. If your carrier is reused, you should delete the fields here * before calling {@link #inject(SpanContext, Object, Setter)}. * *

For example, if the carrier is a single-use or immutable request object, you don't need to * clear fields as they couldn't have been set before. If it is a mutable, retryable object, * successive calls should clear these fields first. * * @since 0.11 */ // The use cases of this are: // * allow pre-allocation of fields, especially in systems like gRPC Metadata // * allow a single-pass over an iterator (ex OpenTracing has no getter in TextMap) public abstract List fields(); /** * Injects the span context downstream. For example, as http headers. * * @param spanContext possibly not sampled. * @param carrier holds propagation fields. For example, an outgoing message or http request. * @param setter invoked for each propagation key to add or remove. * @since 0.11 */ public abstract >> extends @NonNull Object*/> void inject( SpanContext spanContext, C carrier, Setter setter); /** * Class that allows a {@code TextFormat} to set propagated fields into a carrier. * *

{@code Setter} is stateless and allows to be saved as a constant to avoid runtime * allocations. * * @param carrier of propagation fields, such as an http request * @since 0.11 */ public abstract static class Setter { /** * Replaces a propagated field with the given value. * *

For example, a setter for an {@link java.net.HttpURLConnection} would be the method * reference {@link java.net.HttpURLConnection#addRequestProperty(String, String)} * * @param carrier holds propagation fields. For example, an outgoing message or http request. * @param key the key of the field. * @param value the value of the field. * @since 0.11 */ public abstract void put(C carrier, String key, String value); } /** * Extracts the span context from upstream. For example, as http headers. * * @param carrier holds propagation fields. For example, an outgoing message or http request. * @param getter invoked for each propagation key to get. * @throws SpanContextParseException if the input is invalid * @since 0.11 */ public abstract >> extends @NonNull Object*/> SpanContext extract( C carrier, Getter getter) throws SpanContextParseException; /** * Class that allows a {@code TextFormat} to read propagated fields from a carrier. * *

{@code Getter} is stateless and allows to be saved as a constant to avoid runtime * allocations. * * @param carrier of propagation fields, such as an http request * @since 0.11 */ public abstract static class Getter { /** * Returns the first value of the given propagation {@code key} or returns {@code null}. * * @param carrier carrier of propagation fields, such as an http request * @param key the key of the field. * @return the first value of the given propagation {@code key} or returns {@code null}. * @since 0.11 */ @Nullable public abstract String get(C carrier, String key); } /** * Returns the no-op implementation of the {@code TextFormat}. * * @return the no-op implementation of the {@code TextFormat}. */ static TextFormat getNoopTextFormat() { return NOOP_TEXT_FORMAT; } private static final class NoopTextFormat extends TextFormat { private NoopTextFormat() {} @Override public List fields() { return Collections.emptyList(); } @Override public >> extends @NonNull Object*/> void inject( SpanContext spanContext, C carrier, Setter setter) { Utils.checkNotNull(spanContext, "spanContext"); Utils.checkNotNull(carrier, "carrier"); Utils.checkNotNull(setter, "setter"); } @Override public >> extends @NonNull Object*/> SpanContext extract(C carrier, Getter getter) { Utils.checkNotNull(carrier, "carrier"); Utils.checkNotNull(getter, "getter"); return SpanContext.INVALID; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy