You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/05/25 00:15:39 UTC

[james-project] branch master updated (8918482 -> 1a45cbe)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.


    from 8918482  [PERFORMANCE] Further improve things by passing codecs
     new 6f5333d  JAMES-3587 Deprecate MDCBuild::addContext
     new 1a45cbe  JAMES-3587 Optimize MDCBuilder::build

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/james/events/EventDispatcher.java   | 10 +--
 .../apache/james/events/GroupConsumerRetry.java    |  8 +-
 .../org/apache/james/events/GroupRegistration.java |  2 +-
 .../james/events/KeyRegistrationHandler.java       | 10 +--
 .../org/apache/james/events/ListenerExecutor.java  |  8 +-
 .../james/events/delivery/InVmEventDelivery.java   | 16 ++--
 .../cassandra/MailboxOperationLoggingListener.java | 14 ++--
 .../cassandra/mail/CassandraMailboxPathV3DAO.java  | 10 +--
 .../james/imap/processor/AppendProcessor.java      |  4 +-
 .../imap/processor/AuthenticateProcessor.java      |  4 +-
 .../james/imap/processor/CapabilityProcessor.java  |  2 +-
 .../james/imap/processor/CheckProcessor.java       |  2 +-
 .../james/imap/processor/CloseProcessor.java       |  2 +-
 .../james/imap/processor/CompressProcessor.java    |  4 +-
 .../apache/james/imap/processor/CopyProcessor.java |  8 +-
 .../james/imap/processor/CreateProcessor.java      |  4 +-
 .../james/imap/processor/DeleteACLProcessor.java   |  6 +-
 .../james/imap/processor/DeleteProcessor.java      |  4 +-
 .../james/imap/processor/EnableProcessor.java      |  4 +-
 .../james/imap/processor/ExamineProcessor.java     | 18 ++--
 .../james/imap/processor/ExpungeProcessor.java     |  4 +-
 .../james/imap/processor/GetACLProcessor.java      |  4 +-
 .../imap/processor/GetAnnotationProcessor.java     | 11 +--
 .../james/imap/processor/GetQuotaProcessor.java    |  4 +-
 .../imap/processor/GetQuotaRootProcessor.java      |  4 +-
 .../apache/james/imap/processor/IdleProcessor.java |  2 +-
 .../apache/james/imap/processor/LSubProcessor.java |  6 +-
 .../apache/james/imap/processor/ListProcessor.java |  6 +-
 .../james/imap/processor/ListRightsProcessor.java  |  6 +-
 .../james/imap/processor/LoginProcessor.java       |  4 +-
 .../james/imap/processor/LogoutProcessor.java      |  2 +-
 .../apache/james/imap/processor/MoveProcessor.java |  8 +-
 .../james/imap/processor/MyRightsProcessor.java    |  4 +-
 .../james/imap/processor/NamespaceProcessor.java   |  2 +-
 .../apache/james/imap/processor/NoopProcessor.java |  2 +-
 .../james/imap/processor/RenameProcessor.java      |  6 +-
 .../james/imap/processor/SearchProcessor.java      |  6 +-
 .../james/imap/processor/SelectProcessor.java      | 18 ++--
 .../james/imap/processor/SetACLProcessor.java      |  8 +-
 .../imap/processor/SetAnnotationProcessor.java     |  6 +-
 .../james/imap/processor/SetQuotaProcessor.java    |  6 +-
 .../james/imap/processor/StartTLSProcessor.java    |  2 +-
 .../james/imap/processor/StatusProcessor.java      |  6 +-
 .../james/imap/processor/StoreProcessor.java       | 10 +--
 .../james/imap/processor/SubscribeProcessor.java   |  4 +-
 .../imap/processor/SystemMessageProcessor.java     |  4 +-
 .../james/imap/processor/UnselectProcessor.java    |  2 +-
 .../james/imap/processor/UnsubscribeProcessor.java |  4 +-
 .../base/ImapResponseMessageProcessor.java         |  2 +-
 .../james/imap/processor/fetch/FetchProcessor.java |  8 +-
 .../protocols/netty/ProtocolMDCContextFactory.java | 14 ++--
 .../pop3/core/AbstractPassCmdHandler.java          |  4 +-
 .../james/protocols/pop3/core/CapaCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/DeleCmdHandler.java  |  6 +-
 .../james/protocols/pop3/core/ListCmdHandler.java  |  6 +-
 .../james/protocols/pop3/core/MDCConstants.java    |  8 +-
 .../james/protocols/pop3/core/NoopCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/QuitCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/RetrCmdHandler.java  |  6 +-
 .../james/protocols/pop3/core/RsetCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/StatCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/StlsCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/TopCmdHandler.java   |  6 +-
 .../james/protocols/pop3/core/UidlCmdHandler.java  |  6 +-
 .../protocols/pop3/core/UnknownCmdHandler.java     |  6 +-
 .../james/protocols/pop3/core/UserCmdHandler.java  |  6 +-
 .../smtp/core/AbstractHookableCmdHandler.java      |  2 +-
 .../james/protocols/smtp/core/DataCmdHandler.java  |  2 +-
 .../protocols/smtp/core/SMTPMDCContextFactory.java | 16 ++--
 .../apache/james/cli/probe/impl/JmxDataProbe.java  | 68 ++++++++--------
 .../adapter/mailbox/MailboxManagerManagement.java  | 32 ++++----
 .../james/adapter/mailbox/QuotaManagement.java     | 44 +++++-----
 .../james/adapter/mailbox/ReIndexerManagement.java |  8 +-
 .../adapter/mailbox/ReIndexerManagementTest.java   | 28 +++++--
 .../java/org/apache/james/util/MDCBuilder.java     | 95 ++++++++++++++--------
 .../org/apache/james/util/MDCStructuredLogger.java | 15 ++++
 .../java/org/apache/james/util/ReactorUtils.java   |  2 +-
 .../org/apache/james/util/StructuredLogger.java    | 11 +++
 .../java/org/apache/james/util/MDCBuilderTest.java | 73 ++++-------------
 .../org/apache/james/util/ReactorUtilsTest.java    | 10 +--
 .../mailetcontainer/impl/camel/CamelProcessor.java | 16 ++--
 .../impl/camel/MatcherSplitter.java                | 18 ++--
 .../james/jmap/draft/methods/GetFilterMethod.java  |  2 +-
 .../jmap/draft/methods/GetMailboxesMethod.java     |  8 +-
 .../jmap/draft/methods/GetMessageListMethod.java   | 29 ++++---
 .../jmap/draft/methods/GetMessagesMethod.java      | 14 +++-
 .../james/jmap/draft/methods/RequestHandler.java   |  8 +-
 .../james/jmap/draft/methods/SetFilterMethod.java  |  2 +-
 .../jmap/draft/methods/SetMailboxesMethod.java     |  8 +-
 .../jmap/draft/methods/SetMessagesMethod.java      | 10 +--
 .../draft/methods/SetVacationResponseMethod.java   |  2 +-
 .../james/jmap/draft/model/MessageProperties.java  | 10 +++
 .../org/apache/james/jmap/http/LoggingHelper.java  |  8 +-
 .../james/imapserver/netty/IMAPMDCContext.java     | 26 +++---
 .../netty/ManageSieveMDCContext.java               | 12 +--
 .../james/pop3server/core/PassCmdHandler.java      |  2 +-
 .../james/webadmin/mdc/LoggingRequestFilter.java   | 14 ++--
 .../james/webadmin/mdc/LoggingResponseFilter.java  | 16 ++--
 .../org/apache/james/webadmin/mdc/MDCFilter.java   | 12 +--
 .../webadmin/routes/UserCreationRequestLogger.java | 12 +--
 .../apache/james/task/SerialTaskManagerWorker.java |  6 +-
 101 files changed, 541 insertions(+), 493 deletions(-)

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 01/02: JAMES-3587 Deprecate MDCBuild::addContext

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 6f5333d582933807a5ebeaadcd2bc20b6a0543f8
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 19 21:28:57 2021 +0700

    JAMES-3587 Deprecate MDCBuild::addContext
    
    MDCBuilder::addContext does an implicit call to Object::toString
    
    We do not want that for two reasons:
    
     - 1. Formatting. For instance ` {"user":"btellier@erugerkuf"} ` instead
          of simply `btellier@erugerkuf`.
    
     - 2. Performance.
    
    See the attached flame graphs: James spends ~1.20% of CPU calling
    Object::toString which correlate closely to MDCBuilder::addContext.
    This crosses the "valuable to optimize" threshold. Especially calls
    to MoreObject::toStringHelper(this) are not negligible.
---
 .../org/apache/james/events/EventDispatcher.java   | 10 ++--
 .../apache/james/events/GroupConsumerRetry.java    |  8 +--
 .../org/apache/james/events/GroupRegistration.java |  2 +-
 .../james/events/KeyRegistrationHandler.java       | 10 ++--
 .../org/apache/james/events/ListenerExecutor.java  |  8 +--
 .../james/events/delivery/InVmEventDelivery.java   | 16 ++---
 .../cassandra/MailboxOperationLoggingListener.java | 14 ++---
 .../cassandra/mail/CassandraMailboxPathV3DAO.java  | 10 ++--
 .../james/imap/processor/AppendProcessor.java      |  4 +-
 .../imap/processor/AuthenticateProcessor.java      |  4 +-
 .../james/imap/processor/CapabilityProcessor.java  |  2 +-
 .../james/imap/processor/CheckProcessor.java       |  2 +-
 .../james/imap/processor/CloseProcessor.java       |  2 +-
 .../james/imap/processor/CompressProcessor.java    |  4 +-
 .../apache/james/imap/processor/CopyProcessor.java |  8 +--
 .../james/imap/processor/CreateProcessor.java      |  4 +-
 .../james/imap/processor/DeleteACLProcessor.java   |  6 +-
 .../james/imap/processor/DeleteProcessor.java      |  4 +-
 .../james/imap/processor/EnableProcessor.java      |  4 +-
 .../james/imap/processor/ExamineProcessor.java     | 18 +++---
 .../james/imap/processor/ExpungeProcessor.java     |  4 +-
 .../james/imap/processor/GetACLProcessor.java      |  4 +-
 .../imap/processor/GetAnnotationProcessor.java     | 11 ++--
 .../james/imap/processor/GetQuotaProcessor.java    |  4 +-
 .../imap/processor/GetQuotaRootProcessor.java      |  4 +-
 .../apache/james/imap/processor/IdleProcessor.java |  2 +-
 .../apache/james/imap/processor/LSubProcessor.java |  6 +-
 .../apache/james/imap/processor/ListProcessor.java |  6 +-
 .../james/imap/processor/ListRightsProcessor.java  |  6 +-
 .../james/imap/processor/LoginProcessor.java       |  4 +-
 .../james/imap/processor/LogoutProcessor.java      |  2 +-
 .../apache/james/imap/processor/MoveProcessor.java |  8 +--
 .../james/imap/processor/MyRightsProcessor.java    |  4 +-
 .../james/imap/processor/NamespaceProcessor.java   |  2 +-
 .../apache/james/imap/processor/NoopProcessor.java |  2 +-
 .../james/imap/processor/RenameProcessor.java      |  6 +-
 .../james/imap/processor/SearchProcessor.java      |  6 +-
 .../james/imap/processor/SelectProcessor.java      | 18 +++---
 .../james/imap/processor/SetACLProcessor.java      |  8 +--
 .../imap/processor/SetAnnotationProcessor.java     |  6 +-
 .../james/imap/processor/SetQuotaProcessor.java    |  6 +-
 .../james/imap/processor/StartTLSProcessor.java    |  2 +-
 .../james/imap/processor/StatusProcessor.java      |  6 +-
 .../james/imap/processor/StoreProcessor.java       | 10 ++--
 .../james/imap/processor/SubscribeProcessor.java   |  4 +-
 .../imap/processor/SystemMessageProcessor.java     |  4 +-
 .../james/imap/processor/UnselectProcessor.java    |  2 +-
 .../james/imap/processor/UnsubscribeProcessor.java |  4 +-
 .../base/ImapResponseMessageProcessor.java         |  2 +-
 .../james/imap/processor/fetch/FetchProcessor.java |  8 +--
 .../protocols/netty/ProtocolMDCContextFactory.java | 14 ++---
 .../pop3/core/AbstractPassCmdHandler.java          |  4 +-
 .../james/protocols/pop3/core/CapaCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/DeleCmdHandler.java  |  6 +-
 .../james/protocols/pop3/core/ListCmdHandler.java  |  6 +-
 .../james/protocols/pop3/core/MDCConstants.java    |  8 +--
 .../james/protocols/pop3/core/NoopCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/QuitCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/RetrCmdHandler.java  |  6 +-
 .../james/protocols/pop3/core/RsetCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/StatCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/StlsCmdHandler.java  |  4 +-
 .../james/protocols/pop3/core/TopCmdHandler.java   |  6 +-
 .../james/protocols/pop3/core/UidlCmdHandler.java  |  6 +-
 .../protocols/pop3/core/UnknownCmdHandler.java     |  6 +-
 .../james/protocols/pop3/core/UserCmdHandler.java  |  6 +-
 .../smtp/core/AbstractHookableCmdHandler.java      |  2 +-
 .../james/protocols/smtp/core/DataCmdHandler.java  |  2 +-
 .../protocols/smtp/core/SMTPMDCContextFactory.java | 16 ++---
 .../apache/james/cli/probe/impl/JmxDataProbe.java  | 68 +++++++++++-----------
 .../adapter/mailbox/MailboxManagerManagement.java  | 32 +++++-----
 .../james/adapter/mailbox/QuotaManagement.java     | 44 +++++++-------
 .../james/adapter/mailbox/ReIndexerManagement.java |  8 +--
 .../adapter/mailbox/ReIndexerManagementTest.java   | 28 +++++++--
 .../java/org/apache/james/util/MDCBuilder.java     | 48 +++++++++++++++
 .../org/apache/james/util/MDCStructuredLogger.java | 15 +++++
 .../java/org/apache/james/util/ReactorUtils.java   |  2 +-
 .../org/apache/james/util/StructuredLogger.java    | 11 ++++
 .../java/org/apache/james/util/MDCBuilderTest.java | 20 +++++--
 .../org/apache/james/util/ReactorUtilsTest.java    | 10 ++--
 .../mailetcontainer/impl/camel/CamelProcessor.java | 16 ++---
 .../impl/camel/MatcherSplitter.java                | 18 +++---
 .../james/jmap/draft/methods/GetFilterMethod.java  |  2 +-
 .../jmap/draft/methods/GetMailboxesMethod.java     |  8 +--
 .../jmap/draft/methods/GetMessageListMethod.java   | 29 +++++----
 .../jmap/draft/methods/GetMessagesMethod.java      | 14 +++--
 .../james/jmap/draft/methods/RequestHandler.java   |  8 ++-
 .../james/jmap/draft/methods/SetFilterMethod.java  |  2 +-
 .../jmap/draft/methods/SetMailboxesMethod.java     |  8 +--
 .../jmap/draft/methods/SetMessagesMethod.java      | 10 ++--
 .../draft/methods/SetVacationResponseMethod.java   |  2 +-
 .../james/jmap/draft/model/MessageProperties.java  | 10 ++++
 .../org/apache/james/jmap/http/LoggingHelper.java  |  8 +--
 .../james/imapserver/netty/IMAPMDCContext.java     | 26 ++++-----
 .../netty/ManageSieveMDCContext.java               | 12 ++--
 .../james/pop3server/core/PassCmdHandler.java      |  2 +-
 .../james/webadmin/mdc/LoggingRequestFilter.java   | 14 ++---
 .../james/webadmin/mdc/LoggingResponseFilter.java  | 16 ++---
 .../org/apache/james/webadmin/mdc/MDCFilter.java   | 12 ++--
 .../webadmin/routes/UserCreationRequestLogger.java | 12 ++--
 .../apache/james/task/SerialTaskManagerWorker.java |  6 +-
 101 files changed, 530 insertions(+), 404 deletions(-)

diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
index ddfa875..5c7ff16 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -130,7 +130,7 @@ public class EventDispatcher {
     private Mono<Void> executeListener(Event event, EventListener.ReactiveEventListener listener, RegistrationKey registrationKey) {
         return listenerExecutor.execute(listener,
                     MDCBuilder.create()
-                        .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, registrationKey),
+                        .addToContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, registrationKey.asString()),
                     event)
             .onErrorResume(e -> {
                 structuredLogger(event, ImmutableSet.of(registrationKey))
@@ -141,10 +141,10 @@ public class EventDispatcher {
 
     private StructuredLogger structuredLogger(Event event, Set<RegistrationKey> keys) {
         return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.REGISTRATION_KEYS, keys);
+            .field(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId().getId().toString())
+            .field(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass().getCanonicalName())
+            .field(EventBus.StructuredLoggingFields.USER, event.getUsername().asString())
+            .field(EventBus.StructuredLoggingFields.REGISTRATION_KEYS, keys.toString());
     }
 
     private Mono<Void> dispatchToRemoteListeners(Event event, Set<RegistrationKey> keys) {
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
index 5982933..598d86d 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
@@ -123,9 +123,9 @@ class GroupConsumerRetry {
 
     private StructuredLogger createStructuredLogger(Event event) {
         return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.GROUP, group.asString());
+            .field(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId().getId().toString())
+            .field(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass().getCanonicalName())
+            .field(EventBus.StructuredLoggingFields.USER, event.getUsername().asString())
+            .field(EventBus.StructuredLoggingFields.GROUP, group.asString());
     }
 }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
index 4a83f81..57839ef 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistration.java
@@ -165,7 +165,7 @@ class GroupRegistration implements Registration {
         return listenerExecutor.execute(
             listener,
             MDCBuilder.create()
-                .addContext(EventBus.StructuredLoggingFields.GROUP, group),
+                .addToContext(EventBus.StructuredLoggingFields.GROUP, group.asString()),
             event);
     }
 
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
index d62f59f..6226dd0 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
@@ -172,7 +172,7 @@ class KeyRegistrationHandler {
 
     private Mono<Void> executeListener(EventListener.ReactiveEventListener listener, Event event, RegistrationKey key) {
         MDCBuilder mdcBuilder = MDCBuilder.create()
-            .addContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
+            .addToContext(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key.asString());
 
         return listenerExecutor.execute(listener, mdcBuilder, event)
             .doOnError(e -> structuredLogger(event, key)
@@ -192,9 +192,9 @@ class KeyRegistrationHandler {
 
     private StructuredLogger structuredLogger(Event event, RegistrationKey key) {
         return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key);
+            .field(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId().getId().toString())
+            .field(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass().getCanonicalName())
+            .field(EventBus.StructuredLoggingFields.USER, event.getUsername().asString())
+            .field(EventBus.StructuredLoggingFields.REGISTRATION_KEY, key.asString());
     }
 }
diff --git a/event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java b/event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java
index 2d2f258..0603b73 100644
--- a/event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java
+++ b/event-bus/distributed/src/main/java/org/apache/james/events/ListenerExecutor.java
@@ -45,9 +45,9 @@ class ListenerExecutor {
 
     private MDCBuilder mdc(EventListener listener, MDCBuilder mdcBuilder, Event event) {
         return mdcBuilder
-            .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addContext(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass());
+            .addToContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId().getId().toString())
+            .addToContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass().getCanonicalName())
+            .addToContext(EventBus.StructuredLoggingFields.USER, event.getUsername().asString())
+            .addToContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass().getCanonicalName());
     }
 }
diff --git a/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
index 0cc70d5..952e627 100644
--- a/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
+++ b/event-bus/in-vm/src/main/java/org/apache/james/events/delivery/InVmEventDelivery.java
@@ -88,17 +88,17 @@ public class InVmEventDelivery implements EventDelivery {
 
     private MDCBuilder buildMDC(EventListener listener, Event event) {
         return MDCBuilder.create()
-            .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addContext(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass());
+            .addToContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId().toString())
+            .addToContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass().getCanonicalName())
+            .addToContext(EventBus.StructuredLoggingFields.USER, event.getUsername().asString())
+            .addToContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass().getCanonicalName());
     }
 
     private StructuredLogger structuredLogger(Event event, EventListener listener) {
         return MDCStructuredLogger.forLogger(LOGGER)
-            .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId())
-            .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass())
-            .addField(EventBus.StructuredLoggingFields.USER, event.getUsername())
-            .addField(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass());
+            .field(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId().getId().toString())
+            .field(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass().getCanonicalName())
+            .field(EventBus.StructuredLoggingFields.USER, event.getUsername().asString())
+            .field(EventBus.StructuredLoggingFields.LISTENER_CLASS, listener.getClass().getCanonicalName());
     }
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
index dcfd070..dcbc712 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/MailboxOperationLoggingListener.java
@@ -59,23 +59,23 @@ public class MailboxOperationLoggingListener implements EventListener.GroupEvent
         if (event instanceof MailboxRenamed) {
             MailboxRenamed mailboxRenamed = (MailboxRenamed) event;
             GhostMailbox.logger()
-                .addField(MAILBOX_ID, mailboxRenamed.getMailboxId())
-                .addField(MAILBOX_NAME, mailboxRenamed.getNewPath())
-                .addField(TYPE, ADDED)
+                .field(MAILBOX_ID, mailboxRenamed.getMailboxId().serialize())
+                .field(MAILBOX_NAME, mailboxRenamed.getNewPath().asString())
+                .field(TYPE, ADDED)
                 .log(logger -> logger.info("Mailbox renamed event"));
         }
         if (event instanceof MailboxDeletion) {
             MailboxDeletion mailboxDeletion = (MailboxDeletion) event;
             GhostMailbox.logger()
-                .addField(MAILBOX_ID, mailboxDeletion.getMailboxId())
-                .addField(TYPE, REMOVED)
+                .field(MAILBOX_ID, mailboxDeletion.getMailboxId().serialize())
+                .field(TYPE, REMOVED)
                 .log(logger -> logger.info("Mailbox deleted event"));
         }
         if (event instanceof MailboxAdded) {
             MailboxAdded mailboxAdded = (MailboxAdded) event;
             GhostMailbox.logger()
-                .addField(MAILBOX_ID, mailboxAdded.getMailboxId())
-                .addField(TYPE, ADDED)
+                .field(MAILBOX_ID, mailboxAdded.getMailboxId().serialize())
+                .field(TYPE, ADDED)
                 .log(logger -> logger.info("Mailbox added event"));
         }
     }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathV3DAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathV3DAO.java
