I agree with the way Piotr dissects the problem. I think `ScopedContext`,
even though it has its own merits, doesn't address the problem reported by
users. They simply want a new logger associated with some additional
context data.

*[See my comments below.]*

On Mon, Mar 18, 2024 at 10:40 AM Piotr P. Karwasz <piotr.karw...@gmail.com>
wrote:
> == Possible solutions
>
> As far as I know there are currently the following approaches we can
> take for problem 1:
>
> * we can add a list of `<Property>` elements in the configuration of a
> `<Logger>`, which will add the given keys to all loggers using that
> configuration. This is something we can do for very static data, e.g.
> we can add to each log statement the name of the library that issued
> it.

I don't like this approach. This is simply a hack, an abuse of a component
designed for totally something else.

> * we can create a `Logger` wrapper "bound" to context data as Mikko
> does. This wrapper will take care of setting the `ThreadContext`
> before the logger call and restore it after it.

Creating a wrapper `Logger` can work without needing to deal with
`ThreadContext`. I can think of two different ways to carry this out:

   1. Currently, `AbstractLogger` only creates `Message`s. We can rework it
   to create `LogEvent`s too. Once `AbstractLogger` gets its hand on a
   `LogEvent`, it can enrich its context data as it wishes.
   2. We can extend `ContextDataInjector` with a new `void
   injectContextData(Logger logger, StringMap target)` method, provide a
   `ContextDataInjector` implementation that branches on `logger instanceof
   ContextDataProvider`, and call `ContextDataInjector` with the associated
   `Logger` in `LogEventFactory`.

On Tue, Mar 19, 2024 at 7:45 AM Ralph Goers <ralph.go...@dslextreme.com>
wrote:
> In the meantime, I provided
https://github.com/apache/logging-log4j2/pull/2385 which I very loosely
modeled after ScopedValues.

The fact that `ScopedContext` tries to imitate `ScopedValue` using
`ThreadLocal`s is extremely confusing (from a user's pov) and risky
liability (from a maintainer's pov). I guess you wanted to implement *a*
`ScopedValue` without using *the* `ScopedValue` to be compatible with Java
8. If so, that really sounds like the `o.a.l.log4j.util.Supplier` downward
spiral. We can rather have an *internal* `Log4jScopedValue` interface and
provide Java 8 (using `InheritableThreadLocal`) and Java 21+ (using
`ScopedValue`) compatible solutions in an MRJ (Multi-Release JAR).

We can integrate `ScopedContext` to the `LogEventFactory` by providing a
specialized `ContextDataInjector` plugin – assuming `LogEventFactory`
employs all available `ContextDataInjector` plugins.

I find the current ceremony also too long:
`ScopedContext.getCurrent().where("key1", "value1").run(...)`. I would
rather aim for `ScopedContext.run(key, value, runnable)` and similar
`ScopedContext.op(..., runnable)` interaction.

I will also drop some other remarks to the PR.

Reply via email to