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

com.almworks.jira.structure.api.util.ConsiderateLogger Maven / Gradle / Ivy

There is a newer version: 17.25.3
Show newest version
package com.almworks.jira.structure.api.util;

import org.slf4j.Logger;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * Utility class that is used to log errors that are likely to happen often. Muffles repetitive errors.
 * 

* First method invocation will set the skipped messages log level.
* If you use {@link #warn(String, String)} and then {@link #info(String, String)} for the same source, then the messages about skipped messages will be logged at warn level. * */ public class ConsiderateLogger { private static long DEFAULT_INTERVAL = TimeUnit.MINUTES.toNanos(5); private final Logger myLogger; private final ConcurrentMap myStats = new ConcurrentHashMap<>(); private volatile long myInterval = DEFAULT_INTERVAL; public ConsiderateLogger(Logger logger) { myLogger = logger; } public ConsiderateLogger(Logger logger, long interval) { myLogger = logger; myInterval = interval; } public void info(String source, String message) { if (acceptSource(source, Level.INFO)) { myLogger.info(source + " " + message); } } public void info(String source, String message, Throwable throwable) { if (acceptSource(source, Level.INFO)) { myLogger.info(source + " " + message, throwable); } } public void warn(String source, String message) { if (acceptSource(source, Level.WARN)) { myLogger.warn(source + " " + message); } } public void warn(String source, String message, Throwable throwable) { if (acceptSource(source, Level.WARN)) { myLogger.warn(source + " " + message, throwable); } } private boolean acceptSource(String source, Level level) { SourceStats stats = myStats.get(source); if (stats == null) { stats = new SourceStats(source, level); myStats.putIfAbsent(source, stats); } return stats.isAcceptable(); } public void reset() { myStats.clear(); } public void setInterval(long interval) { myInterval = interval; } private enum Level { INFO, WARN } private class SourceStats { private final String mySource; private final AtomicInteger myCount = new AtomicInteger(); private final Level myLevel; private volatile long myLastLogTime; public SourceStats(String source, Level level) { mySource = source; myLevel = level; } public boolean isAcceptable() { long now = System.nanoTime(); if (myLastLogTime != 0 && now - myLastLogTime <= myInterval) { myCount.incrementAndGet(); return false; } myLastLogTime = now; int count = myCount.getAndSet(0); if (count > 0) { switch (myLevel) { case INFO: myLogger.info(count + " info log entries from " + mySource + " were not shown"); break; case WARN: default: myLogger.warn(count + " warnings from " + mySource + " were not shown"); } } return true; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy