问题描述
我认为这是一个非常基本的要求,尽管难以有效地实施:
在一个代码库中,我们根据用户行为进行了很多记录.为了参数,每次点击按钮都会以单击按钮的名称创建一个日志消息.
现在,我不在乎每个点击按钮.我很满意每5分钟打印一次消息,无论用户单击按钮的次数如何.
我可以在用户代码中很容易地执行此操作:
private static final Logger LOG = Logger.getLogger("buttons"); private static final long LOG_ONLY_EVERY = Duration.ofMinutes( 5 ).getSeconds(); private static final Map<String, Long> loggedViolations = new HashMap<>(); public static void logClick( String buttonName ) { String msg = "Button " + buttonName + " has been clicked"; final long epochSecond = Instant.now( Clock.systemUTC() ).getEpochSecond(); if ( !loggedViolations.containsKey( msg ) ) { loggedViolations.put( msg, epochSecond ); } if ( loggedViolations.get( msg ) + LOG_ONLY_EVERY < epochSecond ) { LOG.warn( msg ); loggedViolations.put( msg, epochSecond ); } }
我的问题是:SLF4J或Log4J可以为我做到这一点吗?如何?
是的,我知道上述代码缺乏同步.如果上述问题的答案是"不,您自己做" - 以上在多线程环境中会安全(因为我不删除消息)?
推荐答案
使用 burstfilter "> burstfilter buttons记录器:
BurstFilter提供了一种机制,可以控制达到最大极限后默默丢弃事件处理的速率.
用于记录,请使用 deplicatemessagefilter .
问题描述
I thought this is a pretty basic requirement, although difficult to implement efficiently:
At one codebase, we log quite a bit, depending on user behavior. For the sake of argument say every click on a button creates a log message with the name of the clicked button.
Now, I don't care about each and every clicked button. I'm quite content having one message printed once every 5 minutes, regardless of the number of times the user clicked the button.
I can do this pretty easily in user code:
private static final Logger LOG = Logger.getLogger("buttons"); private static final long LOG_ONLY_EVERY = Duration.ofMinutes( 5 ).getSeconds(); private static final Map<String, Long> loggedViolations = new HashMap<>(); public static void logClick( String buttonName ) { String msg = "Button " + buttonName + " has been clicked"; final long epochSecond = Instant.now( Clock.systemUTC() ).getEpochSecond(); if ( !loggedViolations.containsKey( msg ) ) { loggedViolations.put( msg, epochSecond ); } if ( loggedViolations.get( msg ) + LOG_ONLY_EVERY < epochSecond ) { LOG.warn( msg ); loggedViolations.put( msg, epochSecond ); } }
My question is: can SLF4J or Log4J do this for me? How?
And yes, I'm aware the above code is lacking synchronization. If the answer to the above question is "no, do it yourself" - would the above be safe in a multi-threaded environment (since I don't remove messages, anyway)?
推荐答案
Use the BurstFilter and install it on the buttons logger:
The BurstFilter provides a mechanism to control the rate at which LogEvents are processed by silently discarding events after the maximum limit has been reached.
For Logback use the DuplicateMessageFilter.