private static Field mdcAdapterField() throws NoSuchFieldException {
        try {
            // SLF4J 2.0.17 change the field name to 'MDC_ADAPTER'.
            return MDC.class.getDeclaredField("MDC_ADAPTER");
        } catch (NoSuchFieldException e) {
            // Try use the old field name "mdcAdapter"
            return MDC.class.getDeclaredField("mdcAdapter");
        }
    }
Provides the access to request-scoped {@link MDC} properties. All properties set via the access methods in
this class are bound to a {@link RequestContext}, unlike the traditional thread-local {@link MDC} properties.

<h2>Updating the request-scoped context map</h2>

<p>Update the request-scoped context map using {@link #put(RequestContext, String, String)},
{@link #putAll(RequestContext, Map)}, {@link #remove(RequestContext, String)} and
{@link #clear(RequestContext)}:
<pre>{@code
RequestContext ctx = ...;
RequestScopedMdc.put(ctx, "transactionId", "1234");
RequestScopedMdc.putAll(ctx, Map.of("foo", "1", "bar", "2"));
}</pre>

<h2>Transferring thread-local properties</h2>

<p>Use {@link #copy(RequestContext, String)} or {@link #copyAll(RequestContext)} to copy some or all of
thread-local {@link MDC} properties to the request-scoped context map:
<pre>{@code
RequestContext ctx = ...;
MDC.put("transactionId", "1234");
RequestScopedMdc.copy(ctx, "transactionId");
}</pre>

<h2>Retrieving a value from the request-scoped context map</h2>

<p>You can explicitly retrieve request-scoped properties using {@link #get(RequestContext, String)} or
{@link #getAll(RequestContext)}:
<pre>{@code
RequestContext ctx = ...;
String transactionId = RequestScopedMdc.get(ctx, "transactionId");
}</pre>

<p>{@link RequestScopedMdc} replaces SLF4J's underlying {@link MDCAdapter} implementation so that
{@link MDC#get(String)} and {@link MDC#getCopyOfContextMap()} look into the request-scoped context map
before the thread-local context map:
<pre>{@code
RequestContext ctx = ...;
RequestScopedMdc.put(ctx, "transactionId", "1234");
try (SafeCloseable ignored = ctx.push()) {
    assert MDC.get("transactionId").equals("1234");

    // A request-scoped property always gets higher priority:
    MDC.put("transactionId", "5678");
    assert MDC.get("transactionId").equals("1234");
}

// Now using the thread-local property
// because not in a request scope anymore
assert MDC.get("transactionId").equals("5678");
}</pre>
core/src/main/java/com/linecorp/armeria/common/logging/RequestScopedMdc.java