Maflec
Maflec

Reputation: 41

First time trying to use Aspect. What if I want to output a different value for specific logs?

First of all, I am not 100% sure if my code is correct, since this is the first time I am ever using Aspect in Spring, so I will be happy if you point out any errors.

First a little background. I have an application that uses a logging method that returns a stacktrace, an error message and the priority of that error (Low, Medium, Critical). In my manager it looks like this:

public UUID createErrorLogEntry(UUID userId, Throwable throwable, ErrorLogEntryPriorityType priority, String errorMessage) {
    ErrorLogEntryEntity errorLogEntryEntity = new ErrorLogEntryEntity(priority, errorMessage);
    errorLogEntryEntity.setNew(true);
    errorLogEntryEntity.setId(UUID.randomUUID());
    if (throwable != null)
        errorLogEntryEntity.setStackTrace(ExceptionUtils.getStackTrace(throwable));
    errorLogEntryEntity.setCreationDateTime(DateTimeUtils.nowUtc());
    errorLogEntryEntity.setCreationUserId(userId);
    errorLogEntryEntity.setChangedDateTime(errorLogEntryEntity.getCreationDateTime());
    errorLogEntryEntity.setChangedUserId(userId);
    errorLogEntryEntity.setPriority(errorLogEntryEntity.getPriority());
    errorLogEntryEntity.setDone(errorLogEntryEntity.isDone());
    errorLogEntryEntity.setMessage(errorLogEntryEntity.getMessage());
    errorLogEntryRepository.save(errorLogEntryEntity);
    return errorLogEntryEntity.getId();
}

Up until now I have been manually inserting this into try-blocks on every class in the system, which is very tedious. So I wanted to use Aspect and only target async and scheduled jobs, so I made this class:

@Aspect
@Component
public class errorEntryLogger {

    @Autowired
    private ErrorLogEntryManager errorLogEntryManager;

    @Around("@annotation(org.springframework.scheduling.annotation.Scheduled) && @annotation(org.springframework.scheduling.annotation.Async)")
    public Object createErrorEntryLogger(ProceedingJoinPoint pjp) throws Throwable {
        try {
            pjp.proceed();
        } catch (Exception e) {
            errorLogEntryManager.createErrorLogEntry(null, e.fillInStackTrace(), ErrorLogEntryPriorityType.LOW, "An error occurred");
        }
        return createErrorEntryLogger(pjp);
    }
}

But here is the issue. Doing it this way, all error logs will have a priority of "Low" and a generic error message. But what if I have classes where I want to set the priority higher or create more detailed error messages? How would I deal with these while using aspect?

Again, if there are better ways to write this code, let me know.

Upvotes: 0

Views: 42

Answers (1)

Joan
Joan

Reputation: 408

As @Stultuske said in his comment you can create a custom @Priority annotation.

You can create the annotation as follows:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Priority {
    public String value() default "LOW";
}

Then you can read the value of this annotation as follows:

public Object createErrorEntryLogger(final ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {
    final MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint .getSignature();
    final Method method = methodSignature.getMethod();
    final Priority priority = method.getAnnotation(Priority.class);
    // Do whatever you want with priority.value()
}

Upvotes: 1

Related Questions