Forráskód Böngészése

assira.junit: we use our own slf4j.LogObserver instead of slf4j.SimpleLogger

Ranides Atterwim 10 éve
szülő
commit
9ab451ccbc

+ 4 - 0
assira.junit/pom.xml

@@ -35,5 +35,9 @@
             <groupId>com.google.code.findbugs</groupId>
             <artifactId>annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 44 - 0
assira.junit/src/main/java/net/ranides/assira/junit/LogMessage.java

@@ -0,0 +1,44 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira.junit
+ */
+package net.ranides.assira.junit;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class LogMessage {
+    
+    private final int level;
+            
+    private final String text;
+    
+    private final Throwable error;
+
+    LogMessage(int level, String text, Throwable error) {
+        this.level = level;
+        this.text = (error==null) ? text : text + " @ " + error.toString();
+        this.error = error;
+    }
+    
+    public String text() {
+        return text;
+    }
+  
+    public int level() {
+        return level;
+    }
+    
+    public Throwable error() {
+        return error;
+    }
+
+    @Override
+    public String toString() {
+        return text;
+    }
+    
+}

+ 59 - 0
assira.junit/src/main/java/net/ranides/assira/junit/LogObserver.java

@@ -0,0 +1,59 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira.junit
+ */
+package net.ranides.assira.junit;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.stream.Stream;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class LogObserver {
+    
+    private static final Queue<LogMessage> TARGET = new ConcurrentLinkedQueue<>();
+    
+    private static final boolean DEBUG = "true".equals(System.getProperty("assira.junit.debug"));
+    
+    private static final boolean ENABLED = "true".equals(System.getProperty("assira.junit.logger.observe"));
+    
+    private static volatile boolean debug = DEBUG;
+    
+    private static volatile boolean enabled = ENABLED;
+        
+    private LogObserver() {
+        /* utility class */
+    }
+    
+    @SuppressWarnings("PMD.SystemPrintln")
+    public static void append(int level, String message, Throwable error) {
+        if(enabled) {
+            TARGET.add(new LogMessage(level, message, error));
+        }
+        if(debug) {
+            System.err.println(message);
+            if(null != error) {
+                error.printStackTrace(System.err);
+            }
+        }
+    }
+    
+    public static void debug(boolean value) {
+        debug = value;
+    }
+    
+    public static void reset(boolean enabled) {
+        TARGET.clear();
+        LogObserver.enabled = enabled;
+    }
+    
+    public static Stream<LogMessage> messages() {
+        return TARGET.stream();
+    }
+    
+}

+ 210 - 0
assira.junit/src/main/java/org/slf4j/impl/ObserveLogger.java

@@ -0,0 +1,210 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira.junit
+ */
+package org.slf4j.impl;
+
+
+import net.ranides.assira.junit.LogObserver;
+import org.slf4j.helpers.FormattingTuple;
+import org.slf4j.helpers.MarkerIgnoringBase;
+import org.slf4j.helpers.MessageFormatter;
+import static org.slf4j.spi.LocationAwareLogger.*;
+
+/**
+ * 
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class ObserveLogger extends MarkerIgnoringBase {
+
+    private static final long serialVersionUID = 7L;
+
+    ObserveLogger(String name) {
+        this.name = name;
+    }
+
+    private void log(int level, String message, Throwable t) {
+        StringBuilder buf = new StringBuilder(32);
+        buf.append('[').append(Thread.currentThread().getName()).append("] ");
+
+        switch (level) {
+            case TRACE_INT:
+                buf.append("TRACE");
+                break;
+            case DEBUG_INT:
+                buf.append("DEBUG");
+                break;
+            case INFO_INT:
+                buf.append("INFO");
+                break;
+            case WARN_INT:
+                buf.append("WARN");
+                break;
+            case ERROR_INT:
+                buf.append("ERROR");
+                break;
+            default:
+                throw new AssertionError("Unknown level: " + level);
+        }
+        buf.append(' ').append(String.valueOf(name)).append(" - ").append(message);
+        LogObserver.append(level, buf.toString(), t);
+
+    }
+
+    private void formatAndLog(int level, String format, Object... arguments) {
+        FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments);
+        log(level, tp.getMessage(), tp.getThrowable());
+    }
+
+    @Override
+    public boolean isTraceEnabled() {
+        return true;
+    }
+
+    @Override
+    public void trace(String msg) {
+        log(TRACE_INT, msg, null);
+    }
+
+    @Override
+    public void trace(String format, Object param1) {
+        formatAndLog(TRACE_INT, format, param1, null);
+    }
+
+    @Override
+    public void trace(String format, Object param1, Object param2) {
+        formatAndLog(TRACE_INT, format, param1, param2);
+    }
+
+    @Override
+    public void trace(String format, Object... argArray) {
+        formatAndLog(TRACE_INT, format, argArray);
+    }
+
+    @Override
+    public void trace(String msg, Throwable t) {
+        log(TRACE_INT, msg, t);
+    }
+
+    @Override
+    public boolean isDebugEnabled() {
+        return true;
+    }
+
+    @Override
+    public void debug(String msg) {
+        log(DEBUG_INT, msg, null);
+    }
+
+    @Override
+    public void debug(String format, Object param1) {
+        formatAndLog(DEBUG_INT, format, param1, null);
+    }
+
+    @Override
+    public void debug(String format, Object param1, Object param2) {
+        formatAndLog(DEBUG_INT, format, param1, param2);
+    }
+
+    @Override
+    public void debug(String format, Object... argArray) {
+        formatAndLog(DEBUG_INT, format, argArray);
+    }
+
+    @Override
+    public void debug(String msg, Throwable t) {
+        log(DEBUG_INT, msg, t);
+    }
+
+    @Override
+    public boolean isInfoEnabled() {
+        return true;
+    }
+
+    @Override
+    public void info(String msg) {
+        log(INFO_INT, msg, null);
+    }
+
+    @Override
+    public void info(String format, Object arg) {
+        formatAndLog(INFO_INT, format, arg, null);
+    }
+
+    @Override
+    public void info(String format, Object arg1, Object arg2) {
+        formatAndLog(INFO_INT, format, arg1, arg2);
+    }
+
+    @Override
+    public void info(String format, Object... argArray) {
+        formatAndLog(INFO_INT, format, argArray);
+    }
+
+    @Override
+    public void info(String msg, Throwable t) {
+        log(INFO_INT, msg, t);
+    }
+
+    @Override
+    public boolean isWarnEnabled() {
+        return true;
+    }
+
+    @Override
+    public void warn(String msg) {
+        log(WARN_INT, msg, null);
+    }
+
+    @Override
+    public void warn(String format, Object arg) {
+        formatAndLog(WARN_INT, format, arg, null);
+    }
+
+    @Override
+    public void warn(String format, Object arg1, Object arg2) {
+        formatAndLog(WARN_INT, format, arg1, arg2);
+    }
+
+    @Override
+    public void warn(String format, Object... argArray) {
+        formatAndLog(WARN_INT, format, argArray);
+    }
+
+    @Override
+    public void warn(String msg, Throwable t) {
+        log(WARN_INT, msg, t);
+    }
+
+    @Override
+    public boolean isErrorEnabled() {
+        return true;
+    }
+
+    @Override
+    public void error(String msg) {
+        log(ERROR_INT, msg, null);
+    }
+
+    @Override
+    public void error(String format, Object arg) {
+        formatAndLog(ERROR_INT, format, arg, null);
+    }
+
+    @Override
+    public void error(String format, Object arg1, Object arg2) {
+        formatAndLog(ERROR_INT, format, arg1, arg2);
+    }
+
+    @Override
+    public void error(String format, Object... argArray) {
+        formatAndLog(ERROR_INT, format, argArray);
+    }
+
+    @Override
+    public void error(String msg, Throwable t) {
+        log(ERROR_INT, msg, t);
+    }
+}

+ 62 - 0
assira.junit/src/main/java/org/slf4j/impl/ObserveLoggerFactory.java

@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free  of charge, to any person obtaining
+ * a  copy  of this  software  and  associated  documentation files  (the
+ * "Software"), to  deal in  the Software without  restriction, including
+ * without limitation  the rights to  use, copy, modify,  merge, publish,
+ * distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ * permit persons to whom the Software  is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The  above  copyright  notice  and  this permission  notice  shall  be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package org.slf4j.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.slf4j.Logger;
+import org.slf4j.ILoggerFactory;
+
+/**
+ * An implementation of {@link ILoggerFactory} which always returns
+ * {@link ObserveLogger} instances.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public class ObserveLoggerFactory implements ILoggerFactory {
+
+    ConcurrentMap<String, Logger> loggerMap;
+
+    public ObserveLoggerFactory() {
+        loggerMap = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * Return an appropriate {@link ObserveLogger} instance by name.
+     */
+    @Override
+    public Logger getLogger(String name) {
+        Logger simpleLogger = loggerMap.get(name);
+        if (simpleLogger != null) {
+            return simpleLogger;
+        } else {
+            Logger newInstance = new ObserveLogger(name);
+            Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
+            return oldInstance == null ? newInstance : oldInstance;
+        }
+    }
+
+}

+ 82 - 0
assira.junit/src/main/java/org/slf4j/impl/StaticLoggerBinder.java

