You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Roman Vottner (JIRA)" <ji...@apache.org> on 2019/03/04 18:04:00 UTC

[jira] [Commented] (SSHD-900) Support for MDC Logging

    [ 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)