<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.theeggeadventure.com/wikimedia/index.php?action=history&amp;feed=atom&amp;title=SlowDownSpamEvaluator</id>
	<title>SlowDownSpamEvaluator - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.theeggeadventure.com/wikimedia/index.php?action=history&amp;feed=atom&amp;title=SlowDownSpamEvaluator"/>
	<link rel="alternate" type="text/html" href="https://www.theeggeadventure.com/wikimedia/index.php?title=SlowDownSpamEvaluator&amp;action=history"/>
	<updated>2026-05-13T09:48:37Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.0-beta</generator>
	<entry>
		<id>https://www.theeggeadventure.com/wikimedia/index.php?title=SlowDownSpamEvaluator&amp;diff=1799&amp;oldid=prev</id>
		<title>Egge: New page: Occasionally something will go wrong in a program an log4j will send a mountain of emails.  Here&#039;s a simple filtering class that can be used to prevent too many emails from being sent at o...</title>
		<link rel="alternate" type="text/html" href="https://www.theeggeadventure.com/wikimedia/index.php?title=SlowDownSpamEvaluator&amp;diff=1799&amp;oldid=prev"/>
		<updated>2007-11-06T22:25:32Z</updated>

		<summary type="html">&lt;p&gt;New page: Occasionally something will go wrong in a program an log4j will send a mountain of emails.  Here&amp;#039;s a simple filtering class that can be used to prevent too many emails from being sent at o...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Occasionally something will go wrong in a program an log4j will send a mountain of emails.  Here&amp;#039;s a simple filtering class that can be used to prevent too many emails from being sent at once.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;geshi lang=&amp;quot;java5&amp;quot;&amp;gt;&lt;br /&gt;
import java.util.LinkedList;&lt;br /&gt;
&lt;br /&gt;
import org.apache.log4j.spi.LoggingEvent;&lt;br /&gt;
import org.apache.log4j.spi.TriggeringEventEvaluator;&lt;br /&gt;
/**&lt;br /&gt;
 * This class is a filter for log4j to send at most four emails per hour.&lt;br /&gt;
 * @author brianegge&lt;br /&gt;
 */&lt;br /&gt;
public class SlowDownSpamEvaluator implements TriggeringEventEvaluator {&lt;br /&gt;
&lt;br /&gt;
	private static final int MAX_MESSAGES_PER_HOUR = 4;&lt;br /&gt;
	private final LinkedList queue = new LinkedList();&lt;br /&gt;
	private final TriggeringEventEvaluator parent;&lt;br /&gt;
	&lt;br /&gt;
	public SlowDownSpamEvaluator() {&lt;br /&gt;
		parent = null;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public SlowDownSpamEvaluator(TriggeringEventEvaluator parent) {&lt;br /&gt;
		this.parent = parent;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * At most, {@value #MAX_MESSAGES_PER_HOUR} messages per hour will be triggered. &lt;br /&gt;
	 * @return Is this the triggering event?&lt;br /&gt;
	 */&lt;br /&gt;
	public boolean isTriggeringEvent(LoggingEvent event) {&lt;br /&gt;
		long oneHourAgo = getTime() - 1000L * 60 * 60;&lt;br /&gt;
		synchronized (queue) {&lt;br /&gt;
			while(queue.size() &amp;gt; 0 &amp;amp;&amp;amp; ((Long)queue.getLast()).longValue() &amp;lt;= oneHourAgo)&lt;br /&gt;
				queue.removeLast();&lt;br /&gt;
			if (queue.size() &amp;gt;= MAX_MESSAGES_PER_HOUR) { // we&amp;#039;ve sent more than four messages in the past hour&lt;br /&gt;
				return false;&lt;br /&gt;
			}&lt;br /&gt;
			queue.addFirst(new Long(getTime()));&lt;br /&gt;
		}&lt;br /&gt;
		if (parent != null) &lt;br /&gt;
			return parent.isTriggeringEvent(event);&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * subclasses can override this method for testing.  &amp;lt;a href=&amp;quot;http://joda-time.sourceforge.net/&amp;quot;&amp;gt;&lt;br /&gt;
	 * Joda Time&amp;lt;/a&amp;gt; provides good testing capabilities,&lt;br /&gt;
	 * but I don&amp;#039;t want to add an external dependency.&lt;br /&gt;
	 * &lt;br /&gt;
	 * @return System.currentTimeMillis()&lt;br /&gt;
	 */&lt;br /&gt;
	protected long getTime() {&lt;br /&gt;
		return System.currentTimeMillis();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/geshi&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And of course the test case.&lt;br /&gt;
&amp;lt;geshi lang=&amp;quot;java5&amp;quot;&amp;gt;&lt;br /&gt;
import org.apache.log4j.spi.LoggingEvent;&lt;br /&gt;
import org.apache.log4j.spi.TriggeringEventEvaluator;&lt;br /&gt;
&lt;br /&gt;
import junit.framework.TestCase;&lt;br /&gt;
&lt;br /&gt;
public class SlowDownSpamEvaluatorUnitTest extends TestCase implements TriggeringEventEvaluator {&lt;br /&gt;
&lt;br /&gt;
	int parent;&lt;br /&gt;
	long offset;&lt;br /&gt;
	&lt;br /&gt;
	public void testIsTriggeringEvent() {&lt;br /&gt;
		TriggeringEventEvaluator evaluator = new SlowDownSpamEvaluator() {&lt;br /&gt;
			protected long getTime() {&lt;br /&gt;
				return super.getTime() + offset;&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
		assertTrue(evaluator.isTriggeringEvent(null));&lt;br /&gt;
		assertTrue(evaluator.isTriggeringEvent(null));&lt;br /&gt;
		assertTrue(evaluator.isTriggeringEvent(null));&lt;br /&gt;
		assertTrue(evaluator.isTriggeringEvent(null));&lt;br /&gt;
		assertFalse(evaluator.isTriggeringEvent(null));&lt;br /&gt;
		offset += 1000L * 60 * 60; // One hour&lt;br /&gt;
		assertTrue(evaluator.isTriggeringEvent(null));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public void testParent() throws Exception {&lt;br /&gt;
		TriggeringEventEvaluator evaluator = new SlowDownSpamEvaluator(this);&lt;br /&gt;
		assertEquals(0, parent);&lt;br /&gt;
		assertFalse(evaluator.isTriggeringEvent(null));&lt;br /&gt;
		assertEquals(1, parent);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// we could use EasyMock, but since this is a small project, I&amp;#039;ll create the stub in-line&lt;br /&gt;
	public boolean isTriggeringEvent(LoggingEvent event) {&lt;br /&gt;
		parent++;&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/geshi&amp;gt;&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>Egge</name></author>
	</entry>
</feed>