@Around(value = "@annotation(audits)", argNames = "audits")
    public Object handleAuditTrail(final ProceedingJoinPoint joinPoint, final Audits audits) throws Throwable {
        if (!this.enabled) {
            return joinPoint.proceed();
        }

        Object retVal = null;
        String currentPrincipal = null;
        val actions = new String[audits.value().length];
        val auditableResources = new String[audits.value().length][];
        try {
            retVal = joinPoint.proceed();

            currentPrincipal = getCurrentPrincipal(joinPoint, audits, retVal);

            for (var i = 0; i < audits.value().length; i++) {
                val auditActionResolver = auditActionResolvers.get(audits.value()[i].actionResolverName());

                val auditResourceResolver = auditResourceResolvers.get(audits.value()[i].resourceResolverName());
                auditResourceResolver.setAuditFormat(this.auditFormat);

                auditableResources[i] = auditResourceResolver.resolveFrom(joinPoint, retVal);
                actions[i] = auditActionResolver.resolveFrom(joinPoint, retVal, audits.value()[i]);
            }
            return retVal;
        } catch (final Throwable t) {
            val e = wrapIfNecessary(t);
            currentPrincipal = getCurrentPrincipal(joinPoint, audits, e);

            if (currentPrincipal != null) {
                for (var i = 0; i < audits.value().length; i++) {
                    var auditResourceResolver = this.auditResourceResolvers.get(audits.value()[i].resourceResolverName());
                    auditResourceResolver.setAuditFormat(this.auditFormat);

                    auditableResources[i] = auditResourceResolver.resolveFrom(joinPoint, e);
                    actions[i] = auditActionResolvers.get(audits.value()[i].actionResolverName()).resolveFrom(joinPoint, e, audits.value()[i]);
                }
            }
            throw t;
        } finally {
            for (var i = 0; i < audits.value().length; i++) {
                executeAuditCode(currentPrincipal, auditableResources[i], joinPoint, retVal, actions[i]);
            }
        }
    }
Handle audit trail.

@param joinPoint the join point
@param audits    the audits
@return the object
@throws Throwable the throwable
core/cas-server-core-audit-api/src/main/java/org/apereo/inspektr/audit/AuditTrailManagementAspect.java