@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free  of charge, to any person obtaining
+ * a  copy  of this  software  and  associated  documentation files  (the
+ * "Software"), to  deal in  the Software without  restriction, including
+ * without limitation  the rights to  use, copy, modify,  merge, publish,
+ * distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ * permit persons to whom the Software  is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The  above  copyright  notice  and  this permission  notice  shall  be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package org.slf4j.impl;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
+import org.slf4j.spi.LoggerFactoryBinder;
+
+/**
+ * The binding of {@link LoggerFactory} class with an actual instance of
+ * {@link ILoggerFactory} is performed using information returned by this class.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public final class StaticLoggerBinder implements LoggerFactoryBinder {
+
+    /**
+     * Declare the version of the SLF4J API this implementation is compiled
+     * against. The value of this field is usually modified with each release.
+     */
+    // to avoid constant folding by the compiler, this field must *not* be final
+    public static String REQUESTED_API_VERSION = "1.6.99"; // !final
+    
+    /**
+     * The unique instance of this class.
+     * 
+     */
+    private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
+
+    private static final String FACTORY_CLASSNAME = ObserveLoggerFactory.class.getName();
+    
+    /**
+     * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
+     * method should always be the same object
+     */
+    private final ILoggerFactory factory;
+
+    private StaticLoggerBinder() {
+        factory = new ObserveLoggerFactory();
+    }
+    
+    /**
+     * Return the singleton of this class.
+     * 
+     * @return the StaticLoggerBinder singleton
+     */
+    public static StaticLoggerBinder getSingleton() {
+        return SINGLETON;
+    }
+
+    @Override
+    public ILoggerFactory getLoggerFactory() {
+        return factory;
+    }
+
+    @Override
+    public String getLoggerFactoryClassStr() {
+        return FACTORY_CLASSNAME;
+    }
+}

+ 57 - 0
assira.junit/src/main/java/org/slf4j/impl/StaticMDCBinder.java

@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free  of charge, to any person obtaining
+ * a  copy  of this  software  and  associated  documentation files  (the
+ * "Software"), to  deal in  the Software without  restriction, including
+ * without limitation  the rights to  use, copy, modify,  merge, publish,
+ * distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ * permit persons to whom the Software  is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The  above  copyright  notice  and  this permission  notice  shall  be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package org.slf4j.impl;
+
+import org.slf4j.helpers.NOPMDCAdapter;
+import org.slf4j.spi.MDCAdapter;
+
+/**
+ * This implementation is bound to {@link NOPMDCAdapter}.
+ *
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public final class StaticMDCBinder {
+
+    /**
+     * The unique instance of this class.
+     */
+    public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
+
+    private StaticMDCBinder() {
+        /* singleton */
+    }
+
+    /**
+     * Currently this method always returns an instance of 
+     * {@link StaticMDCBinder}.
+     */
+    public MDCAdapter getMDCA() {
+        return new NOPMDCAdapter();
+    }
+
+    public String getMDCAdapterClassStr() {
+        return NOPMDCAdapter.class.getName();
+    }
+}

+ 71 - 0
assira.junit/src/main/java/org/slf4j/impl/StaticMarkerBinder.java

@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free  of charge, to any person obtaining
+ * a  copy  of this  software  and  associated  documentation files  (the
+ * "Software"), to  deal in  the Software without  restriction, including
+ * without limitation  the rights to  use, copy, modify,  merge, publish,
+ * distribute,  sublicense, and/or sell  copies of  the Software,  and to
+ * permit persons to whom the Software  is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The  above  copyright  notice  and  this permission  notice  shall  be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+ * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+ * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+package org.slf4j.impl;
+
+import org.slf4j.IMarkerFactory;
+import org.slf4j.MarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.spi.MarkerFactoryBinder;
+
+/**
+ * 
+ * The binding of {@link MarkerFactory} class with an actual instance of 
+ * {@link IMarkerFactory} is performed using information returned by this class. 
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public final class StaticMarkerBinder implements MarkerFactoryBinder {
+
+    /**
+     * The unique instance of this class.
+     */
+    public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
+
+    final IMarkerFactory markerFactory = new BasicMarkerFactory();
+
+    private StaticMarkerBinder() {
+        /* singleton */
+    }
+
+    /**
+     * Currently this method always returns an instance of 
+     * {@link BasicMarkerFactory}.
+     */
+    @Override
+    public IMarkerFactory getMarkerFactory() {
+        return markerFactory;
+    }
+
+    /**
+     * Currently, this method returns the class name of
+     * {@link BasicMarkerFactory}.
+     */
+    @Override
+    public String getMarkerFactoryClassStr() {
+        return BasicMarkerFactory.class.getName();
+    }
+
+}