Examples
The examples in this section use the Context Propagation library.
ThreadLocal
Population
The following example shows a holder for ThreadLocal
values.
ObservationThreadLocalHolder
/**
* Example of a wrapper around ThreadLocal values.
*/
public class ObservationThreadLocalHolder {
private static final ThreadLocal<String> holder = new ThreadLocal<>();
public static void setValue(String value) {
holder.set(value);
}
public static String getValue() {
return holder.get();
}
public static void reset() {
holder.remove();
}
}
The following example shows a ThreadLocalAccessor
that interacts with the holder.
ObservationThreadLocalAccessor
/**
* Example {@link ThreadLocalAccessor} implementation.
*/
public class ObservationThreadLocalAccessor implements ThreadLocalAccessor<String> {
public static final String KEY = "micrometer.observation";
@Override
public Object key() {
return KEY;
}
@Override
public String getValue() {
return ObservationThreadLocalHolder.getValue();
}
@Override
public void setValue(String value) {
ObservationThreadLocalHolder.setValue(value);
}
@Override
public void setValue() {
ObservationThreadLocalHolder.reset();
}
}
The following example shows one way to store and restore thread local values by using ThreadLocalAccessor
, ContextSnapshot
, and ContextRegistry
.
// Create a new Context Registry (you can use a global too)
ContextRegistry registry = new ContextRegistry();
// Register thread local accessors (you can use SPI too)
registry.registerThreadLocalAccessor(new ObservationThreadLocalAccessor());
// When you set a thread local value...
ObservationThreadLocalHolder.setValue("hello");
// ... we can capture it using ContextSnapshot
ContextSnapshot snapshot = ContextSnapshotFactory.builder().contextRegistry(registry).build().captureAll();
// After capturing if you change the thread local value again ContextSnapshot will
// not see it
ObservationThreadLocalHolder.setValue("hola");
try {
// We're populating the thread local values with what we had in
// ContextSnapshot
try (Scope scope = snapshot.setThreadLocals()) {
// Within this scope you will see the stored thread local values
then(ObservationThreadLocalHolder.getValue()).isEqualTo("hello");
}
// After the scope is closed we will come back to the previously present
// values in thread local
then(ObservationThreadLocalHolder.getValue()).isEqualTo("hola");
}
finally {
// We're clearing the thread local values so that we don't pollute the thread
ObservationThreadLocalHolder.reset();
}