All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kiwiproject.retry.RetryResultLogger Maven / Gradle / Ivy

Go to download

Kiwi is a utility library. We really like Google's Guava, and also use Apache Commons. But if they don't have something we need, and we think it is useful, this is where we put it.

There is a newer version: 4.4.0
Show newest version
package org.kiwiproject.retry;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.isNull;
import static org.kiwiproject.base.KiwiPreconditions.checkArgumentNotNull;
import static org.kiwiproject.collect.KiwiLists.nth;

import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * Utility class for logging information about errors in {@link RetryResult} objects.
 */
@UtilityClass
public class RetryResultLogger {

    private static final String NO_ERRORS_TO_LOG = "no errors to log";

    /**
     * Logs a summary of the given result only if it {@link RetryResult#failed()}.
     *
     * @param result                    the result
     * @param logger                    the SLF4J logger to use
     * @param actionDescriptionSupplier a {@link Supplier} that provides a description of the action that was attempted
     *                                  for example "Create new order #12345" or "Update order #456"
     * @param                        the type held in the result
     * @see #logSummary(RetryResult, Logger, String)
     */
    public static  void logSummaryIfFailed(RetryResult result,
                                              Logger logger,
                                              Supplier actionDescriptionSupplier) {

        checkArgumentsNotNull(result, logger);

        if (result.failed()) {
            logSummaryWithDescriptionSupplier(result, logger, actionDescriptionSupplier);
        }
    }

    /**
     * Logs a summary of the given result only if it has any errors or more than one attempt was made.
     *
     * @param result                    the result
     * @param logger                    the SLF4J logger to use
     * @param actionDescriptionSupplier a {@link Supplier} that provides a description of the action that was attempted
     *                                  for example "Create new order #12345" or "Update order #456"
     * @param                        the type held in the result
     */
    public static  void logSummaryIfHasErrorsOrMultipleAttempts(RetryResult result,
                                                                   Logger logger,
                                                                   Supplier actionDescriptionSupplier) {

        checkArgumentsNotNull(result, logger);

        if (result.hasAnyErrors() || result.hasMoreThanOneAttempt()) {
            logSummaryWithDescriptionSupplier(result, logger, actionDescriptionSupplier);
        }
    }

    private static  void logSummaryWithDescriptionSupplier(RetryResult result,
                                                              Logger logger,
                                                              Supplier supplier) {

        var actionDescription = isNull(supplier) ? "" : supplier.get();
        logSummary(result, logger, actionDescription);
    }

    /**
     * Logs a high-level summary of the result. The log level is dependent on whether the result was successful
     * or not, and whether there were any errors (e.g. a result was successful but took more than one attempt).
     * 

* The log levels are: *

* Result failed: ERROR *

* Result succeeded with errors: WARN *

* Result succeeded with no errors: DEBUG * * @param result the result * @param logger the SLF4J logger to use * @param actionDescription a {@link Supplier} that provides a description of the action that was attempted * for example "Create new order #12345" or "Update order #456" * @param the type held in the result */ public static void logSummary(RetryResult result, Logger logger, String actionDescription) { checkArgumentsNotNull(result, logger); if (result.failed()) { logFailureSummary(result, logger, actionDescription); } else { logSuccessSummary(result, logger, actionDescription); } } private static void logFailureSummary(RetryResult result, Logger logger, String actionDescription) { checkArgument(result.failed(), "you must only pass a failed result to this method"); var newActionDescription = buildActionDescription(actionDescription); var lastErrorInfo = buildLastErrorDescription(result); logger.error("Result {}: {} FAILED after {} attempts with {} errors. Unique error types: {}. Last error type/message: {}", result.getResultUuid(), newActionDescription, result.getNumAttemptsMade(), result.getNumErrors(), result.getUniqueErrorTypes(), lastErrorInfo); } private static void logSuccessSummary(RetryResult result, Logger logger, String actionDescription) { checkArgument(result.succeeded(), "you must only pass a successful result to this method"); var newActionDescription = buildActionDescription(actionDescription); if (result.hasAnyErrors()) { var lastErrorInfo = buildLastErrorDescription(result); logger.warn("Result {}: {} SUCCEEDED after {} attempts with {} errors. Unique error types: {}. Last error type/message: {}", result.getResultUuid(), newActionDescription, result.getNumAttemptsMade(), result.getNumErrors(), result.getUniqueErrorTypes(), lastErrorInfo); } else { logger.debug("Result {}: {} SUCCEEDED after {} attempts with no errors.", result.getResultUuid(), newActionDescription, result.getNumAttemptsMade()); } } private static String buildActionDescription(String summaryText) { return StringUtils.isBlank(summaryText) ? "" : ("[" + summaryText + "]"); } private static String buildLastErrorDescription(RetryResult result) { var lastError = result.getLastErrorIfPresent().orElse(null); return isNull(lastError) ? "[none]" : (lastError.getClass().getName() + " / " + lastError.getMessage()); } /** * Log all exceptions contained in the result using the given logger. * * @param result the result * @param logger the SLF4J logger to use * @param the type held in the result */ public static void logAllExceptions(RetryResult result, Logger logger) { logCommonResultInfo(result, logger, "all errors logged below"); if (!result.hasAnyErrors()) { return; } var uuid = result.getResultUuid(); var numErrors = result.getNumErrors(); var errors = result.getErrors(); IntStream.rangeClosed(1, numErrors).forEachOrdered(i -> { var error = nth(errors, i); logger.error("Result {}: error #{} of {}:", uuid, i, numErrors, error); }); } /** * Log only the last exception contained in the result using the given logger. * * @param result the result * @param logger the SLF4J logger to use * @param the type held in the result */ public static void logLastException(RetryResult result, Logger logger) { logCommonResultInfo(result, logger, "last error logged below"); logLastErrorIfPresent(result, logger); } /** * Log the unique error types and the last exception contained in the result using the given logger. * * @param result the result * @param logger the SLF4J logger to use * @param the type held in the result */ public static void logExceptionTypesAndLast(RetryResult result, Logger logger) { logCommonResultInfo(result, logger, "error types and last error logged below"); var uniqueTypes = result.getUniqueErrorTypes(); logger.error("Result {}: {} unique error types: {}", result.getResultUuid(), uniqueTypes.size(), uniqueTypes); logLastErrorIfPresent(result, logger); } private static void logCommonResultInfo(RetryResult result, Logger logger, String customErrorTypeMessage) { checkArgumentsNotNull(result, logger); var displayMessage = result.hasAnyErrors() ? customErrorTypeMessage : NO_ERRORS_TO_LOG; logger.error("Result {}: attempts: {}, maxAttempts: {}, hasObject: {}, hasErrors: {}, numErrors: {} ({})", result.getResultUuid(), result.getNumAttemptsMade(), result.getMaxAttempts(), result.hasObject(), result.hasAnyErrors(), result.getNumErrors(), displayMessage); } private static void checkArgumentsNotNull(RetryResult result, Logger logger) { checkArgumentNotNull(result, "result cannot be null"); checkArgumentNotNull(logger, "logger cannot be null"); } private static void logLastErrorIfPresent(RetryResult result, Logger logger) { result.getLastErrorIfPresent().ifPresent(lastError -> logger.error("Result {}: last error (of {} total errors):", result.getResultUuid(), result.getNumErrors(), lastError)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy