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

no.mnemonic.commons.logging.LocalLoggingContext Maven / Gradle / Ivy

There is a newer version: 0.4.25
Show newest version
package no.mnemonic.commons.logging;


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * Use this context to easily annotate all logs from a limited code block with certain context variables.
 * 

* Example: * * try (LocalLoggingContext llc = LocalLoggingContext.using("correlationID", myCorrelationID)) { * // this will be logged with correlationID SET * } * //here the correlationID should be removed again.... * * If setting a context variable overwrites an existing variable, this will be reset to the original value when closing the context. *

* *

* When working with multiple threads, use {@link #duplicate()} to duplicate an existing context, or * the {@link #running(Runnable)} to copy the logging context to the context of the running task: * * try (LocalLoggingContext llc = LocalLoggingContext.using("correlationID", myCorrelationID)) { * executor.submit(llc.running(()->{ * // this will be logged with correlationID SET * })); * } * *

* */ public class LocalLoggingContext implements AutoCloseable { //map of changed keys, with the original value private final Map oldContext = new HashMap<>(); //map of changed keys, with the new value private final Map newContext = new HashMap<>(); //the original (untouched) context at the time when the context was created private final Map originalContext = new HashMap<>(); private final LoggingContext ctx; private LocalLoggingContext() { ctx = Logging.getLoggingContext(); originalContext.putAll(ctx.getAll()); } /** * Add variable to context. Any variable added here will be cleared when the context is closed. * * @param key variable key * @param newValue variable value * @return this context, to allow method chaining. */ public LocalLoggingContext using(String key, String newValue) { if (key == null) return this; this.oldContext.put(key, originalContext.get(key)); this.newContext.put(key, newValue); ctx.put(key, newValue); return this; } /** * Create a new LocalLoggingContext in the current thread duplicating this context * Example usage: * * try (LocalLoggingContext ctx = LocalLoggingContext.create().using("correlationID", UUID.randomUUID().toString)) { * executor.submit(()->{ * try (LocalLoggingContext tctx = ctx.duplicate()) { * //here, the correlationID is set in the LoggingContext of this thread too! * } * }); * } * * * @return the new LocalLoggingContext, setting all parameters from this context into the current thread. */ public LocalLoggingContext duplicate() { LocalLoggingContext duplicateContext = new LocalLoggingContext(); this.originalContext.forEach(duplicateContext::using); this.newContext.forEach(duplicateContext::using); return duplicateContext; } /** * Run a callable with the logging context set by this LocalLoggingContext * Example usage: * * try (LocalLoggingContext ctx = LocalLoggingContext.create().using("correlationID", UUID.randomUUID().toString)) { * executor.submit(ctx.running(()->{ * //here, the correlationID is set in the LoggingContext of this thread too! * })); * } * */ public Callable running(Callable task) { return () -> { try (LocalLoggingContext ignored = LocalLoggingContext.this.duplicate()) { return task.call(); } }; } /** * Run a callable with the logging context set by this LocalLoggingContext * Example usage: * * try (LocalLoggingContext ctx = LocalLoggingContext.create().using("correlationID", UUID.randomUUID().toString)) { * executor.submit(ctx.running(()->{ * //here, the correlationID is set in the LoggingContext of this thread too! * })); * } * */ public Runnable running(Runnable task) { return () -> { try (LocalLoggingContext ignored = this.duplicate()) { task.run(); } }; } @Override public void close() { oldContext.forEach((k, v) -> { if (v == null) ctx.remove(k); else ctx.put(k, v); }); } /** * Create a new LocalLoggingContext. * Recommended usage is using try-with-resources to ensure the context is closed when done */ public static LocalLoggingContext create() { return new LocalLoggingContext(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy