de.kaiserpfalzEdv.commons.jee.spring.ServiceLogging.java Source code

Java tutorial

Introduction

Here is the source code for de.kaiserpfalzEdv.commons.jee.spring.ServiceLogging.java

Source

/*
 * Copyright 2015 Kaiserpfalz EDV-Service Roland Lichti
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.kaiserpfalzEdv.commons.jee.spring;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.UUID;

/**
 * This class adds logging to Service calls.
 *
 * @author klenkes
 * @since 1.2.1
 */
@Component
@Aspect
public class ServiceLogging implements Serializable {
    private static final long serialVersionUID = -2188058410551323342L;

    private static final ZoneId UTC = ZoneId.of("UTC");
    public static final Logger oplog = LoggerFactory.getLogger("operations");

    @Around("execution(* de.kaiserpfalzEdv..service..*Impl.*(..))")
    public Object updateMDC(ProceedingJoinPoint joinPoint) throws Throwable {
        String id = retrieveIdFromMDCOrGenerateNewUUID(joinPoint);
        MDC.put("id", id);

        Object result;

        if (oplog.isInfoEnabled()) {
            String serviceName = retrieveMethodNameFromSignature(joinPoint);

            OffsetDateTime start = OffsetDateTime.now(UTC);
            oplog.info("Service '{}' started. id={}, start={}", serviceName, id, start);

            result = joinPoint.proceed();

            OffsetDateTime end = OffsetDateTime.now(UTC);

            oplog.info("Service '{}' ended. id={}, start={}, duration={}",
                    retrieveMethodNameFromSignature(joinPoint), id, start, Duration.between(start, end));
        } else {
            result = joinPoint.proceed();
        }

        MDC.remove("id");

        return result;
    }

    private String retrieveMethodNameFromSignature(ProceedingJoinPoint joinPoint) {
        return joinPoint.getStaticPart().getSignature().getDeclaringTypeName() + "."
                + joinPoint.getStaticPart().getSignature().getName();
    }

    /**
     * @return the old UUID or a newly generated one.
     */
    private String retrieveIdFromMDCOrGenerateNewUUID(ProceedingJoinPoint joinPoint) {
        try {
            return retrieveUUIDFromArguments(joinPoint);
        } catch (NullPointerException e) {
            try {
                return retrieveUUIDFromMDC();
            } catch (IllegalArgumentException ignored) {
                // klenkes 2015-01-25 ignored, since we will randomly generate a new ID.
            }
        }

        return UUID.randomUUID().toString();
    }

    /**
     * Retrieves the first UUID from argument list.
     *
     * @param joinPoint The join point information
     * @return a string containing the UUID.
     * @throws NullPointerException if no argument contained an UUID.
     */
    private String retrieveUUIDFromArguments(ProceedingJoinPoint joinPoint) throws NullPointerException {
        for (Object arg : joinPoint.getArgs()) {
            if (arg != null && arg.getClass().equals(UUID.class)) {
                UUID result = (UUID) arg;

                return result.toString();
            }
        }

        throw new NullPointerException("There is no UUID in the argument list of this joinPoint!");
    }

    private String retrieveUUIDFromMDC() throws IllegalArgumentException {
        String result = MDC.get("id");

        if (result == null)
            throw new IllegalArgumentException("No ID in MDC set.");

        return result;
    }
}