index 1228691..3de61be 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathV3DAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxPathV3DAO.java
@@ -169,8 +169,8 @@ public class CassandraMailboxPathV3DAO {
 
     public void logGhostMailboxFailure(MailboxPath mailboxPath) {
         GhostMailbox.logger()
-                .addField(GhostMailbox.MAILBOX_NAME, mailboxPath)
-                .addField(TYPE, "readMiss")
+                .field(GhostMailbox.MAILBOX_NAME, mailboxPath.asString())
+                .field(TYPE, "readMiss")
                 .log(logger -> logger.debug("Read mailbox missed"));
     }
 
@@ -182,9 +182,9 @@ public class CassandraMailboxPathV3DAO {
      */
     private void logReadSuccess(Mailbox mailbox) {
         GhostMailbox.logger()
-            .addField(GhostMailbox.MAILBOX_NAME, mailbox.generateAssociatedPath())
-            .addField(TYPE, "readSuccess")
-            .addField(GhostMailbox.MAILBOX_ID, mailbox.getMailboxId())
+            .field(GhostMailbox.MAILBOX_NAME, mailbox.generateAssociatedPath().asString())
+            .field(TYPE, "readSuccess")
+            .field(GhostMailbox.MAILBOX_ID, mailbox.getMailboxId().serialize())
             .log(logger -> logger.debug("Read mailbox succeeded"));
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
index f4fa9a8..4b9cc56 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
@@ -141,8 +141,8 @@ public class AppendProcessor extends AbstractMailboxProcessor<AppendRequest> {
     @Override
     protected Closeable addContextToMDC(AppendRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "APPEND")
-            .addContext("mailbox", request.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "APPEND")
+            .addToContext("mailbox", request.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
index 38709cf..067d397 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
@@ -150,8 +150,8 @@ public class AuthenticateProcessor extends AbstractAuthProcessor<AuthenticateReq
     @Override
     protected Closeable addContextToMDC(AuthenticateRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "AUTHENTICATE")
-            .addContext("authType", request.getAuthType())
+            .addToContext(MDCBuilder.ACTION, "AUTHENTICATE")
+            .addToContext("authType", request.getAuthType())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
index 03f3a93..f9d6e3a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
@@ -119,7 +119,7 @@ public class CapabilityProcessor extends AbstractMailboxProcessor<CapabilityRequ
     @Override
     protected Closeable addContextToMDC(CapabilityRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "CAPABILITY")
+            .addToContext(MDCBuilder.ACTION, "CAPABILITY")
             .build();
     }
     
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CheckProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CheckProcessor.java
index 57863f6..6d567e7 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CheckProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CheckProcessor.java
@@ -45,7 +45,7 @@ public class CheckProcessor extends AbstractMailboxProcessor<CheckRequest> {
     @Override
     protected Closeable addContextToMDC(CheckRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "CHECK")
+            .addToContext(MDCBuilder.ACTION, "CHECK")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CloseProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CloseProcessor.java
index 60d6e17..768b46d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CloseProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CloseProcessor.java
@@ -71,7 +71,7 @@ public class CloseProcessor extends AbstractMailboxProcessor<CloseRequest> {
     @Override
     protected Closeable addContextToMDC(CloseRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "CLOSE")
+            .addToContext(MDCBuilder.ACTION, "CLOSE")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
index 4f4d8a8..449a545 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
@@ -78,8 +78,8 @@ public class CompressProcessor extends AbstractChainedProcessor<CompressRequest>
     @Override
     protected Closeable addContextToMDC(CompressRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "COMPRESS")
-            .addContext("algorithm", message.getAlgorithm())
+            .addToContext(MDCBuilder.ACTION, "COMPRESS")
+            .addToContext("algorithm", message.getAlgorithm())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CopyProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CopyProcessor.java
index d96f327..7a3e189 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CopyProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CopyProcessor.java
@@ -58,10 +58,10 @@ public class CopyProcessor extends AbstractMessageRangeProcessor<CopyRequest> {
     @Override
     protected Closeable addContextToMDC(CopyRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "COPY")
-            .addContext("targetMailbox", request.getMailboxName())
-            .addContext("uidEnabled", request.isUseUids())
-            .addContext("idSet", IdRange.toString(request.getIdSet()))
+            .addToContext(MDCBuilder.ACTION, "COPY")
+            .addToContext("targetMailbox", request.getMailboxName())
+            .addToContext("uidEnabled", Boolean.toString(request.isUseUids()))
+            .addToContext("idSet", IdRange.toString(request.getIdSet()))
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CreateProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CreateProcessor.java
index b5646f9..dee7528 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CreateProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CreateProcessor.java
@@ -68,8 +68,8 @@ public class CreateProcessor extends AbstractMailboxProcessor<CreateRequest> {
     @Override
     protected Closeable addContextToMDC(CreateRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "CREATE")
-            .addContext("mailbox", request.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "CREATE")
+            .addToContext("mailbox", request.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
index 0db8646..5f0e30e 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
@@ -142,9 +142,9 @@ public class DeleteACLProcessor extends AbstractMailboxProcessor<DeleteACLReques
     @Override
     protected Closeable addContextToMDC(DeleteACLRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "DELETE_ACL")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("identifier", request.getIdentifier())
+            .addToContext(MDCBuilder.ACTION, "DELETE_ACL")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("identifier", request.getIdentifier())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteProcessor.java
index edc86ce..930961d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteProcessor.java
@@ -74,8 +74,8 @@ public class DeleteProcessor extends AbstractMailboxProcessor<DeleteRequest> {
     @Override
     protected Closeable addContextToMDC(DeleteRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "DELETE")
-            .addContext("mailbox", request.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "DELETE")
+            .addToContext("mailbox", request.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java
index 33e650d..1d88a07 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java
@@ -130,8 +130,8 @@ public class EnableProcessor extends AbstractMailboxProcessor<EnableRequest> imp
     @Override
     protected Closeable addContextToMDC(EnableRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "ENABLE")
-            .addContext("capabilities", ImmutableList.copyOf(request.getCapabilities()))
+            .addToContext(MDCBuilder.ACTION, "ENABLE")
+            .addToContext("capabilities", ImmutableList.copyOf(request.getCapabilities()).toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/ExamineProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/ExamineProcessor.java
index 47dc5d0..2c4a834 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/ExamineProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/ExamineProcessor.java
@@ -20,6 +20,8 @@
 package org.apache.james.imap.processor;
 
 import java.io.Closeable;
+import java.util.Objects;
+import java.util.Optional;
 
 import org.apache.james.events.EventBus;
 import org.apache.james.imap.api.message.IdRange;
@@ -41,14 +43,14 @@ public class ExamineProcessor extends AbstractSelectionProcessor<ExamineRequest>
     @Override
     protected Closeable addContextToMDC(ExamineRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "EXAMINE")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("condstore", Boolean.toString(request.getCondstore()))
-            .addContext("knownModseq", request.getKnownModSeq())
-            .addContext("knownUids", UidRange.toString(request.getKnownUidSet()))
-            .addContext("knownIdRange", IdRange.toString(request.getKnownSequenceSet()))
-            .addContext("lastKnownUidValidity", request.getLastKnownUidValidity())
-            .addContext("uidSet", UidRange.toString(request.getUidSet()))
+            .addToContext(MDCBuilder.ACTION, "EXAMINE")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("condstore", Boolean.toString(request.getCondstore()))
+            .addToContextIfPresent("knownModseq", Optional.ofNullable(request.getKnownModSeq()).map(Objects::toString))
+            .addToContext("knownUids", UidRange.toString(request.getKnownUidSet()))
+            .addToContext("knownIdRange", IdRange.toString(request.getKnownSequenceSet()))
+            .addToContext("lastKnownUidValidity", request.getLastKnownUidValidity().toString())
+            .addToContext("uidSet", UidRange.toString(request.getUidSet()))
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java
index dc6094d..fa87110 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java
@@ -132,8 +132,8 @@ public class ExpungeProcessor extends AbstractMailboxProcessor<ExpungeRequest> i
     @Override
     protected Closeable addContextToMDC(ExpungeRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "EXPUNGE")
-            .addContext("uidSet", IdRange.toString(request.getUidSet()))
+            .addToContext(MDCBuilder.ACTION, "EXPUNGE")
+            .addToContext("uidSet", IdRange.toString(request.getUidSet()))
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
index ba7729d..6db88dd 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
@@ -117,8 +117,8 @@ public class GetACLProcessor extends AbstractMailboxProcessor<GetACLRequest> imp
     @Override
     protected Closeable addContextToMDC(GetACLRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "GET_ACL")
-            .addContext("mailbox", request.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "GET_ACL")
+            .addToContext("mailbox", request.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java
index 8cd15c9..7658554 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java
@@ -158,11 +158,12 @@ public class GetAnnotationProcessor extends AbstractMailboxProcessor<GetAnnotati
     @Override
     protected Closeable addContextToMDC(GetAnnotationRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "GET_ANNOTATION")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("depth", request.getDepth())
-            .addContext("maxSize", request.getMaxsize())
-            .addContext("keys", request.getKeys())
+            .addToContext(MDCBuilder.ACTION, "GET_ANNOTATION")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("depth", request.getDepth().getCode())
+            .addToContextIfPresent("maxSize", request.getMaxsize()
+                .map(i -> Integer.toString(i)))
+            .addToContext("keys", request.getKeys().toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java
index 51cdee5..a752582 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java
@@ -114,8 +114,8 @@ public class GetQuotaProcessor extends AbstractMailboxProcessor<GetQuotaRequest>
     @Override
     protected Closeable addContextToMDC(GetQuotaRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "GET_QUOTA")
-            .addContext("quotaRoot", request.getQuotaRoot())
+            .addToContext(MDCBuilder.ACTION, "GET_QUOTA")
+            .addToContext("quotaRoot", request.getQuotaRoot())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java
index 75c8738..61a184a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java
@@ -111,8 +111,8 @@ public class GetQuotaRootProcessor extends AbstractMailboxProcessor<GetQuotaRoot
     @Override
     protected Closeable addContextToMDC(GetQuotaRootRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "GET_QUOTA_ROOT")
-            .addContext("mailbox", request.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "GET_QUOTA_ROOT")
+            .addToContext("mailbox", request.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
index 0b5a933..1f01f62 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
@@ -192,7 +192,7 @@ public class IdleProcessor extends AbstractMailboxProcessor<IdleRequest> impleme
     @Override
     protected Closeable addContextToMDC(IdleRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "IDLE")
+            .addToContext(MDCBuilder.ACTION, "IDLE")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
index de43684..4efeb74 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
@@ -102,9 +102,9 @@ public class LSubProcessor extends AbstractSubscriptionProcessor<LsubRequest> {
     @Override
     protected Closeable addContextToMDC(LsubRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "LSUB")
-            .addContext("base", request.getBaseReferenceName())
-            .addContext("pattern", request.getMailboxPattern())
+            .addToContext(MDCBuilder.ACTION, "LSUB")
+            .addToContext("base", request.getBaseReferenceName())
+            .addToContext("pattern", request.getMailboxPattern())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
index 3155fa2..6bb465f 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
@@ -189,9 +189,9 @@ public class ListProcessor extends AbstractMailboxProcessor<ListRequest> {
     @Override
     protected Closeable addContextToMDC(ListRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "LIST")
-            .addContext("base", request.getBaseReferenceName())
-            .addContext("pattern", request.getMailboxPattern())
+            .addToContext(MDCBuilder.ACTION, "LIST")
+            .addToContext("base", request.getBaseReferenceName())
+            .addToContext("pattern", request.getMailboxPattern())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java
index ca76e6f..736ac61 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java
@@ -131,9 +131,9 @@ public class ListRightsProcessor extends AbstractMailboxProcessor<ListRightsRequ
     @Override
     protected Closeable addContextToMDC(ListRightsRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "LIST_RIGHTS")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("identifier", request.getIdentifier())
+            .addToContext(MDCBuilder.ACTION, "LIST_RIGHTS")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("identifier", request.getIdentifier())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java
index b5df53c..a75bdab 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java
@@ -71,8 +71,8 @@ public class LoginProcessor extends AbstractAuthProcessor<LoginRequest> implemen
     @Override
     protected Closeable addContextToMDC(LoginRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "LOGIN")
-            .addContext(MDCBuilder.USER, request.getUserid().asString())
+            .addToContext(MDCBuilder.ACTION, "LOGIN")
+            .addToContext(MDCBuilder.USER, request.getUserid().asString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/LogoutProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/LogoutProcessor.java
index 390ea77..11ca339 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/LogoutProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/LogoutProcessor.java
@@ -48,7 +48,7 @@ public class LogoutProcessor extends AbstractMailboxProcessor<LogoutRequest> {
     @Override
     protected Closeable addContextToMDC(LogoutRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "LOGOUT")
+            .addToContext(MDCBuilder.ACTION, "LOGOUT")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java
index bbe1cc4..45ed65a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java
@@ -73,10 +73,10 @@ public class MoveProcessor extends AbstractMessageRangeProcessor<MoveRequest> im
     @Override
     protected Closeable addContextToMDC(MoveRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "MOVE")
-            .addContext("targetMailbox", request.getMailboxName())
-            .addContext("uidEnabled", request.isUseUids())
-            .addContext("idSet", IdRange.toString(request.getIdSet()))
+            .addToContext(MDCBuilder.ACTION, "MOVE")
+            .addToContext("targetMailbox", request.getMailboxName())
+            .addToContext("uidEnabled", Boolean.toString(request.isUseUids()))
+            .addToContext("idSet", IdRange.toString(request.getIdSet()))
             .build();
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java
index 63f5138..02bf6fa 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java
@@ -114,8 +114,8 @@ public class MyRightsProcessor extends AbstractMailboxProcessor<MyRightsRequest>
     @Override
     protected Closeable addContextToMDC(MyRightsRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "MYRIGHTS")
-            .addContext("mailbox", request.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "MYRIGHTS")
+            .addToContext("mailbox", request.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java
index eb2e8c5..d30238a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java
@@ -110,7 +110,7 @@ public class NamespaceProcessor extends AbstractMailboxProcessor<NamespaceReques
     @Override
     protected Closeable addContextToMDC(NamespaceRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "NAMESPACE")
+            .addToContext(MDCBuilder.ACTION, "NAMESPACE")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/NoopProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/NoopProcessor.java
index e66015a..98a23d5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/NoopProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/NoopProcessor.java
@@ -46,7 +46,7 @@ public class NoopProcessor extends AbstractMailboxProcessor<NoopRequest> {
     @Override
     protected Closeable addContextToMDC(NoopRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "NOOP")
+            .addToContext(MDCBuilder.ACTION, "NOOP")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/RenameProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/RenameProcessor.java
index a6795e9..e2bb04e 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/RenameProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/RenameProcessor.java
@@ -83,9 +83,9 @@ public class RenameProcessor extends AbstractMailboxProcessor<RenameRequest> {
     @Override
     protected Closeable addContextToMDC(RenameRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "RENAME")
-            .addContext("existingName", request.getExistingName())
-            .addContext("newName", request.getNewName())
+            .addToContext(MDCBuilder.ACTION, "RENAME")
+            .addToContext("existingName", request.getExistingName())
+            .addToContext("newName", request.getNewName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
index d93742f..dcfdfa3 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
@@ -514,9 +514,9 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
     @Override
     protected Closeable addContextToMDC(SearchRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SEARCH")
-            .addContext("useUid", request.isUseUids())
-            .addContext("searchOperation", request.getSearchOperation())
+            .addToContext(MDCBuilder.ACTION, "SEARCH")
+            .addToContext("useUid", Boolean.toString(request.isUseUids()))
+            .addToContext("searchOperation", request.getSearchOperation().toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SelectProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SelectProcessor.java
index 6f4cdd8..4035875 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SelectProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SelectProcessor.java
@@ -20,6 +20,8 @@
 package org.apache.james.imap.processor;
 
 import java.io.Closeable;
+import java.util.Objects;
+import java.util.Optional;
 
 import org.apache.james.events.EventBus;
 import org.apache.james.imap.api.message.IdRange;
@@ -41,14 +43,14 @@ public class SelectProcessor extends AbstractSelectionProcessor<SelectRequest> {
     @Override
     protected Closeable addContextToMDC(SelectRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SELECT")
-            .addContext("mailbox", message.getMailboxName())
-            .addContext("condstore", message.getCondstore())
-            .addContext("knownModseq", message.getKnownModSeq())
-            .addContext("knownUids", UidRange.toString(message.getKnownUidSet()))
-            .addContext("knownIdRange", IdRange.toString(message.getKnownSequenceSet()))
-            .addContext("lastKnownUidValidity", message.getLastKnownUidValidity())
-            .addContext("uidSet", UidRange.toString(message.getUidSet()))
+            .addToContext(MDCBuilder.ACTION, "SELECT")
+            .addToContext("mailbox", message.getMailboxName())
+            .addToContext("condstore", Boolean.toString(message.getCondstore()))
+            .addToContextIfPresent("knownModseq", Optional.ofNullable(message.getKnownModSeq()).map(Objects::toString))
+            .addToContext("knownUids", UidRange.toString(message.getKnownUidSet()))
+            .addToContext("knownIdRange", IdRange.toString(message.getKnownSequenceSet()))
+            .addToContext("lastKnownUidValidity", message.getLastKnownUidValidity().toString())
+            .addToContext("uidSet", UidRange.toString(message.getUidSet()))
             .build();
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java
index afba088..828da25 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java
@@ -160,10 +160,10 @@ public class SetACLProcessor extends AbstractMailboxProcessor<SetACLRequest> imp
     @Override
     protected Closeable addContextToMDC(SetACLRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SET_ACL")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("identifier", request.getIdentifier())
-            .addContext("rights", request.getRights())
+            .addToContext(MDCBuilder.ACTION, "SET_ACL")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("identifier", request.getIdentifier())
+            .addToContext("rights", request.getRights())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
index 12209a0..d014956 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
@@ -83,9 +83,9 @@ public class SetAnnotationProcessor extends AbstractMailboxProcessor<SetAnnotati
     @Override
     protected Closeable addContextToMDC(SetAnnotationRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SET_ANNOTATION")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("annotations", request.getMailboxAnnotations())
+            .addToContext(MDCBuilder.ACTION, "SET_ANNOTATION")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("annotations", request.getMailboxAnnotations().toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java
index 3f0e443..659b693 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java
@@ -65,9 +65,9 @@ public class SetQuotaProcessor extends AbstractMailboxProcessor<SetQuotaRequest>
     @Override
     protected Closeable addContextToMDC(SetQuotaRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SET_QUOTA")
-            .addContext("quotaRoot", request.getQuotaRoot())
-            .addContext("limits", request.getResourceLimits())
+            .addToContext(MDCBuilder.ACTION, "SET_QUOTA")
+            .addToContext("quotaRoot", request.getQuotaRoot())
+            .addToContext("limits", request.getResourceLimits().toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
index 65977f9..028ac98 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
@@ -70,7 +70,7 @@ public class StartTLSProcessor extends AbstractChainedProcessor<StartTLSRequest>
     @Override
     protected Closeable addContextToMDC(StartTLSRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "START_TLS")
+            .addToContext(MDCBuilder.ACTION, "START_TLS")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
index b96d38a..3688928 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
@@ -151,9 +151,9 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> {
     @Override
     protected Closeable addContextToMDC(StatusRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "STATUS")
-            .addContext("mailbox", request.getMailboxName())
-            .addContext("parameters", request.getStatusDataItems())
+            .addToContext(MDCBuilder.ACTION, "STATUS")
+            .addToContext("mailbox", request.getMailboxName())
+            .addToContext("parameters", request.getStatusDataItems().toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
index 0ec5697..7297957 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
@@ -328,11 +328,11 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
     @Override
     protected Closeable addContextToMDC(StoreRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "STORE")
-            .addContext("ranges", IdRange.toString(message.getIdSet()))
-            .addContext("useUids", message.isUseUids())
-            .addContext("unchangedSince", message.getUnchangedSince())
-            .addContext("isSilent", message.isSilent())
+            .addToContext(MDCBuilder.ACTION, "STORE")
+            .addToContext("ranges", IdRange.toString(message.getIdSet()))
+            .addToContext("useUids", Boolean.toString(message.isUseUids()))
+            .addToContext("unchangedSince", Long.toString(message.getUnchangedSince()))
+            .addToContext("isSilent", Boolean.toString(message.isSilent()))
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SubscribeProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SubscribeProcessor.java
index 4683879..c977d7c 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SubscribeProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SubscribeProcessor.java
@@ -63,8 +63,8 @@ public class SubscribeProcessor extends AbstractSubscriptionProcessor<SubscribeR
     @Override
     protected Closeable addContextToMDC(SubscribeRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SUBSCRIBE")
-            .addContext("mailbox", message.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "SUBSCRIBE")
+            .addToContext("mailbox", message.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SystemMessageProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SystemMessageProcessor.java
index 71b9112..291ae95 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SystemMessageProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SystemMessageProcessor.java
@@ -75,8 +75,8 @@ public class SystemMessageProcessor extends AbstractChainedProcessor<SystemMessa
     @Override
     protected Closeable addContextToMDC(SystemMessage message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SYSTEM_MESSAGE")
-            .addContext("message", message)
+            .addToContext(MDCBuilder.ACTION, "SYSTEM_MESSAGE")
+            .addToContext("message", message.toString())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java
index f6fa95a..fc3237a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java
@@ -66,7 +66,7 @@ public class UnselectProcessor extends AbstractMailboxProcessor<UnselectRequest>
 
     @Override
     protected Closeable addContextToMDC(UnselectRequest request) {
-        return MDCBuilder.of(MDCBuilder.ACTION, "UNSELECT")
+        return MDCBuilder.ofValue(MDCBuilder.ACTION, "UNSELECT")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/UnsubscribeProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/UnsubscribeProcessor.java
index e90bbc7..77aeb3d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/UnsubscribeProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/UnsubscribeProcessor.java
@@ -64,8 +64,8 @@ public class UnsubscribeProcessor extends AbstractSubscriptionProcessor<Unsubscr
     @Override
     protected Closeable addContextToMDC(UnsubscribeRequest message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "UNSUBSCRIBE")
-            .addContext("mailbox", message.getMailboxName())
+            .addToContext(MDCBuilder.ACTION, "UNSUBSCRIBE")
+            .addToContext("mailbox", message.getMailboxName())
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/ImapResponseMessageProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/ImapResponseMessageProcessor.java
index d6d28be..98abd1d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/ImapResponseMessageProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/ImapResponseMessageProcessor.java
@@ -40,7 +40,7 @@ public class ImapResponseMessageProcessor extends AbstractChainedProcessor<ImapR
     @Override
     protected Closeable addContextToMDC(ImapResponseMessage message) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "RESPOND")
+            .addToContext(MDCBuilder.ACTION, "RESPOND")
             .build();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
index f60bc02..8be367d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
@@ -223,10 +223,10 @@ public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {
     @Override
     protected Closeable addContextToMDC(FetchRequest request) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "FETCH")
-            .addContext("useUid", request.isUseUids())
-            .addContext("idSet", IdRange.toString(request.getIdSet()))
-            .addContext("fetchedData", request.getFetch())
+            .addToContext(MDCBuilder.ACTION, "FETCH")
+            .addToContext("useUid", Boolean.toString(request.isUseUids()))
+            .addToContext("idSet", IdRange.toString(request.getIdSet()))
+            .addToContext("fetchedData", request.getFetch().toString())
             .build();
     }
 }
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java
index d277b08..7e1e9df 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/ProtocolMDCContextFactory.java
@@ -42,10 +42,10 @@ public interface ProtocolMDCContextFactory {
 
     static MDCBuilder mdcContext(Protocol protocol, ChannelHandlerContext ctx) {
         return MDCBuilder.create()
-            .addContext(from(ctx.getAttachment()))
-            .addContext(MDCBuilder.PROTOCOL, protocol.getName())
-            .addContext(MDCBuilder.IP, retrieveIp(ctx))
-            .addContext(MDCBuilder.HOST, retrieveHost(ctx));
+            .addToContext(from(ctx.getAttachment()))
+            .addToContext(MDCBuilder.PROTOCOL, protocol.getName())
+            .addToContext(MDCBuilder.IP, retrieveIp(ctx))
+            .addToContext(MDCBuilder.HOST, retrieveHost(ctx));
     }
 
     private static String retrieveIp(ChannelHandlerContext ctx) {
@@ -76,9 +76,9 @@ public interface ProtocolMDCContextFactory {
 
     static MDCBuilder forSession(ProtocolSession protocolSession) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.SESSION_ID, protocolSession.getSessionID())
-            .addContext(MDCBuilder.CHARSET, protocolSession.getCharset().displayName())
-            .addContext(MDCBuilder.USER, Optional.ofNullable(protocolSession.getUsername()).map(Username::asString));
+            .addToContext(MDCBuilder.SESSION_ID, protocolSession.getSessionID())
+            .addToContext(MDCBuilder.CHARSET, protocolSession.getCharset().displayName())
+            .addToContextIfPresent(MDCBuilder.USER, Optional.ofNullable(protocolSession.getUsername()).map(Username::asString));
     }
 
 }
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/AbstractPassCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/AbstractPassCmdHandler.java
index ba70287..709fcc4 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/AbstractPassCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/AbstractPassCmdHandler.java
@@ -60,8 +60,8 @@ public abstract class AbstractPassCmdHandler extends RsetCmdHandler {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-pass", () ->
             MDCBuilder.withMdc(
             MDCBuilder.create()
-                .addContext(MDCBuilder.ACTION, "AUTH")
-                .addContext(MDCConstants.withSession(session)),
+                .addToContext(MDCBuilder.ACTION, "AUTH")
+                .addToContext(MDCConstants.withSession(session)),
             () -> doAuth(session, request)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CapaCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CapaCmdHandler.java
index 8c93abc..9b90529 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CapaCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/CapaCmdHandler.java
@@ -57,8 +57,8 @@ public class CapaCmdHandler implements CommandHandler<POP3Session>, ExtensibleHa
     public Response onCommand(POP3Session session, Request request) {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-capa", () ->
             MDCBuilder.withMdc(MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "CAPA")
-                    .addContext(MDCConstants.withSession(session)),
+                    .addToContext(MDCBuilder.ACTION, "CAPA")
+                    .addToContext(MDCConstants.withSession(session)),
                 () -> capa(session)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/DeleCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/DeleCmdHandler.java
index cdc0771..c27f847 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/DeleCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/DeleCmdHandler.java
@@ -62,9 +62,9 @@ public class DeleCmdHandler implements CommandHandler<POP3Session> {
     public Response onCommand(POP3Session session, Request request) {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-dele", () ->
             MDCBuilder.withMdc(MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "DELE")
-                    .addContext(MDCConstants.withSession(session))
-                    .addContext(MDCConstants.forRequest(request)),
+                    .addToContext(MDCBuilder.ACTION, "DELE")
+                    .addToContext(MDCConstants.withSession(session))
+                    .addToContext(MDCConstants.forRequest(request)),
                 () -> delete(session, request)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/ListCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/ListCmdHandler.java
index 60649de..76600ee 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/ListCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/ListCmdHandler.java
@@ -68,9 +68,9 @@ public class ListCmdHandler implements CommandHandler<POP3Session> {
     public Response onCommand(POP3Session session, Request request) {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-list", () ->
             MDCBuilder.withMdc(MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "LIST")
-                    .addContext(MDCConstants.withSession(session))
-                    .addContext(MDCConstants.forRequest(request)),
+                    .addToContext(MDCBuilder.ACTION, "LIST")
+                    .addToContext(MDCConstants.withSession(session))
+                    .addToContext(MDCConstants.forRequest(request)),
                 () -> list(session, request)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/MDCConstants.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/MDCConstants.java
index f6a1c00..92943a2 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/MDCConstants.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/MDCConstants.java
@@ -36,19 +36,19 @@ public interface MDCConstants {
     static MDCBuilder withMailbox(POP3Session session) {
         return Optional.ofNullable(session.getUserMailbox())
             .map(Throwing.function(Mailbox::getIdentifier).sneakyThrow())
-            .map(id -> MDCBuilder.create().addContext(MAILBOX, id))
+            .map(id -> MDCBuilder.create().addToContext(MAILBOX, id))
             .orElseGet(MDCBuilder::create);
     }
 
     static MDCBuilder forRequest(Request request) {
         return Optional.ofNullable(request.getArgument())
-            .map(argument -> MDCBuilder.create().addContext(ARGUMENT, argument))
+            .map(argument -> MDCBuilder.create().addToContext(ARGUMENT, argument))
             .orElseGet(MDCBuilder::create);
     }
 
     static MDCBuilder withSession(POP3Session session) {
         return MDCBuilder.create()
-            .addContext(withMailbox(session))
-            .addContext(STATE, session.getHandlerState());
+            .addToContext(withMailbox(session))
+            .addToContext(STATE, Integer.toString(session.getHandlerState()));
     }
 }
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/NoopCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/NoopCmdHandler.java
index 4bdc7b5..9c9a0f6 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/NoopCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/NoopCmdHandler.java
@@ -58,8 +58,8 @@ public class NoopCmdHandler implements CommandHandler<POP3Session> {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-noop", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "NOOP")
-                    .addContext(MDCConstants.withSession(session)),
+                    .addToContext(MDCBuilder.ACTION, "NOOP")
+                    .addToContext(MDCConstants.withSession(session)),
                 () -> noop(session)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java
index 902ae72..7ed2ea1 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java
@@ -75,8 +75,8 @@ public class QuitCmdHandler implements CommandHandler<POP3Session> {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-quit", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "QUIT")
-                    .addContext(MDCConstants.withSession(session)),
+                    .addToContext(MDCBuilder.ACTION, "QUIT")
+                    .addToContext(MDCConstants.withSession(session)),
                 () -> quit(session)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java
index fc05faa..416bd51 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java
@@ -70,9 +70,9 @@ public class RetrCmdHandler implements CommandHandler<POP3Session> {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-retr", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "RETR")
-                    .addContext(MDCConstants.withSession(session))
-                    .addContext(MDCConstants.forRequest(request)),
+                    .addToContext(MDCBuilder.ACTION, "RETR")
+                    .addToContext(MDCConstants.withSession(session))
+                    .addToContext(MDCConstants.forRequest(request)),
                 () -> retr(session, request)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java
index 003e0d0..45c81b0 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java
@@ -63,8 +63,8 @@ public class RsetCmdHandler implements CommandHandler<POP3Session> {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-rset", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "RSET")
-                    .addContext(MDCConstants.withSession(session)),
+                    .addToContext(MDCBuilder.ACTION, "RSET")
+                    .addToContext(MDCConstants.withSession(session)),
                 () -> rset(session)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java
index c2a3e83..85032ee 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java
@@ -63,8 +63,8 @@ public class StatCmdHandler implements CommandHandler<POP3Session> {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-stat", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "STAT")
-                    .addContext(MDCConstants.withSession(session)),
+                    .addToContext(MDCBuilder.ACTION, "STAT")
+                    .addToContext(MDCConstants.withSession(session)),
                 () -> stat(session)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java
index 7e5ab10..6f3a57c 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java
@@ -61,8 +61,8 @@ public class StlsCmdHandler implements CommandHandler<POP3Session>, CapaCapabili
         return metricFactory.decorateSupplierWithTimerMetric("pop3-stls", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "START_TLS")
-                    .addContext(MDCConstants.withSession(session)),
+                    .addToContext(MDCBuilder.ACTION, "START_TLS")
+                    .addToContext(MDCConstants.withSession(session)),
                 () -> stls(session)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java
index f7d8a52..3a56360 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java
@@ -76,9 +76,9 @@ public class TopCmdHandler extends RetrCmdHandler implements CapaCapability {
         return metricFactory.decorateSupplierWithTimerMetric("pop3-top", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "TOP")
-                    .addContext(MDCConstants.withSession(session))
-                    .addContext(MDCConstants.forRequest(request)),
+                    .addToContext(MDCBuilder.ACTION, "TOP")
+                    .addToContext(MDCConstants.withSession(session))
+                    .addToContext(MDCConstants.forRequest(request)),
                 () -> top(session, request)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java
index feee247..0fd140c 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java
@@ -66,9 +66,9 @@ public class UidlCmdHandler implements CommandHandler<POP3Session>, CapaCapabili
         return metricFactory.decorateSupplierWithTimerMetric("pop3-uidl", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "UIDL")
-                    .addContext(MDCConstants.withSession(session))
-                    .addContext(MDCConstants.forRequest(request)),
+                    .addToContext(MDCBuilder.ACTION, "UIDL")
+                    .addToContext(MDCConstants.withSession(session))
+                    .addToContext(MDCConstants.forRequest(request)),
                 () -> uidl(session, request)));
     }
 
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java
index 7ec03f4..38b4789 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java
@@ -42,9 +42,9 @@ public class UnknownCmdHandler extends UnknownCommandHandler<POP3Session> {
     public Response onCommand(POP3Session session, Request request) {
         MDCBuilder.withMdc(
             MDCBuilder.create()
-                .addContext(MDCBuilder.ACTION, request.getCommand())
-                .addContext(MDCConstants.withSession(session))
-                .addContext(MDCConstants.forRequest(request)),
+                .addToContext(MDCBuilder.ACTION, request.getCommand())
+                .addToContext(MDCConstants.withSession(session))
+                .addToContext(MDCConstants.forRequest(request)),
             () -> LOGGER.info("Unknown command received"));
         return POP3Response.ERR;
     }
diff --git a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java
index 5980485..bd5a438 100644
--- a/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java
+++ b/protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java
@@ -61,9 +61,9 @@ public class UserCmdHandler implements CommandHandler<POP3Session>, CapaCapabili
         return metricFactory.decorateSupplierWithTimerMetric("pop3-user", () ->
             MDCBuilder.withMdc(
                 MDCBuilder.create()
-                    .addContext(MDCBuilder.ACTION, "USER")
-                    .addContext(MDCConstants.withSession(session))
-                    .addContext(MDCConstants.forRequest(request)),
+                    .addToContext(MDCBuilder.ACTION, "USER")
+                    .addToContext(MDCConstants.withSession(session))
+                    .addToContext(MDCConstants.forRequest(request)),
                 () -> user(session, request)));
     }
 
diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractHookableCmdHandler.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractHookableCmdHandler.java
index 4497ef6..9c2ce2a 100644
--- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractHookableCmdHandler.java
+++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/AbstractHookableCmdHandler.java
@@ -67,7 +67,7 @@ public abstract class AbstractHookableCmdHandler<HookT extends org.apache.james.
 
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.ACTION, command)
+                     .addToContext(MDCBuilder.ACTION, command)
                      .build()) {
             Response response = doFilterChecks(session, command, parameters);
             if (response == null) {
diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/DataCmdHandler.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/DataCmdHandler.java
index d93b22f..1a085f4 100644
--- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/DataCmdHandler.java
+++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/DataCmdHandler.java
@@ -132,7 +132,7 @@ public class DataCmdHandler implements CommandHandler<SMTPSession>, ExtensibleHa
         session.stopDetectingCommandInjection();
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.ACTION, request.getCommand())
+                     .addToContext(MDCBuilder.ACTION, request.getCommand())
                      .build()) {
             String parameters = request.getArgument();
             Response response = doDATAFilter(session, parameters);
diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java
index 58fbe85..97b1094 100644
--- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java
+++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/SMTPMDCContextFactory.java
@@ -20,6 +20,7 @@
 package org.apache.james.protocols.smtp.core;
 
 import java.io.Closeable;
+import java.util.Objects;
 import java.util.Optional;
 
 import org.apache.james.core.MaybeSender;
@@ -34,15 +35,15 @@ public class SMTPMDCContextFactory implements ProtocolMDCContextFactory {
 
     public Closeable from(Protocol protocol, ChannelHandlerContext ctx) {
         return MDCBuilder.create()
-            .addContext(ProtocolMDCContextFactory.mdcContext(protocol, ctx))
-            .addContext(from(ctx.getAttachment()))
+            .addToContext(ProtocolMDCContextFactory.mdcContext(protocol, ctx))
+            .addToContext(from(ctx.getAttachment()))
             .build();
     }
 
     public static MDCBuilder forSession(SMTPSession smtpSession) {
         return MDCBuilder.create()
-            .addContext(ProtocolMDCContextFactory.forSession(smtpSession))
-            .addContext(forSMTPSession(smtpSession));
+            .addToContext(ProtocolMDCContextFactory.forSession(smtpSession))
+            .addToContext(forSMTPSession(smtpSession));
     }
 
     private MDCBuilder from(Object o) {
@@ -55,9 +56,10 @@ public class SMTPMDCContextFactory implements ProtocolMDCContextFactory {
 
     private static MDCBuilder forSMTPSession(SMTPSession smtpSession) {
         return MDCBuilder.create()
-            .addContext("ehlo", smtpSession.getAttachment(SMTPSession.CURRENT_HELO_NAME, ProtocolSession.State.Connection))
-            .addContext("sender", smtpSession.getAttachment(SMTPSession.SENDER, ProtocolSession.State.Transaction)
+            .addToContextIfPresent("ehlo", smtpSession.getAttachment(SMTPSession.CURRENT_HELO_NAME, ProtocolSession.State.Connection))
+            .addToContextIfPresent("sender", smtpSession.getAttachment(SMTPSession.SENDER, ProtocolSession.State.Transaction)
                 .map(MaybeSender::asString))
-            .addContext("recipients", smtpSession.getAttachment(SMTPSession.RCPT_LIST, ProtocolSession.State.Transaction));
+            .addToContextIfPresent("recipients", smtpSession.getAttachment(SMTPSession.RCPT_LIST, ProtocolSession.State.Transaction)
+                .map(Objects::toString));
     }
 }
diff --git a/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java b/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
index 4fdcf85..67e45fe 100644
--- a/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
+++ b/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxDataProbe.java
@@ -58,9 +58,9 @@ public class JmxDataProbe implements JmxProbe {
     public void addUser(String userName, String password) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "addUser")
-                     .addContext("parameter", userName)
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "addUser")
+                     .addToContext("parameter", userName)
                      .build()) {
             usersRepositoryProxy.addUser(userName, password);
         }
@@ -69,9 +69,9 @@ public class JmxDataProbe implements JmxProbe {
     public void removeUser(String username) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "removeUser")
-                     .addContext("parameter", username)
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "removeUser")
+                     .addToContext("parameter", username)
                      .build()) {
             usersRepositoryProxy.deleteUser(username);
         }
@@ -80,8 +80,8 @@ public class JmxDataProbe implements JmxProbe {
     public String[] listUsers() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "listUsers")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "listUsers")
                      .build()) {
             return usersRepositoryProxy.listAllUsers();
         }
@@ -90,9 +90,9 @@ public class JmxDataProbe implements JmxProbe {
     public void setPassword(String userName, String password) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "setPassword")
-                     .addContext("parameter", userName)
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "setPassword")
+                     .addToContext("parameter", userName)
                      .build()) {
             usersRepositoryProxy.setPassword(userName, password);
         }
@@ -101,9 +101,9 @@ public class JmxDataProbe implements JmxProbe {
     public boolean containsDomain(String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "containsDomain")
-                     .addContext("parameter", domain)
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "containsDomain")
+                     .addToContext("parameter", domain)
                      .build()) {
             return domainListProxy.containsDomain(domain);
         }
@@ -112,9 +112,9 @@ public class JmxDataProbe implements JmxProbe {
     public void addDomain(String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "addDomain")
-                     .addContext("parameter", domain)
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "addDomain")
+                     .addToContext("parameter", domain)
                      .build()) {
             domainListProxy.addDomain(domain);
         }
@@ -123,9 +123,9 @@ public class JmxDataProbe implements JmxProbe {
     public void removeDomain(String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "removeDomain")
-                     .addContext("parameter", domain)
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "removeDomain")
+                     .addToContext("parameter", domain)
                      .build()) {
             domainListProxy.removeDomain(domain);
         }
@@ -134,8 +134,8 @@ public class JmxDataProbe implements JmxProbe {
     public List<String> listDomains() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "listDomains")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "listDomains")
                      .build()) {
             return domainListProxy.getDomains();
         }
@@ -144,8 +144,8 @@ public class JmxDataProbe implements JmxProbe {
     public Map<String, Mappings> listMappings() throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "listMappings")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "listMappings")
                      .build()) {
             return virtualUserTableProxy.getAllMappings();
         }
@@ -154,8 +154,8 @@ public class JmxDataProbe implements JmxProbe {
     public void addAddressMapping(String fromUser, String fromDomain, String toAddress) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "addAddressMapping")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "addAddressMapping")
                      .build()) {
             virtualUserTableProxy.addAddressMapping(fromUser, fromDomain, toAddress);
         }
@@ -164,8 +164,8 @@ public class JmxDataProbe implements JmxProbe {
     public void removeAddressMapping(String fromUser, String fromDomain, String toAddress) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "removeAddressMapping")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "removeAddressMapping")
                      .build()) {
             virtualUserTableProxy.removeAddressMapping(fromUser, fromDomain, toAddress);
         }
@@ -174,8 +174,8 @@ public class JmxDataProbe implements JmxProbe {
     public Mappings listUserDomainMappings(String user, String domain) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "listUserDomainMappings")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "listUserDomainMappings")
                      .build()) {
             return virtualUserTableProxy.getUserDomainMappings(user, domain);
         }
@@ -184,8 +184,8 @@ public class JmxDataProbe implements JmxProbe {
     public void addRegexMapping(String user, String domain, String regex) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "addRegexMapping")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "addRegexMapping")
                      .build()) {
             virtualUserTableProxy.addRegexMapping(user, domain, regex);
         }
@@ -194,8 +194,8 @@ public class JmxDataProbe implements JmxProbe {
     public void removeRegexMapping(String user, String domain, String regex) throws Exception {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, JMX)
-                     .addContext(MDCBuilder.ACTION, "removeRegexMapping")
+                     .addToContext(MDCBuilder.PROTOCOL, JMX)
+                     .addToContext(MDCBuilder.ACTION, "removeRegexMapping")
                      .build()) {
             virtualUserTableProxy.removeRegexMapping(user, domain, regex);
         }
diff --git a/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/MailboxManagerManagement.java b/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/MailboxManagerManagement.java
index 91a4f6e..d6b468a 100644
--- a/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/MailboxManagerManagement.java
+++ b/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/MailboxManagerManagement.java
@@ -73,9 +73,9 @@ public class MailboxManagerManagement extends StandardMBean implements MailboxMa
         MailboxSession session = null;
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "deleteMailboxes")
-                     .addContext("concernedUser", username)
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "deleteMailboxes")
+                     .addToContext("concernedUser", username)
                      .build()) {
             session = mailboxManager.createSystemSession(Username.of(username));
             mailboxManager.startProcessingRequest(session);
@@ -101,9 +101,9 @@ public class MailboxManagerManagement extends StandardMBean implements MailboxMa
         MailboxSession session = null;
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "listMailboxes")
-                     .addContext("concernedUser", username)
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "listMailboxes")
+                     .addToContext("concernedUser", username)
                      .build()) {
             session = mailboxManager.createSystemSession(Username.of(username));
             mailboxManager.startProcessingRequest(session);
@@ -130,9 +130,9 @@ public class MailboxManagerManagement extends StandardMBean implements MailboxMa
         MailboxPath mailboxPath = new MailboxPath(namespace, username, name);
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "createMailbox")
-                     .addContext("mailboxPath", mailboxPath.asString())
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "createMailbox")
+                     .addToContext("mailboxPath", mailboxPath.asString())
                      .build()) {
             session = mailboxManager.createSystemSession(username);
             mailboxManager.startProcessingRequest(session);
@@ -154,9 +154,9 @@ public class MailboxManagerManagement extends StandardMBean implements MailboxMa
         MailboxPath mailboxPath = new MailboxPath(namespace, username, name);
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "deleteMailbox")
-                     .addContext("mailboxPath", mailboxPath.asString())
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "deleteMailbox")
+                     .addToContext("mailboxPath", mailboxPath.asString())
                      .build()) {
             session = mailboxManager.createSystemSession(username);
             mailboxManager.startProcessingRequest(session);
@@ -178,10 +178,10 @@ public class MailboxManagerManagement extends StandardMBean implements MailboxMa
         MailboxPath mailboxPath = new MailboxPath(namespace, username, name);
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "importEmlFileToMailbox")
-                     .addContext("mailboxPath", mailboxPath.asString())
-                     .addContext("emlPath", emlPath)
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "importEmlFileToMailbox")
+                     .addToContext("mailboxPath", mailboxPath.asString())
+                     .addToContext("emlPath", emlPath)
                      .build()) {
             session = mailboxManager.createSystemSession(username);
             mailboxManager.startProcessingRequest(session);
diff --git a/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/QuotaManagement.java b/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/QuotaManagement.java
index 564b45b..2bf790c 100644
--- a/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/QuotaManagement.java
+++ b/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/QuotaManagement.java
@@ -57,8 +57,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public String getQuotaRoot(String namespace, String user, String name) throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getQuotaRoot")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getQuotaRoot")
                      .build()) {
             return quotaRootResolver.getQuotaRoot(new MailboxPath(namespace, Username.of(user), name)).getValue();
         } catch (IOException e) {
@@ -70,8 +70,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public SerializableQuotaLimitValue<QuotaCountLimit> getMaxMessageCount(String quotaRoot) throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getMaxMessageCount")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getMaxMessageCount")
                      .build()) {
             return SerializableQuotaLimitValue.valueOf(maxQuotaManager.getMaxMessage(quotaRootResolver.fromString(quotaRoot)));
         } catch (IOException e) {
@@ -83,8 +83,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public SerializableQuotaLimitValue<QuotaSizeLimit> getMaxStorage(String quotaRoot) throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getMaxStorage")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getMaxStorage")
                      .build()) {
             return SerializableQuotaLimitValue.valueOf(maxQuotaManager.getMaxStorage(quotaRootResolver.fromString(quotaRoot)));
         } catch (IOException e) {
@@ -96,8 +96,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public SerializableQuotaLimitValue<QuotaCountLimit> getGlobalMaxMessageCount() throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getGlobalMaxMessageCount")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getGlobalMaxMessageCount")
                      .build()) {
             return SerializableQuotaLimitValue.valueOf(maxQuotaManager.getGlobalMaxMessage());
         } catch (IOException e) {
@@ -109,8 +109,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public SerializableQuotaLimitValue<QuotaSizeLimit> getGlobalMaxStorage() throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getGlobalMaxStorage")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getGlobalMaxStorage")
                      .build()) {
             return SerializableQuotaLimitValue.valueOf(maxQuotaManager.getGlobalMaxStorage());
         } catch (IOException e) {
@@ -122,8 +122,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public void setMaxMessageCount(String quotaRoot, SerializableQuotaLimitValue<QuotaCountLimit> maxMessageCount) {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "setMaxMessageCount")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "setMaxMessageCount")
                      .build()) {
             maxMessageCount.toValue(QuotaCountLimit::count, QuotaCountLimit.unlimited())
                 .ifPresent(
@@ -139,8 +139,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public void setMaxStorage(String quotaRoot, SerializableQuotaLimitValue<QuotaSizeLimit> maxSize) {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "setMaxStorage")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "setMaxStorage")
                      .build()) {
             maxSize.toValue(QuotaSizeLimit::size, QuotaSizeLimit.unlimited())
                 .ifPresent(
@@ -156,8 +156,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public void setGlobalMaxMessageCount(SerializableQuotaLimitValue<QuotaCountLimit> maxGlobalMessageCount) {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "setGlobalMaxMessageCount")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "setGlobalMaxMessageCount")
                      .build()) {
             maxGlobalMessageCount
                 .toValue(QuotaCountLimit::count, QuotaCountLimit.unlimited())
@@ -171,8 +171,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public void setGlobalMaxStorage(SerializableQuotaLimitValue<QuotaSizeLimit> maxGlobalSize) {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "setGlobalMaxStorage")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "setGlobalMaxStorage")
                      .build()) {
             maxGlobalSize
                 .toValue(QuotaSizeLimit::size, QuotaSizeLimit.unlimited())
@@ -186,8 +186,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public SerializableQuota<QuotaCountLimit, QuotaCountUsage> getMessageCountQuota(String quotaRoot) throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getMessageCountQuota")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getMessageCountQuota")
                      .build()) {
             return SerializableQuota.newInstance(quotaManager.getMessageQuota(quotaRootResolver.fromString(quotaRoot)));
         } catch (IOException e) {
@@ -199,8 +199,8 @@ public class QuotaManagement implements QuotaManagementMBean {
     public SerializableQuota<QuotaSizeLimit, QuotaSizeUsage> getStorageQuota(String quotaRoot) throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "getStorageQuota")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "getStorageQuota")
                      .build()) {
             return SerializableQuota.newInstance(quotaManager.getStorageQuota(quotaRootResolver.fromString(quotaRoot)));
         } catch (IOException e) {
diff --git a/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/ReIndexerManagement.java b/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/ReIndexerManagement.java
index 2612d01..55c9f2f 100644
--- a/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/ReIndexerManagement.java
+++ b/server/container/mailbox-jmx/src/main/java/org/apache/james/adapter/mailbox/ReIndexerManagement.java
@@ -51,8 +51,8 @@ public class ReIndexerManagement implements ReIndexerManagementMBean {
     public void reIndex(String namespace, String user, String name) throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "reIndex")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "reIndex")
                      .build()) {
             TaskId taskId = taskManager.submit(reIndexer.reIndex(new MailboxPath(namespace, Username.of(user), name), RunningOptions.DEFAULT));
             taskManager.await(taskId, Duration.of(365, ChronoUnit.DAYS));
@@ -65,8 +65,8 @@ public class ReIndexerManagement implements ReIndexerManagementMBean {
     public void reIndex() throws MailboxException {
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "CLI")
-                     .addContext(MDCBuilder.ACTION, "reIndex")
+                     .addToContext(MDCBuilder.PROTOCOL, "CLI")
+                     .addToContext(MDCBuilder.ACTION, "reIndex")
                      .build()) {
             TaskId taskId = taskManager.submit(reIndexer.reIndex(RunningOptions.DEFAULT));
             taskManager.await(taskId, Duration.of(365, ChronoUnit.DAYS));
diff --git a/server/container/mailbox-jmx/src/test/java/org/apache/james/adapter/mailbox/ReIndexerManagementTest.java b/server/container/mailbox-jmx/src/test/java/org/apache/james/adapter/mailbox/ReIndexerManagementTest.java
index caaf162..5430491 100644
--- a/server/container/mailbox-jmx/src/test/java/org/apache/james/adapter/mailbox/ReIndexerManagementTest.java
+++ b/server/container/mailbox-jmx/src/test/java/org/apache/james/adapter/mailbox/ReIndexerManagementTest.java
@@ -21,7 +21,6 @@ package org.apache.james.adapter.mailbox;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -34,6 +33,7 @@ import org.apache.james.task.Hostname;
 import org.apache.james.task.MemoryTaskManager;
 import org.apache.james.task.Task;
 import org.apache.james.task.TaskManager;
+import org.apache.james.task.TaskType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -51,8 +51,17 @@ public class ReIndexerManagementTest {
 
     @Test
     void reIndexMailboxShouldWaitsForExecution() throws Exception {
-        Task task = mock(Task.class);
-        doReturn(Task.Result.COMPLETED).when(task).run();
+        Task task = new Task() {
+            @Override
+            public Result run() {
+                return Task.Result.COMPLETED;
+            }
+
+            @Override
+            public TaskType type() {
+                return TaskType.of("FakeReindexing");
+            }
+        };
         String namespace = "namespace";
         String user = "user";
         String name = "name";
@@ -66,8 +75,17 @@ public class ReIndexerManagementTest {
 
     @Test
     void reIndexShouldWaitsForExecution() throws Exception {
-        Task task = mock(Task.class);
-        doReturn(Task.Result.COMPLETED).when(task).run();
+        Task task = new Task() {
+            @Override
+            public Result run() {
+                return Task.Result.COMPLETED;
+            }
+
+            @Override
+            public TaskType type() {
+                return TaskType.of("FakeReindexing");
+            }
+        };
         when(reIndexer.reIndex(any(RunningOptions.class))).thenReturn(task);
 
         assertThat(taskManager.list()).isEmpty();
diff --git a/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java b/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java
index 9bf6c5b..aefb7f7 100644
--- a/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java
+++ b/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java
@@ -98,11 +98,25 @@ public class MDCBuilder {
         return new MDCBuilder();
     }
 
+    /**
+     * Using Object::toString causes undesired formatting issues and might lead to complex formatting logic.
+     * We migrated to explicit Strings instead.
+     *
+     * See https://issues.apache.org/jira/browse/JAMES-3587
+     *
+     * Use {@link MDCBuilder::ofValue} instead.
+     */
+    @Deprecated
     public static MDCBuilder of(String key, Object value) {
         return create()
             .addContext(key, value);
     }
 
+    public static MDCBuilder ofValue(String key, String value) {
+        return create()
+            .addToContext(key, value);
+    }
+
     private final ImmutableMap.Builder<String, String> contextMap = ImmutableMap.builder();
     private final ImmutableList.Builder<MDCBuilder> nestedBuilder = ImmutableList.builder();
 
@@ -110,11 +124,28 @@ public class MDCBuilder {
 
     }
 
+    /**
+     * Renamed to preserve a coherent semantic.
+     *
+     * See https://issues.apache.org/jira/browse/JAMES-3587
+     *
+     * Use {@link MDCBuilder::addToContext} instead.
+     */
+    @Deprecated
     public MDCBuilder addContext(MDCBuilder nested) {
         this.nestedBuilder.add(nested);
         return this;
     }
 
+    /**
+     * Using Object::toString causes undesired formatting issues and might lead to complex formatting logic.
+     * We migrated to explicit Strings instead.
+     *
+     * See https://issues.apache.org/jira/browse/JAMES-3587
+     *
+     * Use {@link MDCBuilder::addToContext} instead.
+     */
+    @Deprecated
     public MDCBuilder addContext(String key, Object value) {
         Preconditions.checkNotNull(key);
         Optional.ofNullable(value)
@@ -122,6 +153,23 @@ public class MDCBuilder {
         return this;
     }
 
+    public MDCBuilder addToContext(MDCBuilder nested) {
+        this.nestedBuilder.add(nested);
+        return this;
+    }
+
+    public MDCBuilder addToContextIfPresent(String key, Optional<String> value) {
+        Preconditions.checkNotNull(key);
+        value.ifPresent(nonNullValue -> contextMap.put(key, nonNullValue));
+        return this;
+    }
+
+    public MDCBuilder addToContext(String key, String value) {
+        Preconditions.checkNotNull(key);
+        Optional.ofNullable(value).ifPresent(nonNullValue -> contextMap.put(key, nonNullValue));
+        return this;
+    }
+
     @VisibleForTesting
     Map<String, String> buildContextMap() {
         return ImmutableMap.<String, String>builder()
diff --git a/server/container/util/src/main/java/org/apache/james/util/MDCStructuredLogger.java b/server/container/util/src/main/java/org/apache/james/util/MDCStructuredLogger.java
index cf970ea..887e3a7 100644
--- a/server/container/util/src/main/java/org/apache/james/util/MDCStructuredLogger.java
+++ b/server/container/util/src/main/java/org/apache/james/util/MDCStructuredLogger.java
@@ -37,6 +37,15 @@ public class MDCStructuredLogger implements StructuredLogger {
         this.mdcBuilder = MDCBuilder.create();
     }
 
+    /**
+     * Using Object::toString causes undesired formatting issues and might lead to complex formatting logic.
+     * We migrated to explicit Strings instead.
+     *
+     * See https://issues.apache.org/jira/browse/JAMES-3587
+     *
+     * Use {@link MDCStructuredLogger::field} instead
+     */
+    @Deprecated
     @Override
     public StructuredLogger addField(String name, Object value) {
         mdcBuilder.addContext(name, value);
@@ -44,6 +53,12 @@ public class MDCStructuredLogger implements StructuredLogger {
     }
 
     @Override
+    public StructuredLogger field(String name, String value) {
+        mdcBuilder.addToContext(name, value);
+        return this;
+    }
+
+    @Override
     public void log(Consumer<Logger> logOperation) {
         MDCBuilder.withMdc(mdcBuilder, () -> logOperation.accept(logger));
     }
diff --git a/server/container/util/src/main/java/org/apache/james/util/ReactorUtils.java b/server/container/util/src/main/java/org/apache/james/util/ReactorUtils.java
index c11a9d4..2d2b5a3 100644
--- a/server/container/util/src/main/java/org/apache/james/util/ReactorUtils.java
+++ b/server/container/util/src/main/java/org/apache/james/util/ReactorUtils.java
@@ -195,7 +195,7 @@ public class ReactorUtils {
             .filter(entry -> entry.getValue() instanceof MDCBuilder)
             .filter(entry -> ((String) entry.getKey()).startsWith(MDC_KEY_PREFIX))
             .map(entry -> (MDCBuilder) entry.getValue())
-            .reduce(MDCBuilder.create(), MDCBuilder::addContext);
+            .reduce(MDCBuilder.create(), MDCBuilder::addToContext);
     }
 
 }
diff --git a/server/container/util/src/main/java/org/apache/james/util/StructuredLogger.java b/server/container/util/src/main/java/org/apache/james/util/StructuredLogger.java
index f6fcec4..4c7a714 100644
--- a/server/container/util/src/main/java/org/apache/james/util/StructuredLogger.java
+++ b/server/container/util/src/main/java/org/apache/james/util/StructuredLogger.java
@@ -24,7 +24,18 @@ import java.util.function.Consumer;
 import org.slf4j.Logger;
 
 public interface StructuredLogger {
+    /**
+     * Using Object::toString causes undesired formatting issues and might lead to complex formatting logic.
+     * We migrated to explicit Strings instead.
+     *
+     * See https://issues.apache.org/jira/browse/JAMES-3587
+     *
+     * Use {@link StructuredLogger::field} instead.
+     */
+    @Deprecated
     StructuredLogger addField(String name, Object value);
 
+    StructuredLogger field(String name, String value);
+
     void log(Consumer<Logger> logOperation);
 }
diff --git a/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java b/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
index af47acb..dad7682 100644
--- a/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
@@ -45,6 +45,14 @@ class MDCBuilderTest {
     }
 
     @Test
+    void addToContextShouldThrowOnNullKey() {
+        assertThatNullPointerException()
+            .isThrownBy(() ->
+                MDCBuilder.create()
+                    .addToContext(null, "any"));
+    }
+
+    @Test
     void buildContextMapShouldReturnEmptyWhenNoContext() {
         assertThat(MDCBuilder.create().buildContextMap())
             .isEmpty();
@@ -54,8 +62,8 @@ class MDCBuilderTest {
     void buildContextMapShouldReturnContext() {
         assertThat(
             MDCBuilder.create()
-                .addContext(KEY_1, VALUE_1)
-                .addContext(KEY_2, VALUE_2)
+                .addToContext(KEY_1, VALUE_1)
+                .addToContext(KEY_2, VALUE_2)
                 .buildContextMap())
             .containsOnlyKeys(KEY_1, KEY_2)
             .containsEntry(KEY_1, VALUE_1)
@@ -66,7 +74,7 @@ class MDCBuilderTest {
     void addContextShouldFilterOutNullValues() {
         assertThat(
             MDCBuilder.create()
-                .addContext(KEY_1, null)
+                .addToContext(KEY_1, null)
                 .buildContextMap())
             .isEmpty();
     }
@@ -75,9 +83,9 @@ class MDCBuilderTest {
     void addContextShouldAllowRecursiveBuild() {
         assertThat(
             MDCBuilder.create()
-                .addContext(KEY_1, VALUE_1)
-                .addContext(MDCBuilder.create()
-                    .addContext(KEY_2, VALUE_2))
+                .addToContext(KEY_1, VALUE_1)
+                .addToContext(MDCBuilder.create()
+                    .addToContext(KEY_2, VALUE_2))
                 .buildContextMap())
             .containsOnlyKeys(KEY_1, KEY_2)
             .containsEntry(KEY_1, VALUE_1)
diff --git a/server/container/util/src/test/java/org/apache/james/util/ReactorUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/ReactorUtilsTest.java
index 448b816..845319a 100644
--- a/server/container/util/src/test/java/org/apache/james/util/ReactorUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/ReactorUtilsTest.java
@@ -648,7 +648,7 @@ class ReactorUtilsTest {
                 .doOnEach(ReactorUtils.log(() -> {
                     assertThat(MDC.get(key)).isEqualTo(value);
                 }))
-                .subscriberContext(ReactorUtils.context("test", MDCBuilder.of(key, value)))
+                .subscriberContext(ReactorUtils.context("test", MDCBuilder.ofValue(key, value)))
                 .blockLast();
         }
 
@@ -662,8 +662,8 @@ class ReactorUtilsTest {
                 .doOnEach(ReactorUtils.log(() -> {
                     assertThat(MDC.get(key)).isEqualTo(value1);
                 }))
-                .subscriberContext(ReactorUtils.context("test", MDCBuilder.of(key, value1)))
-                .subscriberContext(ReactorUtils.context("test", MDCBuilder.of(key, value2)))
+                .subscriberContext(ReactorUtils.context("test", MDCBuilder.ofValue(key, value1)))
+                .subscriberContext(ReactorUtils.context("test", MDCBuilder.ofValue(key, value2)))
                 .blockLast();
         }
 
@@ -679,8 +679,8 @@ class ReactorUtilsTest {
                     assertThat(MDC.get(key1)).isEqualTo(value1);
                     assertThat(MDC.get(key2)).isEqualTo(value2);
                 }))
-                .subscriberContext(ReactorUtils.context("test1", MDCBuilder.of(key1, value1)))
-                .subscriberContext(ReactorUtils.context("test2", MDCBuilder.of(key2, value2)))
+                .subscriberContext(ReactorUtils.context("test1", MDCBuilder.ofValue(key1, value1)))
+                .subscriberContext(ReactorUtils.context("test2", MDCBuilder.ofValue(key2, value2)))
                 .blockLast();
         }
     }
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java
index 51bb14b..0ba3254 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/CamelProcessor.java
@@ -62,14 +62,14 @@ public class CamelProcessor {
         Throwable ex = null;
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.PROTOCOL, "MAILET")
-                     .addContext(MDCBuilder.ACTION, "MAILET")
-                     .addContext(MDCBuilder.HOST, mail.getRemoteHost())
-                     .addContext("state", mail.getState())
-                     .addContext("mailet", mailet.getClass().getSimpleName())
-                     .addContext("mail", mail.getName())
-                     .addContext("recipients", ImmutableList.copyOf(mail.getRecipients()))
-                     .addContext("sender", mail.getMaybeSender())
+                     .addToContext(MDCBuilder.PROTOCOL, "MAILET")
+                     .addToContext(MDCBuilder.ACTION, "MAILET")
+                     .addToContext(MDCBuilder.HOST, mail.getRemoteHost())
+                     .addToContext("state", mail.getState())
+                     .addToContext("mailet", mailet.getClass().getSimpleName())
+                     .addToContext("mail", mail.getName())
+                     .addToContext("recipients", ImmutableList.copyOf(mail.getRecipients()).toString())
+                     .addToContext("sender", mail.getMaybeSender().asString())
                      .build()) {
             MailetPipelineLogging.logBeginOfMailetProcess(mailet, mail);
             mailet.service(mail);
diff --git a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/MatcherSplitter.java b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/MatcherSplitter.java
index 4dd0d13..39bef25 100644
--- a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/MatcherSplitter.java
+++ b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/camel/MatcherSplitter.java
@@ -97,15 +97,15 @@ public class MatcherSplitter {
 
             try (Closeable closeable =
                      MDCBuilder.create()
-                         .addContext(MDCBuilder.PROTOCOL, "MAILET")
-                         .addContext(MDCBuilder.ACTION, "MATCHER")
-                         .addContext(MDCBuilder.IP, mail.getRemoteAddr())
-                         .addContext(MDCBuilder.HOST, mail.getRemoteHost())
-                         .addContext("matcher", matcher.getMatcherInfo())
-                         .addContext("state", mail.getState())
-                         .addContext("mail", mail.getName())
-                         .addContext("recipients", ImmutableList.copyOf(mail.getRecipients()))
-                         .addContext("sender", mail.getMaybeSender())
+                         .addToContext(MDCBuilder.PROTOCOL, "MAILET")
+                         .addToContext(MDCBuilder.ACTION, "MATCHER")
+                         .addToContext(MDCBuilder.IP, mail.getRemoteAddr())
+                         .addToContext(MDCBuilder.HOST, mail.getRemoteHost())
+                         .addToContext("matcher", matcher.getMatcherInfo())
+                         .addToContext("state", mail.getState())
+                         .addToContext("mail", mail.getName())
+                         .addToContext("recipients", ImmutableList.copyOf(mail.getRecipients()).toString())
+                         .addToContext("sender", mail.getMaybeSender().asString())
                          .build()) {
                 // call the matcher
                 matchedRcpts = matcher.match(mail);
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java
index 3273fdf..44fbb16 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetFilterMethod.java
@@ -76,7 +76,7 @@ public class GetFilterMethod implements Method {
 
         return Flux.from(metricFactory.decoratePublisherWithTimerMetric(JMAP_PREFIX + METHOD_NAME.getName(),
             process(methodCallId, mailboxSession, filterRequest)
-                .subscriberContext(context("GET_FILTER", MDCBuilder.of(MDCBuilder.ACTION, "GET_FILTER")))));
+                .subscriberContext(context("GET_FILTER", MDCBuilder.ofValue(MDCBuilder.ACTION, "GET_FILTER")))));
     }
 
     private Mono<JmapResponse> process(MethodCallId methodCallId, MailboxSession mailboxSession, GetFilterRequest request) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java
index 3caf29d..be66d0a 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMailboxesMethod.java
@@ -104,10 +104,10 @@ public class GetMailboxesMethod implements Method {
 
     private MDCBuilder mdc(GetMailboxesRequest mailboxesRequest) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, ACTION)
-            .addContext("accountId", mailboxesRequest.getAccountId())
-            .addContext("mailboxIds", mailboxesRequest.getIds())
-            .addContext("properties", mailboxesRequest.getProperties());
+            .addToContext(MDCBuilder.ACTION, ACTION)
+            .addToContextIfPresent("accountId", mailboxesRequest.getAccountId())
+            .addToContext("mailboxIds", mailboxesRequest.getIds().toString())
+            .addToContext("properties", mailboxesRequest.getProperties().toString());
     }
 
     private Flux<JmapResponse> process(MethodCallId methodCallId, MailboxSession mailboxSession, GetMailboxesRequest mailboxesRequest) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java
index a38d0e4..bbf09d4 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java
@@ -23,6 +23,7 @@ import static org.apache.james.util.ReactorUtils.context;
 
 import java.time.ZonedDateTime;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
@@ -56,6 +57,7 @@ import org.apache.james.util.streams.Limit;
 
 import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
@@ -120,17 +122,22 @@ public class GetMessageListMethod implements Method {
 
     private MDCBuilder mdc(GetMessageListRequest messageListRequest) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "GET_MESSAGE_LIST")
-            .addContext("accountId", messageListRequest.getAccountId())
-            .addContext("limit", messageListRequest.getLimit())
-            .addContext("anchor", messageListRequest.getAnchor())
-            .addContext("offset", messageListRequest.getAnchorOffset())
-            .addContext("properties", messageListRequest.getFetchMessageProperties())
-            .addContext("position", messageListRequest.getPosition())
-            .addContext("filters", messageListRequest.getFilter())
-            .addContext("sorts", messageListRequest.getSort())
-            .addContext("isFetchMessage", messageListRequest.isFetchMessages())
-            .addContext("isCollapseThread", messageListRequest.isCollapseThreads());
+            .addToContext(MDCBuilder.ACTION, "GET_MESSAGE_LIST")
+            .addToContextIfPresent("accountId", messageListRequest.getAccountId())
+            .addToContextIfPresent("limit", messageListRequest.getLimit()
+                .map(Number::asLong).map(l -> Long.toString(l)))
+            .addToContextIfPresent("anchor", messageListRequest.getAnchor())
+            .addToContextIfPresent("offset", messageListRequest.getAnchorOffset()
+                .map(Number::asLong).map(l -> Long.toString(l)))
+            .addToContext("properties", Joiner.on(", ")
+                .join(messageListRequest.getFetchMessageProperties()))
+            .addToContextIfPresent("position", messageListRequest.getPosition()
+                .map(Number::asLong).map(l -> Long.toString(l)))
+            .addToContextIfPresent("filters", messageListRequest.getFilter().map(Objects::toString))
+            .addToContext("sorts", Joiner.on(", ")
+                .join(messageListRequest.getSort()))
+            .addToContextIfPresent("isFetchMessage", messageListRequest.isFetchMessages().map(b -> Boolean.toString(b)))
+            .addToContextIfPresent("isCollapseThread", messageListRequest.isCollapseThreads().map(b -> Boolean.toString(b)));
     }
 
     private Flux<JmapResponse> process(MethodCallId methodCallId, MailboxSession mailboxSession, GetMessageListRequest messageListRequest) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java
index 326375b..9368b42 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessagesMethod.java
@@ -24,6 +24,7 @@ import static org.apache.james.util.ReactorUtils.context;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
@@ -40,6 +41,7 @@ import org.apache.james.jmap.draft.model.message.view.MessageView;
 import org.apache.james.jmap.draft.model.message.view.MessageViewFactory;
 import org.apache.james.jmap.draft.model.message.view.MetaMessageViewFactory;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 
@@ -100,10 +102,14 @@ public class GetMessagesMethod implements Method {
 
     private MDCBuilder mdc(GetMessagesRequest getMessagesRequest) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "GET_MESSAGES")
-            .addContext("accountId", getMessagesRequest.getAccountId())
-            .addContext("ids", getMessagesRequest.getIds())
-            .addContext("properties", getMessagesRequest.getProperties());
+            .addToContext(MDCBuilder.ACTION, "GET_MESSAGES")
+            .addToContextIfPresent("accountId", getMessagesRequest.getAccountId())
+            .addToContext("ids", getMessagesRequest.getIds()
+                .stream()
+                .map(MessageId::serialize)
+                .collect(Collectors.joining(", ")))
+            .addToContext("properties", getMessagesRequest.getProperties().asFieldList()
+                .collect(Collectors.joining(", ")));
     }
 
     private Optional<Pair<? extends Set<? extends Property>, SimpleFilterProvider>> buildOptionalHeadersFilteringFilterProvider(MessageProperties properties) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/RequestHandler.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/RequestHandler.java
index c895a3a..a02c314 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/RequestHandler.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/RequestHandler.java
@@ -61,9 +61,11 @@ public class RequestHandler {
         Optional<MailboxSession> mailboxSession = Optional.ofNullable(request.getMailboxSession());
         try (Closeable closeable =
                  MDCBuilder.create()
-                     .addContext(MDCBuilder.USER, mailboxSession.map(MailboxSession::getUser).map(Username::asString))
-                     .addContext(MDCBuilder.SESSION_ID, mailboxSession.map(MailboxSession::getSessionId))
-                     .addContext(MDCBuilder.ACTION, request.getMethodName().getName())
+                     .addToContextIfPresent(MDCBuilder.USER, mailboxSession.map(MailboxSession::getUser).map(Username::asString))
+                     .addToContextIfPresent(MDCBuilder.SESSION_ID, mailboxSession.map(MailboxSession::getSessionId)
+                        .map(MailboxSession.SessionId::getValue)
+                        .map(l -> Long.toString(l)))
+                     .addToContext(MDCBuilder.ACTION, request.getMethodName().getName())
                      .build()) {
             return Optional.ofNullable(methods.get(request.getMethodName()))
                 .map(extractAndProcess(request))
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java
index 1df5e1d..7ba0cb7 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetFilterMethod.java
@@ -122,7 +122,7 @@ public class SetFilterMethod implements Method {
         return Flux.from(metricFactory.decoratePublisherWithTimerMetric(JMAP_PREFIX + METHOD_NAME.getName(),
             process(methodCallId, mailboxSession, setFilterRequest)
                 .subscriberContext(jmapAction("SET_FILTER"))
-                .subscriberContext(context("SET_FILTER", MDCBuilder.of("update", setFilterRequest.getSingleton())))));
+                .subscriberContext(context("SET_FILTER", MDCBuilder.ofValue("update", setFilterRequest.getSingleton().toString())))));
     }
 
     private Mono<JmapResponse> process(MethodCallId methodCallId, MailboxSession mailboxSession, SetFilterRequest request) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java
index 4105b91..60dbbc0 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMailboxesMethod.java
@@ -83,10 +83,10 @@ public class SetMailboxesMethod implements Method {
 
     private MDCBuilder mdc(SetMailboxesRequest setMailboxesRequest) {
         return MDCBuilder.create()
-            .addContext(MDCBuilder.ACTION, "SET_MAILBOXES")
-            .addContext("create", setMailboxesRequest.getCreate())
-            .addContext("update", setMailboxesRequest.getUpdate())
-            .addContext("destroy", setMailboxesRequest.getDestroy());
+            .addToContext(MDCBuilder.ACTION, "SET_MAILBOXES")
+            .addToContext("create", setMailboxesRequest.getCreate().toString())
+            .addToContext("update", setMailboxesRequest.getUpdate().toString())
+            .addToContext("destroy", setMailboxesRequest.getDestroy().toString());
     }
 
     private Mono<SetMailboxesResponse> setMailboxesResponse(SetMailboxesRequest request, MailboxSession mailboxSession) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java
index 75394be..f60fba1 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetMessagesMethod.java
@@ -82,11 +82,11 @@ public class SetMessagesMethod implements Method {
 
     private MDCBuilder mdc(SetMessagesRequest setMessagesRequest) {
         return MDCBuilder.create()
-            .addContext(ACTION, "SET_MESSAGES")
-            .addContext("accountId", setMessagesRequest.getAccountId())
-            .addContext("create", setMessagesRequest.getCreate())
-            .addContext("destroy", setMessagesRequest.getDestroy())
-            .addContext("ifInState", setMessagesRequest.getIfInState());
+            .addToContext(ACTION, "SET_MESSAGES")
+            .addToContextIfPresent("accountId", setMessagesRequest.getAccountId())
+            .addToContext("create", setMessagesRequest.getCreate().toString())
+            .addToContext("destroy", setMessagesRequest.getDestroy().toString())
+            .addToContextIfPresent("ifInState", setMessagesRequest.getIfInState());
     }
 
     private Mono<SetMessagesResponse> setMessagesResponse(SetMessagesRequest request, MailboxSession mailboxSession) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java
index dbc7c86..b7dd31a 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SetVacationResponseMethod.java
@@ -83,7 +83,7 @@ public class SetVacationResponseMethod implements Method {
         return Flux.from(metricFactory.decoratePublisherWithTimerMetric(JMAP_PREFIX + METHOD_NAME.getName(),
             process(methodCallId, mailboxSession, setVacationRequest)
                 .subscriberContext(jmapAction("SET_VACATION"))
-                .subscriberContext(context("set-vacation", MDCBuilder.of("update", setVacationRequest.getUpdate())))));
+                .subscriberContext(context("set-vacation", MDCBuilder.ofValue("update", setVacationRequest.getUpdate().toString())))));
     }
 
     private Flux<JmapResponse> process(MethodCallId methodCallId, MailboxSession mailboxSession, SetVacationRequest setVacationRequest) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/MessageProperties.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/MessageProperties.java
index 490cea4..67c726d 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/MessageProperties.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/MessageProperties.java
@@ -19,6 +19,7 @@
 package org.apache.james.jmap.draft.model;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.Optional;
@@ -85,7 +86,16 @@ public class MessageProperties {
         // "language", "location" ]
         return readLevels.reduce(ReadProfile::combine)
             .orElse(ReadProfile.Full);
+    }
 
+    public Stream<String> asFieldList() {
+        return Stream.concat(
+            messageProperties.stream()
+                .flatMap(Collection::stream)
+                .map(MessageProperty::asFieldName),
+            headersProperties.stream()
+                .flatMap(Collection::stream)
+                .map(HeaderProperty::asFieldName));
     }
 
     private Stream<ReadProfile> headerPropertiesReadLevel() {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/LoggingHelper.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/LoggingHelper.java
index af504f63..033db0e 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/LoggingHelper.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/LoggingHelper.java
@@ -30,17 +30,17 @@ import reactor.util.context.Context;
 public interface LoggingHelper {
     static Context jmapAuthContext(MailboxSession session) {
         return context("JMAP_AUTH",
-            MDCBuilder.of(MDCBuilder.USER, session.getUser().asString()));
+            MDCBuilder.ofValue(MDCBuilder.USER, session.getUser().asString()));
     }
 
     static Context jmapContext(HttpServerRequest req) {
         return context("JMAP", MDCBuilder.create()
-            .addContext(MDCBuilder.PROTOCOL, "JMAP")
-            .addContext(MDCBuilder.IP, req.hostAddress().getHostString()));
+            .addToContext(MDCBuilder.PROTOCOL, "JMAP")
+            .addToContext(MDCBuilder.IP, req.hostAddress().getHostString()));
     }
 
     static Context jmapAction(String action) {
         return context("JMAP_ACTION",
-            MDCBuilder.of(MDCBuilder.ACTION, action));
+            MDCBuilder.ofValue(MDCBuilder.ACTION, action));
     }
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java
index b27242f..4349841 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPMDCContext.java
@@ -26,7 +26,6 @@ import java.util.Optional;
 
 import org.apache.james.core.Username;
 import org.apache.james.imap.api.process.ImapSession;
-import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.util.MDCBuilder;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.ChannelLocal;
@@ -34,10 +33,10 @@ import org.jboss.netty.channel.ChannelLocal;
 public class IMAPMDCContext {
     public static Closeable from(ChannelHandlerContext ctx, ChannelLocal<Object> attributes) {
         return MDCBuilder.create()
-            .addContext(from(attributes.get(ctx.getChannel())))
-            .addContext(MDCBuilder.PROTOCOL, "IMAP")
-            .addContext(MDCBuilder.IP, retrieveIp(ctx))
-            .addContext(MDCBuilder.HOST, retrieveHost(ctx))
+            .addToContext(from(attributes.get(ctx.getChannel())))
+            .addToContext(MDCBuilder.PROTOCOL, "IMAP")
+            .addToContext(MDCBuilder.IP, retrieveIp(ctx))
+            .addToContext(MDCBuilder.HOST, retrieveHost(ctx))
             .build();
     }
 
@@ -64,18 +63,13 @@ public class IMAPMDCContext {
             ImapSession imapSession = (ImapSession) o;
 
             return MDCBuilder.create()
-                .addContext("sessionId", imapSession.sessionId().asString())
-                .addContext(MDCBuilder.USER, Optional.ofNullable(imapSession.getUserName())
-                    .map(Username::asString))
-                .addContext(from(Optional.ofNullable(imapSession.getSelected())));
+                .addToContext("sessionId", imapSession.sessionId().asString())
+                .addToContext(MDCBuilder.USER, Optional.ofNullable(imapSession.getUserName())
+                    .map(Username::asString)
+                    .orElse(""))
+                .addToContextIfPresent("selectedMailbox", Optional.ofNullable(imapSession.getSelected())
+                    .map(selectedMailbox -> selectedMailbox.getMailboxId().serialize()));
         }
         return MDCBuilder.create();
     }
-
-    private static MDCBuilder from(Optional<SelectedMailbox> selectedMailbox) {
-        return selectedMailbox
-            .map(value -> MDCBuilder.create()
-                .addContext("selectedMailbox", value.getMailboxId().serialize()))
-            .orElseGet(MDCBuilder::create);
-    }
 }
diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java
index d069f7a..52727c1 100644
--- a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveMDCContext.java
@@ -32,11 +32,11 @@ import org.jboss.netty.channel.ChannelLocal;
 public class ManageSieveMDCContext {
     public static Closeable from(ChannelHandlerContext ctx, ChannelLocal<Session> attributes) {
         return MDCBuilder.create()
-            .addContext(from(attributes.get(ctx.getChannel())))
-            .addContext(MDCBuilder.PROTOCOL, "MANAGE-SIEVE")
-            .addContext(MDCBuilder.IP, retrieveIp(ctx))
-            .addContext(MDCBuilder.HOST, retrieveHost(ctx))
-            .addContext(MDCBuilder.SESSION_ID, ctx.getChannel().getId())
+            .addToContext(from(attributes.get(ctx.getChannel())))
+            .addToContext(MDCBuilder.PROTOCOL, "MANAGE-SIEVE")
+            .addToContext(MDCBuilder.IP, retrieveIp(ctx))
+            .addToContext(MDCBuilder.HOST, retrieveHost(ctx))
+            .addToContext(MDCBuilder.SESSION_ID, Integer.toString(ctx.getChannel().getId()))
             .build();
     }
 
@@ -61,7 +61,7 @@ public class ManageSieveMDCContext {
     private static MDCBuilder from(Session session) {
         return Optional.ofNullable(session)
             .map(s -> MDCBuilder.create()
-                .addContext(MDCBuilder.USER, s.getUser()))
+                .addToContext(MDCBuilder.USER, s.getUser().asString()))
             .orElse(MDCBuilder.create());
     }
 }
diff --git a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/core/PassCmdHandler.java b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/core/PassCmdHandler.java
index ebef5f4..4569f67 100644
--- a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/core/PassCmdHandler.java
+++ b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/core/PassCmdHandler.java
@@ -80,7 +80,7 @@ public class PassCmdHandler extends AbstractPassCmdHandler  {
     protected Mailbox auth(POP3Session session, Username username, String password) throws Exception {
         return MDCBuilder.withMdc(
             MDCBuilder.create()
-                .addContext(MDCBuilder.USER, username.asString()),
+                .addToContext(MDCBuilder.USER, username.asString()),
             Throwing.supplier(() -> auth(session, password)).sneakyThrow());
     }
 
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
index 06a7edf..bb7973d 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
@@ -47,13 +47,13 @@ public class LoggingRequestFilter implements Filter {
         @Override
         public void log(Request request, RequestId requestId) {
             MDCStructuredLogger.forLogger(LOGGER)
-                    .addField(REQUEST_ID, requestId.asString())
-                    .addField(IP, request.ip())
-                    .addField(ENDPOINT, request.url())
-                    .addField(METHOD, request.requestMethod())
-                    .addField(LOGIN, request.attribute(LOGIN))
-                    .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
-                    .addField(REQUEST_BODY, request.body())
+                    .field(REQUEST_ID, requestId.asString())
+                    .field(IP, request.ip())
+                    .field(ENDPOINT, request.url())
+                    .field(METHOD, request.requestMethod())
+                    .field(LOGIN, request.attribute(LOGIN))
+                    .field(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()).toString())
+                    .field(REQUEST_BODY, request.body())
                     .log(logger -> logger.info("WebAdmin request received"));
         }
     }
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
index 39b99a9..ad460e6 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
@@ -46,14 +46,14 @@ public class LoggingResponseFilter implements Filter {
         RequestId requestId = request.attribute(REQUEST_ID);
 
         MDCStructuredLogger.forLogger(LOGGER)
-            .addField(REQUEST_ID, requestId.asString())
-            .addField(IP, request.ip())
-            .addField(ENDPOINT, request.url())
-            .addField(METHOD, request.requestMethod())
-            .addField(LOGIN, request.attribute(LOGIN))
-            .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
-            .addField(STATUS, response.status())
-            .addField(RESPONSE_BODY, response.body())
+            .field(REQUEST_ID, requestId.asString())
+            .field(IP, request.ip())
+            .field(ENDPOINT, request.url())
+            .field(METHOD, request.requestMethod())
+            .field(LOGIN, request.attribute(LOGIN))
+            .field(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()).toString())
+            .field(STATUS, Integer.toString(response.status()))
+            .field(RESPONSE_BODY, response.body())
             .log(logger -> logger.info("WebAdmin response received"));
     }
 }
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/MDCFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/MDCFilter.java
index 8ac470b..48d7ea2 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/MDCFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/MDCFilter.java
@@ -35,12 +35,12 @@ public class MDCFilter implements Filter {
     @Override
     public void handle(Request request, Response response) throws Exception {
         Closeable mdcCloseable = MDCBuilder.create()
-            .addContext(MDCBuilder.IP, request.ip())
-            .addContext(MDCBuilder.HOST, request.host())
-            .addContext(VERB, request.requestMethod())
-            .addContext(MDCBuilder.PROTOCOL, "webadmin")
-            .addContext(MDCBuilder.ACTION, request.pathInfo())
-            .addContext(MDCBuilder.USER, request.attribute(AuthenticationFilter.LOGIN))
+            .addToContext(MDCBuilder.IP, request.ip())
+            .addToContext(MDCBuilder.HOST, request.host())
+            .addToContext(VERB, request.requestMethod())
+            .addToContext(MDCBuilder.PROTOCOL, "webadmin")
+            .addToContext(MDCBuilder.ACTION, request.pathInfo())
+            .addToContext(MDCBuilder.USER, request.attribute(AuthenticationFilter.LOGIN))
             .build();
         request.attribute(MDC_CLOSEABLE, mdcCloseable);
     }
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/UserCreationRequestLogger.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/UserCreationRequestLogger.java
index 8bcbe5c..8ae80fb 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/UserCreationRequestLogger.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/UserCreationRequestLogger.java
@@ -46,12 +46,12 @@ public class UserCreationRequestLogger implements RequestLogger {
     @Override
     public void log(Request request, RequestId requestId) {
         MDCStructuredLogger.forLogger(LOGGER)
-                .addField(REQUEST_ID, requestId.asString())
-                .addField(IP, request.ip())
-                .addField(ENDPOINT, request.url())
-                .addField(METHOD, request.requestMethod())
-                .addField(LOGIN, request.attribute(LOGIN))
-                .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
+                .field(REQUEST_ID, requestId.asString())
+                .field(IP, request.ip())
+                .field(ENDPOINT, request.url())
+                .field(METHOD, request.requestMethod())
+                .field(LOGIN, request.attribute(LOGIN))
+                .field(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()).toString())
                 .log(logger -> logger.info("WebAdmin request received: user creation request"));
     }
 }
diff --git a/server/task/task-memory/src/main/java/org/apache/james/task/SerialTaskManagerWorker.java b/server/task/task-memory/src/main/java/org/apache/james/task/SerialTaskManagerWorker.java
index 409c4c8..e7b6107 100644
--- a/server/task/task-memory/src/main/java/org/apache/james/task/SerialTaskManagerWorker.java
+++ b/server/task/task-memory/src/main/java/org/apache/james/task/SerialTaskManagerWorker.java
@@ -104,9 +104,9 @@ public class SerialTaskManagerWorker implements TaskManagerWorker {
     private Task.Result runWithMdc(TaskWithId taskWithId, Listener listener) {
         return MDCBuilder.withMdc(
             MDCBuilder.create()
-                .addContext(Task.TASK_ID, taskWithId.getId())
-                .addContext(Task.TASK_TYPE, taskWithId.getTask().type())
-                .addContext(Task.TASK_DETAILS, taskWithId.getTask().details()),
+                .addToContext(Task.TASK_ID, taskWithId.getId().asString())
+                .addToContext(Task.TASK_TYPE, taskWithId.getTask().type().asString())
+                .addToContext(Task.TASK_DETAILS, taskWithId.getTask().details().toString()),
             () -> run(taskWithId, listener).block());
     }
 

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 02/02: JAMES-3587 Optimize MDCBuilder::build

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 1a45cbe249517d867cc1daa5220c117476dd41fa
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed May 19 21:47:42 2021 +0700

    JAMES-3587 Optimize MDCBuilder::build
    
    MDC::build represents 0.40% of CPU time according to flame graphs conducted
    during performance tests.
    
     - Avoids the allocation of MDCCloseable objects
     - Avoids two intermediate collects
---
 .../java/org/apache/james/util/MDCBuilder.java     | 47 +++++--------------
 .../java/org/apache/james/util/MDCBuilderTest.java | 53 ----------------------
 2 files changed, 11 insertions(+), 89 deletions(-)

diff --git a/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java b/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java
index aefb7f7..5255f07 100644
--- a/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java
+++ b/server/container/util/src/main/java/org/apache/james/util/MDCBuilder.java
@@ -21,7 +21,6 @@ package org.apache.james.util;
 
 import java.io.Closeable;
 import java.io.IOException;
-import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.function.Supplier;
@@ -30,7 +29,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
 
-import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
@@ -72,28 +70,6 @@ public class MDCBuilder {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(MDCBuilder.class);
 
-    public static class Closeables implements Closeable {
-        private final List<Closeable> closeables;
-
-        public Closeables(List<Closeable> closeables) {
-            Preconditions.checkNotNull(closeables);
-            this.closeables = ImmutableList.copyOf(closeables);
-        }
-
-        @Override
-        public void close() throws IOException {
-            closeables.forEach(this::closeQuietly);
-        }
-
-        private void closeQuietly(Closeable closeable) {
-            try {
-                closeable.close();
-            } catch (IOException e) {
-                LOGGER.warn("Failed to close Closeable", e);
-            }
-        }
-    }
-
     public static MDCBuilder create() {
         return new MDCBuilder();
     }
@@ -172,12 +148,12 @@ public class MDCBuilder {
 
     @VisibleForTesting
     Map<String, String> buildContextMap() {
-        return ImmutableMap.<String, String>builder()
-            .putAll(nestedBuilder.build()
-                .stream()
-                .map(MDCBuilder::buildContextMap)
-                .flatMap(map -> map.entrySet().stream())
-                .collect(Guavate.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)))
+        ImmutableMap.Builder<String, String> result = ImmutableMap.builder();
+
+        nestedBuilder.build()
+            .forEach(mdcBuilder -> result.putAll(mdcBuilder.buildContextMap()));
+
+        return result
             .putAll(contextMap.build())
             .build();
     }
@@ -191,12 +167,11 @@ public class MDCBuilder {
     }
 
     public Closeable build() {
-        return new Closeables(
-            buildContextMap()
-                .entrySet()
-                .stream()
-                .map(entry -> MDC.putCloseable(entry.getKey(), entry.getValue()))
-                .collect(Guavate.toImmutableList()));
+        Map<String, String> contextMap = buildContextMap();
+        contextMap.forEach(MDC::put);
+
+        return () -> contextMap.keySet()
+            .forEach(MDC::remove);
     }
 
 }
diff --git a/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java b/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
index dad7682..bf074fd 100644
--- a/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/MDCBuilderTest.java
@@ -22,15 +22,9 @@ package org.apache.james.util;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatNullPointerException;
 
-import java.io.Closeable;
-import java.io.IOException;
-
 import org.junit.jupiter.api.Test;
 
-import com.google.common.collect.ImmutableList;
-
 class MDCBuilderTest {
-
     private static final String KEY_1 = "key1";
     private static final String KEY_2 = "key2";
     private static final String VALUE_1 = "value1";
@@ -91,51 +85,4 @@ class MDCBuilderTest {
             .containsEntry(KEY_1, VALUE_1)
             .containsEntry(KEY_2, VALUE_2);
     }
-
-    @Test
-    void closeablesConstructorShouldThrowOnNullList() {
-        assertThatNullPointerException()
-            .isThrownBy(() -> new MDCBuilder.Closeables(null));
-    }
-
-    @Test
-    void closeablesCloseShouldNotThrowWhenEmpty() throws IOException {
-        new MDCBuilder.Closeables(ImmutableList.of())
-            .close();
-    }
-
-    @Test
-    void closeablesCloseShouldCallAllUnderlyingCloseables() throws IOException {
-        ImmutableList.Builder<String> builder = ImmutableList.builder();
-
-        Closeable closeable1 = () -> builder.add(VALUE_1);
-        Closeable closeable2 = () -> builder.add(VALUE_2);
-
-        new MDCBuilder.Closeables(
-            ImmutableList.of(closeable1, closeable2))
-            .close();
-
-        assertThat(builder.build())
-            .containsExactly(VALUE_1, VALUE_2);
-    }
-
-
-    @Test
-    void closeablesCloseShouldCallAllUnderlyingCloseablesWhenError() throws IOException {
-        ImmutableList.Builder<String> builder = ImmutableList.builder();
-
-        Closeable closeable1 = () -> builder.add(VALUE_1);
-        Closeable closeable2 = () -> {
-            throw new IOException();
-        };
-        Closeable closeable3 = () -> builder.add(VALUE_2);
-
-        new MDCBuilder.Closeables(
-            ImmutableList.of(closeable1, closeable2, closeable3))
-            .close();
-
-        assertThat(builder.build())
-            .containsExactly(VALUE_1, VALUE_2);
-    }
-
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org