X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.support.simple%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Flog4j%2FSlcExecutionAppender.java;h=190a0b69661863ec83a188177992dd76f95f9877;hb=04ef2e4533e909122a560a5cb6499fa62bac82ec;hp=997b6d04510e62e6ffa1f5c4ed2f8e22b6819996;hpb=b811ec0603b1e596f26eee8a5378c6294cba495d;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/log4j/SlcExecutionAppender.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/log4j/SlcExecutionAppender.java index 997b6d045..190a0b696 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/log4j/SlcExecutionAppender.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/log4j/SlcExecutionAppender.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Mathieu Baudier + * Copyright (C) 2007-2012 Argeo GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,67 +13,116 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.argeo.slc.log4j; import java.util.Date; +import java.util.concurrent.BlockingQueue; import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; import org.apache.log4j.spi.LoggingEvent; import org.argeo.slc.core.execution.ExecutionThread; import org.argeo.slc.core.execution.ProcessThreadGroup; -import org.argeo.slc.process.SlcExecutionStep; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; +import org.argeo.slc.execution.ExecutionStep; /** Not meant to be used directly in standard log4j config */ -public class SlcExecutionAppender extends AppenderSkeleton implements - InitializingBean, DisposableBean { - - private Layout layout = null; - private String pattern = "%m - %c%n"; - private Boolean onlyExecutionThread = true; - - public void afterPropertiesSet() { - if (layout != null) - setLayout(layout); - else - setLayout(new PatternLayout(pattern)); +public class SlcExecutionAppender extends AppenderSkeleton { + + private Boolean disabled = false; + + private String level = null; + + private Level log4jLevel = null; + + /** Marker to prevent stack overflow */ + private ThreadLocal dispatching = new ThreadLocal() { + + @Override + protected Boolean initialValue() { + return false; + } + }; + + // private Layout layout = null; + // private String pattern = "%m - %c%n"; + private Boolean onlyExecutionThread = false; + + public void init() { + // if (layout != null) + // setLayout(layout); + // else + // setLayout(new PatternLayout(pattern)); Logger.getRootLogger().addAppender(this); } @Override protected void append(LoggingEvent event) { + if (disabled) + return; + + if (dispatching.get()) + return; + + if (level != null && !level.trim().equals("")) { + if (log4jLevel == null || !log4jLevel.toString().equals(level)) + try { + log4jLevel = Level.toLevel(level); + } catch (Exception e) { + System.err + .println("Log4j level could not be set for level '" + + level + "', resetting it to null."); + e.printStackTrace(); + level = null; + } + + if (log4jLevel != null + && !event.getLevel().isGreaterOrEqual(log4jLevel)) { + return; + } + } + + // Check whether we are within an executing process Thread currentThread = Thread.currentThread(); if (currentThread.getThreadGroup() instanceof ProcessThreadGroup) { if (onlyExecutionThread && !(currentThread instanceof ExecutionThread)) return; - + final String type; if (event.getLevel().equals(Level.ERROR) || event.getLevel().equals(Level.FATAL)) - type = SlcExecutionStep.ERROR; + type = ExecutionStep.ERROR; else if (event.getLevel().equals(Level.WARN)) - type = SlcExecutionStep.WARNING; + type = ExecutionStep.WARNING; else if (event.getLevel().equals(Level.INFO)) - type = SlcExecutionStep.INFO; + type = ExecutionStep.INFO; else if (event.getLevel().equals(Level.DEBUG)) - type = SlcExecutionStep.DEBUG; + type = ExecutionStep.DEBUG; else if (event.getLevel().equals(Level.TRACE)) - type = SlcExecutionStep.TRACE; + type = ExecutionStep.TRACE; else - type = SlcExecutionStep.INFO; - - SlcExecutionStep step = new SlcExecutionStep(new Date(event - .getTimeStamp()), type, layout.format(event)); - - ((ProcessThreadGroup) currentThread.getThreadGroup()) - .dispatchAddStep(step); + type = ExecutionStep.INFO; + + ExecutionStep step = new ExecutionStep(event.getLoggerName(), + new Date(event.getTimeStamp()), type, event.getMessage() + .toString()); + + try { + dispatching.set(true); + BlockingQueue steps = ((ProcessThreadGroup) currentThread + .getThreadGroup()).getSteps(); + if (steps.remainingCapacity() == 0) { + stdOut("WARNING: execution steps queue is full, skipping step: " + + step); + // FIXME understand why it block indefinitely: the queue + // should be emptied by the logging thread + } else { + steps.add(step); + } + } finally { + dispatching.set(false); + } } } @@ -88,16 +137,29 @@ public class SlcExecutionAppender extends AppenderSkeleton implements return false; } - public void setLayout(Layout layout) { - this.layout = layout; - } + // public void setLayout(Layout layout) { + // this.layout = layout; + // } - public void setPattern(String pattern) { - this.pattern = pattern; + /** For development purpose, since using regular logging is not easy here */ + static void stdOut(Object obj) { + System.out.println(obj); } + // public void setPattern(String pattern) { + // this.pattern = pattern; + // } + public void setOnlyExecutionThread(Boolean onlyExecutionThread) { this.onlyExecutionThread = onlyExecutionThread; } + public void setDisabled(Boolean disabled) { + this.disabled = disabled; + } + + public void setLevel(String level) { + this.level = level; + } + }