[logback-dev] svn commit: r625 - in logback/trunk: logback-access/src/main/java/ch/qos/logback/access/net logback-classic/src/main/java/ch/qos/logback/classic/helpers logback-classic/src/main/java/ch/qos/logback/classic/net logback-core/src/main/java/ch/qos/logback/core/helpers
noreply.seb at qos.ch
noreply.seb at qos.ch
Thu Oct 5 10:44:41 CEST 2006
Author: seb
Date: Thu Oct 5 10:44:41 2006
New Revision: 625
Added:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/net/
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/helpers/CyclicBuffer.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
Log:
- added SMTPAppender for access module
- moved CyclicBuffer.java to the core module
- modified classic module's SMTPAppender accordingly
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/net/SMTPAppender.java Thu Oct 5 10:44:41 2006
@@ -0,0 +1,144 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.access.net;
+
+import java.io.File;
+
+import ch.qos.logback.access.PatternLayout;
+import ch.qos.logback.core.helpers.CyclicBuffer;
+import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.net.SMTPAppenderBase;
+import ch.qos.logback.core.rolling.TriggeringPolicy;
+
+/**
+ * Send an e-mail when a specific access event occurs, typically on errors or
+ * fatal errors.
+ *
+ * <p>
+ * The number of access events delivered in this e-mail depend on the value of
+ * <b>BufferSize</b> option. The <code>SMTPAppender</code> keeps only the
+ * last <code>BufferSize</code> access events in its cyclic buffer. This
+ * keeps memory requirements at a reasonable level while still delivering useful
+ * application context.
+ * <p>
+ * By default, the email is sent everything an event has a status code of
+ * 500 (server error) or higher.
+ * <p>
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ *
+ */
+public class SMTPAppender extends SMTPAppenderBase {
+
+ static final String DEFAULT_SUBJECT_PATTERN = "%m";
+
+ private int bufferSize = 512;
+ protected CyclicBuffer cb = new CyclicBuffer(bufferSize);
+
+ /**
+ * The default constructor will instantiate the appender with a
+ * {@link TriggeringEventEvaluator} that will trigger on events with level
+ * ERROR or higher.
+ */
+ public SMTPAppender() {
+ this(new DefaultEvaluator());
+ }
+
+ /**
+ * Use <code>evaluator</code> passed as parameter as the {@link
+ * TriggeringEventEvaluator} for this SMTPAppender.
+ */
+ public SMTPAppender(TriggeringPolicy evaluator) {
+ this.evaluator = evaluator;
+ }
+
+ /**
+ * Perform SMTPAppender specific appending actions, mainly adding the event to
+ * a cyclic buffer.
+ */
+ protected void subAppend(Object eventObject) {
+ AccessEvent event = (AccessEvent) eventObject;
+
+ cb.add(event);
+ // addInfo("Added event to the cyclic buffer: " + event.getMessage());
+ }
+
+ @Override
+ protected void fillBuffer(StringBuffer sbuf) {
+ int len = cb.length();
+ for (int i = 0; i < len; i++) {
+ // sbuf.append(MimeUtility.encodeText(layout.format(cb.get())));
+ Object event = cb.get();
+ sbuf.append(layout.doLayout(event));
+ }
+ }
+
+ /**
+ * The <b>BufferSize</b> option takes a positive integer representing the
+ * maximum number of logging events to collect in a cyclic buffer. When the
+ * <code>BufferSize</code> is reached, oldest events are deleted as new
+ * events are added to the buffer. By default the size of the cyclic buffer is
+ * 512 events.
+ */
+ public void setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ cb.resize(bufferSize);
+ }
+
+ /**
+ * Returns value of the <b>BufferSize</b> option.
+ */
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+ @Override
+ protected Layout makeSubjectLayout(String subjectStr) {
+ if(subjectStr == null) {
+ subjectStr = DEFAULT_SUBJECT_PATTERN;
+ }
+ PatternLayout pl = new PatternLayout();
+ pl.setPattern(subjectStr);
+ pl.start();
+ return pl;
+ }
+}
+
+class DefaultEvaluator implements TriggeringPolicy {
+
+ private boolean started;
+
+ private static final Integer TRIGGERING_STATUS_CODE = 500;
+ /**
+ * Is this <code>event</code> the e-mail triggering event?
+ *
+ * <p>
+ * This method returns <code>true</code>, if the event status code
+ * is 500 (server error) or higher. Otherwise it returns <code>false</code>.
+ */
+ public boolean isTriggeringEvent(File file, Object eventObject) {
+ AccessEvent event = (AccessEvent) eventObject;
+ return TRIGGERING_STATUS_CODE.compareTo(event.getStatusCode()) <= 0;
+ }
+
+ public boolean isStarted() {
+ return started == true;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java Thu Oct 5 10:44:41 2006
@@ -14,7 +14,7 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.classic.helpers.CyclicBuffer;
+import ch.qos.logback.core.helpers.CyclicBuffer;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.net.SMTPAppenderBase;
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java Thu Oct 5 10:44:41 2006
@@ -0,0 +1,142 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ *
+ * Copyright (C) 1999-2006, QOS.ch
+ *
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.core.helpers;
+
+
+/**
+ *
+ * CyclicBuffer is used by other appenders to hold
+ * objects for immediate or differed display.
+ * <p>
+ * This buffer gives read access to any element in the buffer not just the first
+ * or last element.
+ *
+ * @author Ceki Gülcü
+ */
+public class CyclicBuffer {
+
+ Object[] ea;
+ int first;
+ int last;
+ int numElems;
+ int maxSize;
+
+ /**
+ * Instantiate a new CyclicBuffer of at most <code>maxSize</code> events.
+ *
+ * The <code>maxSize</code> argument must a positive integer.
+ *
+ * @param maxSize
+ * The maximum number of elements in the buffer.
+ */
+ public CyclicBuffer(int maxSize) throws IllegalArgumentException {
+ if (maxSize < 1) {
+ throw new IllegalArgumentException("The maxSize argument (" + maxSize
+ + ") is not a positive integer.");
+ }
+ this.maxSize = maxSize;
+ ea = new Object[maxSize];
+ first = 0;
+ last = 0;
+ numElems = 0;
+ }
+
+ /**
+ * Add an <code>event</code> as the last event in the buffer.
+ *
+ */
+ public void add(Object event) {
+ ea[last] = event;
+ if (++last == maxSize)
+ last = 0;
+
+ if (numElems < maxSize)
+ numElems++;
+ else if (++first == maxSize)
+ first = 0;
+ }
+
+ /**
+ * Get the <i>i</i>th oldest event currently in the buffer. If <em>i</em>
+ * is outside the range 0 to the number of elements currently in the buffer,
+ * then <code>null</code> is returned.
+ */
+ public Object get(int i) {
+ if (i < 0 || i >= numElems)
+ return null;
+
+ return ea[(first + i) % maxSize];
+ }
+
+ public int getMaxSize() {
+ return maxSize;
+ }
+
+
+ /**
+ * Get the oldest (first) element in the buffer. The oldest element is removed
+ * from the buffer.
+ */
+ public Object get() {
+ Object r = null;
+ if (numElems > 0) {
+ numElems--;
+ r = ea[first];
+ ea[first] = null;
+ if (++first == maxSize)
+ first = 0;
+ }
+ return r;
+ }
+
+ /**
+ * Get the number of elements in the buffer. This number is guaranteed to be
+ * in the range 0 to <code>maxSize</code> (inclusive).
+ */
+ public int length() {
+ return numElems;
+ }
+
+ /**
+ * Resize the cyclic buffer to <code>newSize</code>.
+ *
+ * @throws IllegalArgumentException
+ * if <code>newSize</code> is negative.
+ */
+ public void resize(int newSize) {
+ if (newSize < 0) {
+ throw new IllegalArgumentException("Negative array size [" + newSize
+ + "] not allowed.");
+ }
+ if (newSize == numElems)
+ return; // nothing to do
+
+ Object[] temp = new Object[newSize];
+
+ int loopLen = newSize < numElems ? newSize : numElems;
+
+ for (int i = 0; i < loopLen; i++) {
+ temp[i] = ea[first];
+ ea[first] = null;
+ if (++first == numElems)
+ first = 0;
+ }
+ ea = temp;
+ first = 0;
+ numElems = loopLen;
+ maxSize = newSize;
+ if (loopLen == newSize) {
+ last = 0;
+ } else {
+ last = loopLen;
+ }
+ }
+}
More information about the logback-dev
mailing list