[logback-dev] svn commit: r1853 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Mon Oct 20 21:51:43 CEST 2008
Author: ceki
Date: Mon Oct 20 21:51:43 2008
New Revision: 1853
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
Log:
LBCORE-58
UnsynchronizedAppenderBase is based on Ralph Goers contribution in LBCORE-58.
Note that AppenderBase remains unchanged. Appenders which need to handle synchronization on their
own can do so by deriving from UnsynchronizedAppenderBase.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java Mon Oct 20 21:51:43 2008
@@ -13,12 +13,13 @@
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.FilterAttachableImpl;
-import ch.qos.logback.core.spi.FilterReply;
+import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.WarnStatus;
/**
- * This class is used to manage base functionnalities of all appenders.
+ * Sets a skeleton implementation for appenders.
*
+ * <p>
* For more information about this appender, please refer to the online manual at
* http://logback.qos.ch/manual/appenders.html#AppenderBase
*
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java Mon Oct 20 21:51:43 2008
@@ -0,0 +1,144 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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;
+
+import ch.qos.logback.core.filter.Filter;
+import ch.qos.logback.core.spi.ContextAwareBase;
+import ch.qos.logback.core.spi.FilterAttachable;
+import ch.qos.logback.core.spi.FilterAttachableImpl;
+import ch.qos.logback.core.spi.FilterReply;
+import ch.qos.logback.core.status.WarnStatus;
+
+/**
+ * Similar to AppenderBase except that derived appenders need to handle
+ * thread synchronization on their own.
+ *
+ * @author Ceki Gülcü
+ * @author Ralph Goers
+ */
+abstract public class UnsynchronizedAppenderBase<E> extends ContextAwareBase implements
+ Appender<E>, FilterAttachable {
+
+ protected boolean started = false;
+
+ // using a ThreadLocal instead of a boolean add 75 nanoseconds per
+ // doAppend invocation. This is tolerable as doAppend takes at least a few microseconds
+ // on a real appender
+ /**
+ * The guard prevents an appender from repeatedly calling its own doAppend
+ * method.
+ */
+ private ThreadLocal<Boolean> guard = new ThreadLocal<Boolean>() {
+ protected Boolean initialValue() {
+ return false;
+ }
+ };
+
+ /**
+ * Appenders are named.
+ */
+ protected String name;
+
+ private FilterAttachableImpl fai = new FilterAttachableImpl();
+
+ public String getName() {
+ return name;
+ }
+
+ private int statusRepeatCount = 0;
+ private int exceptionCount = 0;
+
+ static final int ALLOWED_REPEATS = 5;
+
+ public synchronized void doAppend(E eventObject) {
+ // WARNING: The guard check MUST be the first statement in the
+ // doAppend() method.
+
+ // prevent re-entry.
+ if (guard.get()) {
+ return;
+ }
+
+ try {
+ guard.set(true);
+
+ if (!this.started) {
+ if (statusRepeatCount++ < ALLOWED_REPEATS) {
+ addStatus(new WarnStatus(
+ "Attempted to append to non started appender [" + name + "].",
+ this));
+ }
+ return;
+ }
+
+ if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
+ return;
+ }
+
+ // ok, we now invoke derived class' implementation of append
+ this.append(eventObject);
+
+ } catch (Exception e) {
+ if (exceptionCount++ < ALLOWED_REPEATS) {
+ addError("Appender [" + name + "] failed to append.", e);
+ }
+ } finally {
+ guard.set(false);
+ }
+ }
+
+ abstract protected void append(E eventObject);
+
+ /**
+ * Set the name of this appender.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void start() {
+ started = true;
+ }
+
+ public void stop() {
+ started = false;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public String toString() {
+ return this.getClass().getName() + "[" + name + "]";
+ }
+
+ public void addFilter(Filter newFilter) {
+ fai.addFilter(newFilter);
+ }
+
+ public Filter getFirstFilter() {
+ return fai.getFirstFilter();
+ }
+
+ public void clearAllFilters() {
+ fai.clearAllFilters();
+ }
+
+ public FilterReply getFilterChainDecision(Object event) {
+ return fai.getFilterChainDecision(event);
+ }
+
+ public Layout<E> getLayout() {
+ return null;
+ }
+
+ public void setLayout(Layout<E> layout) {
+ }
+}
More information about the logback-dev
mailing list