rgoers opened a new pull request, #2419: URL: https://github.com/apache/logging-log4j2/pull/2419
This adds support for a ScopedContext and a ResourceLogger as requested in https://github.com/apache/logging-log4j-kotlin/issues/71 and similar to https://github.com/apache/logging-log4j2/discussions/2214 Git has a funny way of mangling old PR branches so I deleted the old one and recreated it. Unfortunately, that causes comments on the previous PR to be lost here. This has several changes to ScopedContext from the previous PR. 1. ScopedContext.INITIAL_CONTEXT is no longer present. 2. ScopedContext.current() is no longer necessary. 3. Support for running child threads and propagating the ThreadContext and ScopedContext was added. Example usage for wrapping a simple code block. ``` ScopedContext.where("id", UUID.randomUUID()) .where("ipAddress", request.getRemoteAddr()) .where("loginId", session.getAttribute("loginId")) .where("hostName", request.getServerName()) .run(new Worker()); private class Worker implements Runnable { private static final Logger LOGGER = LogManager.getLogger(Worker.class); public void run() { LOGGER.debug("Performing work"); String loginId = ScopedContext.get("loginId"); } } ``` Creating Threads: ``` BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(5); ExecutorService executorService = new ThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS, workQueue); Future<?> future = ScopedContext.where("id", UUID.randomUUID()) .where("ipAddress", request.getRemoteAddr()) .where("loginId", session.getAttribute("loginId")) .where("hostName", request.getServerName()) .run(executorService, new Worker()); try { future.get(); } catch (ExecutionException ex) { logger.warn("Exception in worker thread: {}", ex.getMessage()); } ``` Note that this syntax supports virtual threads. ResourceLogger can be used to include resource data in all log events coming from a specific Logger. ``` private class User { private final String loginId; private final String role; private int loginAttempts; private final ResourceLogger logger; public User(final String loginId, final String role) { this.loginId = loginId; this.role = role; logger = ResourceLogger.newBuilder() .withClass(this.getClass()) .withSupplier(new UserSupplier()) .build(); } public void login() throws Exception { ++loginAttempts; try { authenticator.authenticate(loginId); logger.info("Login succeeded"); } catch (Exception ex) { logger.warn("Failed login"); throw ex; } } private class UserSupplier implements Supplier<Map<String, String>> { public Map<String, String> get() { Map<String, String> map = new HashMap<>(); map.put("LoginId", loginId); map.put("Role", role); map.put("Count", Integer.toString(loginAttempts)); return map; } } } ``` All events in a ResourceLogger use ParameterizedMapMessage. When logging it behaves like a ParameterizedMessage in that formatMessage only returns the message directly being logged. However, it is a MapMessage so all the attributes can be accessed via the normal Layout, Lookup, and Filter capabilities we have added. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
