Friday, January 21, 2022

Log4j MDC setting with Spring Annotation and Spring AOP

Aspect definition:


@Aspect
@Configuration
@RequiredArgsConstructor
public class ApplicationMDCAspect {
  @SuppressWarnings("squid:S3749")
  private final Log4jMDCSetter log4jMdcSetter;
  @Pointcut(
      "execution(* *(..)) && @annotation(com.idd.abc.base.logging.Log4jDiagnosticContextEnable)")
  public void log4jDiagnosticContextEnabled() {
    // do nothing.
  }
  @Before("com.idd.abc.base.logging.ApplicationMDCAspect.log4jDiagnosticContextEnabled()")
  public void setMdcToResourceBean(JoinPoint joinPoint) {
    log4jMdcSetter.setHostAndAppInfoIfMissing();
  }
}

Enable Aspect:


@Configuration
@EnableAspectJAutoProxy
public class AbcApplicationMdcAspect extends ApplicationMDCAspect {
  public AbcApplicationMdcAspect(Log4jMDCSetter log4jMdcSetter) {
    super(log4jMdcSetter);
  }
}



@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log4jDiagnosticContextEnable {}

public interface CorrelationIdSupplier {
  String createCorrelationId();
}

public interface Log4jMDCSetter {
  void clear();
  void setHostAndAppInfoIfMissing();
  void addParameter(String key, String value);
  void setUniqueId(String uniqueId);
  String getUniqueId();
}


@Service
@RequiredArgsConstructor
public final class CorrelationIdSupplierImpl implements CorrelationIdSupplier {
  @SuppressWarnings("squid:S3749")
  private final Clock clock;
  @SuppressWarnings("squid:S3749")
  @Qualifier("hostnameProperty")
  private final String hostname;
  /** @return a new generated correlation id */
  @Override
  public String createCorrelationId() {
    return new StringBuilder()
        .append(hostname)
        .append("-")
        .append(LocalDateTime.now(clock).getSecond())
        .append("-")
        .append(UUID.randomUUID())
        .toString();
  }
}
@Service
@RequiredArgsConstructor
@Slf4j
public final class Log4JMDCSetterImpl implements Log4jMDCSetter {
  private static final String APPLICATION_KEY = "APPLICATION";
  private static final String CORRELATION_ID_KEY = "CORRELATION_ID";
  private static final String HOSTNAME_KEY = "HOSTNAME";
  private static final String UNIQUE_ID = "UNIQUE_ID";

  @SuppressWarnings("squid:S3749")
  private final CorrelationIdSupplier correlationIdSupplier;
  @SuppressWarnings("squid:S3749")
  private final InetAddress inetAddress;
  @Value("${spring.application.name}")
  private String applicationName;
  
  @Override
  public void clear() {
    ThreadContext.clearAll();
  }

  @Override
  public void setHostAndAppInfoIfMissing() {
    String correlationId = ThreadContext.get(CORRELATION_ID_KEY);
    if (!StringUtils.isBlank(correlationId)) {
      return;
    }
    ThreadContext.put(APPLICATION_KEY, applicationName);
    ThreadContext.put(CORRELATION_ID_KEY, createCorrelationId());
    ThreadContext.put(HOSTNAME_KEY, inetAddress.getHostName());
  }

  @Override
  public void addParameter(String key, String value) {
    ThreadContext.put(key, value);
  }

  @Override
  public void setUniqueId(String uniqueId) {
    ThreadContext.put(UNIQUE_ID, uniqueId);
  }

  @Override
  public String getUniqueId() {
    final String uniqueId = ThreadContext.get(UNIQUE_ID);
    return uniqueId != null ? uniqueId : "NO UNIQIE_ID";
  }

  private String createCorrelationId() {
    try {
      return correlationIdSupplier.createCorrelationId();
    } catch (Exception e) {
      log.warn(
          DmAlertMessage.CAS_DM_APP_INTERNAL_EXCEPTION
              + " ### ### ### Exception when generating correlation id",
          e);
      return UUID.randomUUID().toString();
    }
  }
}

No comments:

Post a Comment