Skip to content
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

[Do not merge] Initial prototype for context-prop overhaul. #655

Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions api/src/main/java/io/opentelemetry/OpenTelemetry.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

package io.opentelemetry;

import io.opentelemetry.distributedcontext.DefaultDistributedContextManager;
import io.opentelemetry.distributedcontext.DistributedContextManager;
import io.opentelemetry.distributedcontext.spi.DistributedContextManagerProvider;
import io.opentelemetry.distributedcontext.CorrelationContextManager;
import io.opentelemetry.distributedcontext.DefaultCorrelationContextManager;
import io.opentelemetry.distributedcontext.spi.CorrelationContextManagerProvider;
import io.opentelemetry.metrics.DefaultMeter;
import io.opentelemetry.metrics.Meter;
import io.opentelemetry.metrics.spi.MeterProvider;
Expand All @@ -33,13 +33,13 @@

/**
* This class provides a static global accessor for telemetry objects {@link Tracer}, {@link Meter}
* and {@link DistributedContextManager}.
* and {@link CorrelationContextManager}.
*
* <p>The telemetry objects are lazy-loaded singletons resolved via {@link ServiceLoader} mechanism.
*
* @see TracerFactory
* @see MeterProvider
* @see DistributedContextManagerProvider
* @see CorrelationContextManagerProvider
*/
@ThreadSafe
public final class OpenTelemetry {
Expand All @@ -48,7 +48,7 @@ public final class OpenTelemetry {

private final TracerFactory tracerFactory;
private final Meter meter;
private final DistributedContextManager contextManager;
private final CorrelationContextManager contextManager;

/**
* Returns a singleton {@link TracerFactory}.
Expand All @@ -74,15 +74,15 @@ public static Meter getMeter() {
}

/**
* Returns a singleton {@link DistributedContextManager}.
* Returns a singleton {@link CorrelationContextManager}.
*
* @return registered manager or default via {@link
* DefaultDistributedContextManager#getInstance()}.
* DefaultCorrelationContextManager#getInstance()}.
* @throws IllegalStateException if a specified manager (via system properties) could not be
* found.
* @since 0.1.0
*/
public static DistributedContextManager getDistributedContextManager() {
public static CorrelationContextManager getCorrelationContextManager() {
return getInstance().contextManager;
}

Expand All @@ -107,12 +107,12 @@ private OpenTelemetry() {

MeterProvider meterProvider = loadSpi(MeterProvider.class);
meter = meterProvider != null ? meterProvider.create() : DefaultMeter.getInstance();
DistributedContextManagerProvider contextManagerProvider =
loadSpi(DistributedContextManagerProvider.class);
CorrelationContextManagerProvider contextManagerProvider =
loadSpi(CorrelationContextManagerProvider.class);
contextManager =
contextManagerProvider != null
? contextManagerProvider.create()
: DefaultDistributedContextManager.getInstance();
: DefaultCorrelationContextManager.getInstance();
}

/**
Expand Down
35 changes: 35 additions & 0 deletions api/src/main/java/io/opentelemetry/baggage/BaggageManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.baggage;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.HttpExtractor;
import io.opentelemetry.context.propagation.HttpInjector;

public interface BaggageManager {
public Context setValue(Context ctx, String key, String value);

public String getValue(Context ctx, String key);

public Context removeValue(Context ctx, String key);

public Context clear(Context ctx);

public HttpInjector getHttpInjector();

public HttpExtractor getHttpExtractor();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.baggage;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.HttpExtractor;
import io.opentelemetry.context.propagation.HttpInjector;
import javax.annotation.Nullable;

public final class DefaultBaggageManager implements BaggageManager {
private static final DefaultBaggageManager INSTANCE = new DefaultBaggageManager();

public static DefaultBaggageManager getInstance() {
return INSTANCE;
}

@Override
public Context setValue(Context ctx, String key, String value) {
return ctx;
}

@Nullable
@Override
public String getValue(Context ctx, String key) {
return null;
}

@Override
public Context removeValue(Context ctx, String key) {
return ctx;
}

@Override
public Context clear(Context ctx) {
return ctx;
}

@Nullable
@Override
public HttpInjector getHttpInjector() {
return null;
}

@Nullable
@Override
public HttpExtractor getHttpExtractor() {
return null;
}

// TODO - define noop propagators (expose them?)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.baggage.propagation;

import io.opentelemetry.context.Context;

public final class ContextKeys {
private static final Context.Key<Object> BAGGAGE_KEY = Context.createKey("baggage");

public static Context.Key<Object> getSpanContextKey() {
return BAGGAGE_KEY;
Copy link
Member

@mwear mwear Nov 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a separate key for span context or is it actually being stored in baggage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate key for SpanContext ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, there is a getSpanContextKey for each context (key).

}

private ContextKeys() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.baggage.propagation;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.HttpExtractor;

public final class DefaultBaggageExtractor implements HttpExtractor {
@Override
public <C> Context extract(Context ctx, C carrier, Getter<C> getter) {
// TODO - Implement (outside the bounds of this prototype).
return ctx;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.baggage.propagation;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.HttpInjector;

public final class DefaultBaggageInjector implements HttpInjector {
@Override
public <C> void inject(Context ctx, C carrier, Setter<C> getter) {
// TODO - Implement (outside the bounds of this prototype).
}
}
72 changes: 72 additions & 0 deletions api/src/main/java/io/opentelemetry/context/Context.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.context;

public final class Context {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add this class we also need all the helpers:

  • Wrap callable/runnable
  • Wrapper for an Executor
  • Run/Call helper to run a Runnable/Callable with the context.

Also we need to make sure somehow that users are not double wrapping things with this Context and io.grpc.Context when they use both opentelemetry and io.grpc.Context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add this class we also need all the helpers:

Good point, yes. Although I wonder if we could postpone them (for a second version), or you think we would need them right from the start?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without them users cannot instrument their code. That is the main reason I actually used directly the grpc one, to not duplicate code unnecessary.

I would like to see how an RPC integration will look like with the new Injector/Extractor

private final io.grpc.Context ctx;

private Context(io.grpc.Context ctx) {
this.ctx = ctx;
}

public static Context current() {
return new Context(io.grpc.Context.current());
}

public static Scope setCurrent(Context ctx) {
return new ScopeImpl(ctx);
}

public static <T> Context.Key<T> createKey(String name) {
return new Key<T>(io.grpc.Context.<T>key(name));
}

public <T> T getValue(Context.Key<T> key) {
return key.key().get(ctx);
}

public <T> Context setValue(Context.Key<T> key, T value) {
return new Context(ctx.withValue(key.key(), value));
}

public static final class Key<T> {
io.grpc.Context.Key<T> key;

private Key(io.grpc.Context.Key<T> key) {
this.key = key;
}

io.grpc.Context.Key<T> key() {
return key;
}
}

static final class ScopeImpl implements Scope {
private final io.grpc.Context ctx;
private final io.grpc.Context prevCtx;

public ScopeImpl(Context ctx) {
this.ctx = ctx.ctx;
this.prevCtx = ctx.ctx.attach();
}

@Override
public void close() {
ctx.detach(prevCtx);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2019, OpenTelemetry 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.opentelemetry.context.propagation;

import io.opentelemetry.context.Context;

public final class ChainedPropagators {
public static HttpInjector chain(HttpInjector injector1, HttpInjector injector2) {
return new ChainedHttpInjector(injector1, injector2);
}

public static HttpExtractor chain(HttpExtractor extractor1, HttpExtractor extractor2) {
return new ChainedHttpExtractor(extractor1, extractor2);
}

private ChainedPropagators() {}

static final class ChainedHttpInjector implements HttpInjector {
private final HttpInjector injector1;
private final HttpInjector injector2;

ChainedHttpInjector(HttpInjector injector1, HttpInjector injector2) {
this.injector1 = injector1;
this.injector2 = injector2;
}

@Override
public <C> void inject(Context ctx, C carrier, Setter<C> setter) {
injector1.inject(ctx, carrier, setter);
injector2.inject(ctx, carrier, setter);
}
}

static final class ChainedHttpExtractor implements HttpExtractor {
private final HttpExtractor extractor1;
private final HttpExtractor extractor2;

ChainedHttpExtractor(HttpExtractor extractor1, HttpExtractor extractor2) {
this.extractor1 = extractor1;
this.extractor2 = extractor2;
}

@Override
public <C> Context extract(Context ctx, C carrier, Getter<C> getter) {
ctx = extractor1.extract(ctx, carrier, getter);
ctx = extractor2.extract(ctx, carrier, getter);
return ctx;
}
}
}
Loading