[ 
https://issues.apache.org/jira/browse/SSHD-900?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16783607#comment-16783607
 ] 

Roman Vottner commented on SSHD-900:
------------------------------------

We, more or less, solved that issue now by adding a new class which we called 
_LoggingAdvice_ that basically just adds data contained either in the Session 
or in the custom FileSystem directly to the MDC context and clears that MDC 
context again after the method has finished. We defined this LoggingAdvice to 
implement AutoClosable in order to utilize try-with-resources to automatically 
set the MDC context within the constructor and clean up the respective method 
once the try-with-resources block was left. That way we can just wrap the whole 
code of selected methods within that try-with-resources block and don't have to 
worry about catching any eventual exception thrown as we would have to if we 
used a lambda-function based approach, which we also evaluated.

In order to avoid clearing of the context in case of nested invocations we also 
had to introduce a basic hierarchy counter which only performes the cleanup 
once the counter reached 0 again.

Code-wise we ended up with something along the lines of: 
{noformat}
/**
 * Enables MDC logging by wrapping the method. Will set MDC keys at the 
 * beginning and remove each entry after the a try-block was left.
 *
 * Usage: 
 * <pre>{@code 
 * public void someMethod() {
 *   try(@SuppressWarnings("unused") LoggingAdvice mdc = 
 *          new LoggingAdvice(session)) {
 *     // perform regular method logic here
 *   }
 * }
 * }</pre>
 */
public class LoggingAdvice implements AutoCloseable {

  private static final String LEVEL = "level";

  public LoggingAdvice(Session session) {
    setMDC(session);
  }

  public LoggingAdvice(CustomFileSystem cfs) {
    setMDC(cfs);
  }

  private void setMDC(Session session) {
    MDC.put(Constants.REMOTE_IP, session.getAttribute(IP_KEY));
    MDC.put(Constants.USER_ID, session.getAttribute(USER_KEY));
    MDC.put(Constants.CONNECTOR_UUID, session.getAttribute(CONNECTOR_KEY));
    MDC.put(Constants.COMPANY_ID, session.getAttribute(COMPANY_KEY));
    MDC.put(Constants.USER_AGENT, session.getAttribute(USERAGENT_KEY));
    checkAndSetLevel();
  }

  private void setMDC(CustomFileSystem cfs) {
    MDC.put(Constants.REMOTE_IP, cfs.getRemoteIP());
    MDC.put(Constants.USER_ID, cfs.getUser());
    if (cfs.getConnector() != null) {
      MDC.put(Constants.CONNECTOR_UUID, cfs.getConnector().getUuid());
    }
    if (!cfs.getCompanies().isEmpty()) {
      MDC.put(Constants.COMPANY_ID, cfs.getCompanies().stream()
          .map(CompanyEntity::getUuid)
          .collect(Collectors.joining(",")));
    }
    MDC.put(Constants.USER_AGENT, cfs.getUserAgent());
    checkAndSetLevel();
  }

  private void checkAndSetLevel() {
    int level;
    if (MDC.get(LEVEL) != null) {
      level = Integer.parseInt(MDC.get(LEVEL)) + 1;
    } else {
      level = 0;
    }
    MDC.put(LEVEL, "" + level);
  }

  private void unsetMDC() {
    String sLevel = MDC.get(LEVEL);
    Integer level = Integer.parseInt(sLevel);
    if (0 == level) {
      MDC.clear();
    } else {
      MDC.put(LEVEL, "" + (--level));
    }
  }

  @Override
  public void close() {
    unsetMDC();
  }
}{noformat}
This try-with-resources block needs to be added to each method that should log 
the MDC context. In our case this are at least all our methods that log onto 
DEBUG level. While we do not get MDC logs for Mina/SSHD this way, especially 
when SSHD is set to DEBUG or even TRACE level logging, we at least gain the 
traceability for a handful simultaneously connected clients now and which logic 
they are performing on the server separated by company/connector and other 
metrices..

> Support for MDC Logging
> -----------------------
>
>                 Key: SSHD-900
>                 URL: https://issues.apache.org/jira/browse/SSHD-900
>             Project: MINA SSHD
>          Issue Type: New Feature
>            Reporter: Marco Zapletal
>            Priority: Minor
>
> MDC logging support (e.g., remote IP, username, etc.) would really be a great 
> enhancement. We checked out the MINA filters 
> ([http://mina.apache.org/mina-project/userguide/ch5-filters/ch5-filters.html)]
>  but it seems they not integrate nicely with SSHD. 
>  
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to