diff --git a/bom/pom.xml b/bom/pom.xml index d1320ac80..239681944 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -22,24 +22,24 @@ 2.0.4-SNAPSHOT 2.0.0 - 2.1.3-SNAPSHOT - 3.0.1-SNAPSHOT + 3.0.0-SNAPSHOT + 3.1.0-SNAPSHOT 2.0.4-SNAPSHOT 2.0.2-SNAPSHOT 1.0.0 2.0.2-SNAPSHOT 1.1.1-SNAPSHOT 2.0.0 - 2.0.0 + 2.0.1-SNAPSHOT 2.0.0 - 2.0.0 + 2.0.1-SNAPSHOT 1.0.1-SNAPSHOT 2.1.1-SNAPSHOT 2.2.1-SNAPSHOT 2.0.0 2.0.2-SNAPSHOT 1.0.1 - 2.0.0 + 2.0.1-SNAPSHOT 0.7.2 diff --git a/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/EventBusMessageListener.java b/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/EventBusMessageListener.java index f2ff0b67a..139da39d2 100644 --- a/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/EventBusMessageListener.java +++ b/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/EventBusMessageListener.java @@ -26,7 +26,6 @@ public class EventBusMessageListener implements XProcMessageListener { EventBusProvider eventBus; MessageBuliderFactory messageBuilderFactory; Properties props; - int sequence = 0; public EventBusMessageListener(EventBusProvider eventBus, Properties props) { @@ -40,7 +39,6 @@ private void post(MessageBuilder builder) { if (props != null && props.getProperty("JOB_ID")!=null) { builder.withJobId(props.getProperty("JOB_ID")); } - builder.withSequence(sequence++); builder.withTimeStamp(new Date()); eventBus.get().post(builder.build()); } diff --git a/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/XProcMessageListenerAggregator.java b/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/XProcMessageListenerAggregator.java index 77479d073..4a56b06c3 100644 --- a/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/XProcMessageListenerAggregator.java +++ b/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/XProcMessageListenerAggregator.java @@ -121,7 +121,7 @@ public void warning(XProcRunnable arg0, XdmNode arg1, String arg2) { @Override public void warning(Throwable throwable) { for(XProcMessageListener l:mListeners){ - l.error(throwable); + l.warning(throwable); } } diff --git a/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/slf4jXProcMessageListener.java b/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/slf4jXProcMessageListener.java index 874f737de..9ac0191f7 100644 --- a/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/slf4jXProcMessageListener.java +++ b/calabash-adapter/src/main/java/org/daisy/common/xproc/calabash/impl/slf4jXProcMessageListener.java @@ -26,21 +26,17 @@ public class slf4jXProcMessageListener implements XProcMessageListener { /** The default logger. */ private static Logger defaultLogger = LoggerFactory.getLogger("com.xmlcalabash"); - /** The log. */ - private Logger log = defaultLogger; - /* (non-Javadoc) * @see com.xmlcalabash.core.XProcMessageListener#error(com.xmlcalabash.core.XProcRunnable, net.sf.saxon.s9api.XdmNode, java.lang.String, net.sf.saxon.s9api.QName) */ @Override public void error(XProcRunnable step, XdmNode node, String message, QName code) { - + Logger log; if (step != null) { log = LoggerFactory.getLogger(step.getClass()); } else { log = defaultLogger; } - log.error(XprocMessageHelper.logLine(step, node, message, code)); } @@ -49,8 +45,7 @@ public void error(XProcRunnable step, XdmNode node, String message, QName code) */ @Override public void error(Throwable exception) { - - + Logger log = defaultLogger; log.error(XprocMessageHelper.errorLogline(exception)); } @@ -59,6 +54,7 @@ public void error(Throwable exception) { */ @Override public void warning(XProcRunnable step, XdmNode node, String message) { + Logger log; if (step != null) { log = LoggerFactory.getLogger(step.getClass()); } else { @@ -72,6 +68,7 @@ public void warning(XProcRunnable step, XdmNode node, String message) { */ @Override public void info(XProcRunnable step, XdmNode node, String message) { + Logger log; if (step != null) { log = LoggerFactory.getLogger(step.getClass()); } else { @@ -85,6 +82,7 @@ public void info(XProcRunnable step, XdmNode node, String message) { */ @Override public void fine(XProcRunnable step, XdmNode node, String message) { + Logger log; if (step != null) { log = LoggerFactory.getLogger(step.getClass()); } else { @@ -98,6 +96,7 @@ public void fine(XProcRunnable step, XdmNode node, String message) { */ @Override public void finer(XProcRunnable step, XdmNode node, String message) { + Logger log; if (step != null) { log = LoggerFactory.getLogger(step.getClass()); } else { @@ -111,6 +110,7 @@ public void finer(XProcRunnable step, XdmNode node, String message) { */ @Override public void finest(XProcRunnable step, XdmNode node, String message) { + Logger log; if (step != null) { log = LoggerFactory.getLogger(step.getClass()); } else { @@ -124,8 +124,8 @@ public void finest(XProcRunnable step, XdmNode node, String message) { */ @Override public void warning(Throwable exception) { - log.warn(XprocMessageHelper.errorLogline(exception)); - + Logger log = defaultLogger; + log.warn(XprocMessageHelper.errorLogline(exception)); } diff --git a/common-utils/pom.xml b/common-utils/pom.xml index 8e3ef787d..984423f71 100644 --- a/common-utils/pom.xml +++ b/common-utils/pom.xml @@ -9,7 +9,7 @@ common-utils - 2.1.3-SNAPSHOT + 3.0.0-SNAPSHOT bundle DAISY Pipeline 2 :: Common Utilities diff --git a/common-utils/src/main/java/org/daisy/common/messaging/Message.java b/common-utils/src/main/java/org/daisy/common/messaging/Message.java index d1a8533ba..b6fbc02dd 100644 --- a/common-utils/src/main/java/org/daisy/common/messaging/Message.java +++ b/common-utils/src/main/java/org/daisy/common/messaging/Message.java @@ -1,6 +1,8 @@ package org.daisy.common.messaging; import java.util.Date; +import java.util.HashMap; +import java.util.Map; public class Message { /** @@ -86,7 +88,6 @@ public static class MessageBuilder { int line; int column; Date timeStamp; - int sequence; String jobId; String file; @@ -127,12 +128,6 @@ public MessageBuilder withTimeStamp(Date timeStamp) { } - public MessageBuilder withSequence(int sequence) { - this.sequence = sequence; - return this; - } - - public MessageBuilder withJobId(String jobId) { this.jobId = jobId; return this; @@ -145,11 +140,22 @@ public MessageBuilder withFile(String file) { } public Message build() { + Integer sequence; { + if (jobId == null) + sequence = 0; + else { + sequence = messageCounts.get(jobId); + if (sequence == null) + sequence = 0; + messageCounts.put(jobId, sequence + 1); + } + } return new Message(throwable, text, level, line, column, timeStamp, sequence, jobId, file); } } + private final static Map messageCounts = new HashMap(); } diff --git a/framework-core/pom.xml b/framework-core/pom.xml index 218cef7d8..82f59de3b 100644 --- a/framework-core/pom.xml +++ b/framework-core/pom.xml @@ -8,7 +8,7 @@ ../parent framework-core - 3.0.1-SNAPSHOT + 3.1.0-SNAPSHOT bundle DAISY Pipeline 2 :: Framework Core diff --git a/framework-core/src/main/java/org/daisy/pipeline/job/Job.java b/framework-core/src/main/java/org/daisy/pipeline/job/Job.java index 0cf238653..6c8ce107e 100644 --- a/framework-core/src/main/java/org/daisy/pipeline/job/Job.java +++ b/framework-core/src/main/java/org/daisy/pipeline/job/Job.java @@ -193,7 +193,6 @@ private final void broadcastError(String text){ .withJobId(this.getId().toString()) .withLevel(Level.ERROR) .withText(text) - .withSequence(1) .build(); if (this.eventBus!=null) this.eventBus.post(msg); diff --git a/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageAccessorTest.java b/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageAccessorTest.java index e3c3fd41c..91437dcff 100644 --- a/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageAccessorTest.java +++ b/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageAccessorTest.java @@ -32,14 +32,14 @@ public class VolatileMessageAccessorTest { public void setUp() { String id = JobIdFactory.newId().toString(); m1 = new Message.MessageBuilder().withText("message1") - .withLevel(Level.INFO).withSequence(0).withJobId(id).build(); + .withLevel(Level.INFO).withJobId(id).build(); m2 = new Message.MessageBuilder().withText("message2") - .withLevel(Level.ERROR).withSequence(1).withJobId(id) + .withLevel(Level.ERROR).withJobId(id) .build(); m3 = new Message.MessageBuilder().withText("message3") - .withLevel(Level.WARNING).withSequence(2).withJobId(id) + .withLevel(Level.WARNING).withJobId(id) .build(); diff --git a/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageStorageTest.java b/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageStorageTest.java index a783c76d7..b0aa49a41 100644 --- a/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageStorageTest.java +++ b/framework-volatile/src/test/java/org/daisy/pipeline/nonpersistent/impl/messaging/VolatileMessageStorageTest.java @@ -4,6 +4,7 @@ import org.daisy.common.messaging.Message; import org.daisy.common.messaging.Message.Level; +import org.daisy.pipeline.job.JobIdFactory; import org.daisy.pipeline.nonpersistent.impl.messaging.VolatileMessageStorage; import org.junit.After; import org.junit.Assert; @@ -12,6 +13,8 @@ public class VolatileMessageStorageTest { + String jobId; + Message m1; Message m2; @@ -22,15 +25,16 @@ public class VolatileMessageStorageTest { @Before public void setUp() { + jobId = JobIdFactory.newId().toString(); m1 = new Message.MessageBuilder().withText("message1") - .withLevel(Level.INFO).withSequence(0).withJobId("id1").build(); + .withLevel(Level.INFO).withJobId(jobId).build(); m2 = new Message.MessageBuilder().withText("message2") - .withLevel(Level.ERROR).withSequence(1).withJobId("id1") + .withLevel(Level.ERROR).withJobId(jobId) .build(); m3 = new Message.MessageBuilder().withText("message3") - .withLevel(Level.DEBUG).withSequence(2).withJobId("id1") + .withLevel(Level.DEBUG).withJobId(jobId) .build(); } @@ -43,7 +47,7 @@ public void tearDown(){ public void add() { storage.add(m1); storage.add(m2); - Assert.assertEquals(storage.get("id1").size(), 2); + Assert.assertEquals(storage.get(jobId).size(), 2); } @Test @@ -61,19 +65,19 @@ public void run() { }; sleeper.start(); sleeper.join(); - Assert.assertEquals(storage.get("id1").size(), 0); + Assert.assertEquals(storage.get(jobId).size(), 0); } @Test public void addDebug() { storage.add(m3); - Assert.assertEquals(0,storage.get("id1").size()); + Assert.assertEquals(0,storage.get(jobId).size()); } @Test public void get() { storage.add(m1); storage.add(m2); - List list= storage.get("id1"); + List list= storage.get(jobId); Assert.assertEquals(0,list.get(0).getSequence()); Assert.assertEquals(1,list.get(1).getSequence()); } @@ -88,8 +92,8 @@ public void getEmpty() { public void remove() { storage.add(m1); storage.add(m2); - storage.remove("id1"); - Assert.assertEquals(0,storage.get("id1").size()); + storage.remove(jobId); + Assert.assertEquals(0,storage.get(jobId).size()); } } diff --git a/logging-appender/pom.xml b/logging-appender/pom.xml index 4960ff27e..3a3ff458f 100644 --- a/logging-appender/pom.xml +++ b/logging-appender/pom.xml @@ -17,6 +17,19 @@ DAISY Pipeline 2 :: Logging Appender + + org.daisy.pipeline + common-utils + + + org.daisy.pipeline + framework-core + + + org.osgi + org.osgi.core + provided + ch.qos.logback logback-classic diff --git a/logging-appender/src/main/java/org/daisy/pipeline/logging/EventBusAppender.java b/logging-appender/src/main/java/org/daisy/pipeline/logging/EventBusAppender.java new file mode 100644 index 000000000..a9d7ba7e0 --- /dev/null +++ b/logging-appender/src/main/java/org/daisy/pipeline/logging/EventBusAppender.java @@ -0,0 +1,99 @@ +package org.daisy.pipeline.logging; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.sift.MDCBasedDiscriminator; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +import org.daisy.common.messaging.Message; +import org.daisy.common.messaging.MessageBuliderFactory; +import org.daisy.pipeline.event.EventBusProvider; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; + +/** + * Configure like this: + * + * <appender name="EVENTBUS" class="org.daisy.pipeline.logging.EventBusAppender"> + * <filter class="org.daisy.pipeline.logging.ThresholdFilter"> + * <rootLevel>INFO</rootLevel> + * <loggerLevels> + * cz.vutbr.web=WARN + * org.daisy.common.xproc.calabash.steps.Message=WARN + * com.xmlcalabash.runtime.XAtomicStep=WARN + * </loggerLevels> + * </filter> + * </appender> + */ +public class EventBusAppender extends AppenderBase { + + private EventBusProvider eventBusProvider; + private BundleContext bundleContext; + private MessageBuliderFactory messageBuilderFactory; + private List eventBuffer; + private MDCBasedDiscriminator discriminator; + + @Override + public void start() { + bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + messageBuilderFactory = new MessageBuliderFactory(); + eventBuffer = new ArrayList(); + discriminator = new MDCBasedDiscriminator(); + discriminator.setKey("jobid"); + discriminator.setDefaultValue("default"); + super.start(); + } + + protected void append(ILoggingEvent event) { + if (!isStarted()) + return; + String jobId = discriminator.getDiscriminatingValue(event); + if (!"default".equals(jobId)) { + if (eventBusProvider == null) { + try { + eventBusProvider = bundleContext.getService( + bundleContext.getServiceReferences(EventBusProvider.class, null).iterator().next()); + for (ILoggingEvent e : eventBuffer) + append(eventBusProvider, discriminator.getDiscriminatingValue(e), e); + eventBuffer.clear(); } + catch (Exception e) { + eventBuffer.add(event); + return; }} + append(eventBusProvider, jobId, event); } + } + + private void append(EventBusProvider eventBus, String jobId, ILoggingEvent event) { + Level level = event.getLevel(); + Message m = messageBuilderFactory.newMessageBuilder() + .withTimeStamp(new Date()) + .withJobId(jobId) + .withLevel(messageLevelFromLogbackLevel(level)) + .withText(event.getFormattedMessage()) + .build(); + eventBus.get().post(m); + } + + private static Message.Level messageLevelFromLogbackLevel(Level level) { + switch(level.toInt()) { + case Level.TRACE_INT: + return Message.Level.TRACE; + case Level.DEBUG_INT: + return Message.Level.DEBUG; + case Level.INFO_INT: + return Message.Level.INFO; + case Level.WARN_INT: + return Message.Level.WARNING; + case Level.ERROR_INT: + return Message.Level.ERROR; + case Level.ALL_INT: + case Level.OFF_INT: + default: + return null; } + } +} diff --git a/logging-appender/src/main/java/org/daisy/pipeline/logging/ThresholdFilter.java b/logging-appender/src/main/java/org/daisy/pipeline/logging/ThresholdFilter.java new file mode 100644 index 000000000..ebab3c6cb --- /dev/null +++ b/logging-appender/src/main/java/org/daisy/pipeline/logging/ThresholdFilter.java @@ -0,0 +1,64 @@ +package org.daisy.pipeline.logging; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +import ch.qos.logback.classic.Level; +import static ch.qos.logback.classic.Level.toLevel; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.Filter; +import ch.qos.logback.core.spi.FilterReply; + +public class ThresholdFilter extends Filter { + + private Level rootLevel; + private Map loggerLevels; + private Map cache; + + public void setRootLevel(Level rootLevel) { + this.rootLevel = rootLevel; + } + + public void setLoggerLevels(String loggerLevels) { + this.loggerLevels = new TreeMap(); + try { + Properties p = new Properties(); + p.load(new StringReader(loggerLevels)); + for (String logger : p.stringPropertyNames()) + this.loggerLevels.put(logger, toLevel(p.getProperty(logger))); } + catch (IOException e) { + throw new RuntimeException(e); } + } + + @Override + public void start() { + if (rootLevel == null) + rootLevel = Level.ALL; + cache = new TreeMap(); + super.start(); + } + + @Override + public FilterReply decide(ILoggingEvent event) { + if (!isStarted()) + return FilterReply.NEUTRAL; + String logger = event.getLoggerName(); + Level threshold = cache.get(logger); + if (threshold == null) { + threshold = rootLevel; { + if (loggerLevels != null) + for (String l : loggerLevels.keySet()) + if (logger.startsWith(l)) { + threshold = loggerLevels.get(l); + break; }} + cache.put(logger, threshold); } + Level level = event.getLevel(); + if (level.isGreaterOrEqual(threshold)) + return FilterReply.NEUTRAL; + else + return FilterReply.DENY; + } +} diff --git a/persistence-derby/pom.xml b/persistence-derby/pom.xml index 0afa9858d..05dbe1bc6 100644 --- a/persistence-derby/pom.xml +++ b/persistence-derby/pom.xml @@ -6,7 +6,7 @@ org.daisy.pipeline framework-parent - 1.8.1-SNAPSHOT + 1.10.1-SNAPSHOT ../parent diff --git a/pom.xml b/pom.xml index cc8bc96c7..80c7d835d 100644 --- a/pom.xml +++ b/pom.xml @@ -36,15 +36,15 @@ logging-activator logging-appender - + persistence-derby - + push-notifier updater webservice webservice-utils - + xproc-api diff --git a/push-notifier/pom.xml b/push-notifier/pom.xml index bb619b3e5..719a46aca 100644 --- a/push-notifier/pom.xml +++ b/push-notifier/pom.xml @@ -6,7 +6,7 @@ org.daisy.pipeline framework-parent - 1.8.1-SNAPSHOT + 1.10.1-SNAPSHOT ../parent diff --git a/webservice-utils/src/main/java/org/daisy/pipeline/webserviceutils/xml/JobXmlWriter.java b/webservice-utils/src/main/java/org/daisy/pipeline/webserviceutils/xml/JobXmlWriter.java index 3c7aa6860..948a8a8e5 100644 --- a/webservice-utils/src/main/java/org/daisy/pipeline/webserviceutils/xml/JobXmlWriter.java +++ b/webservice-utils/src/main/java/org/daisy/pipeline/webserviceutils/xml/JobXmlWriter.java @@ -159,6 +159,7 @@ private void addElementData(Job job, Element element) { Element messageElm = doc.createElementNS(XmlUtils.NS_PIPELINE_DATA, "message"); messageElm.setAttribute("level", message.getLevel().toString()); messageElm.setAttribute("sequence", Integer.toString(message.getSequence())); + messageElm.setAttribute("timeStamp", Long.toString(message.getTimeStamp().getTime())); messageElm.setTextContent(message.getText()); messagesElm.appendChild(messageElm); } diff --git a/webservice-utils/src/main/resources/org/daisy/pipeline/webservice-utils/resources/jobElement.rnc b/webservice-utils/src/main/resources/org/daisy/pipeline/webservice-utils/resources/jobElement.rnc index c8190d559..4db22225c 100644 --- a/webservice-utils/src/main/resources/org/daisy/pipeline/webservice-utils/resources/jobElement.rnc +++ b/webservice-utils/src/main/resources/org/daisy/pipeline/webservice-utils/resources/jobElement.rnc @@ -22,6 +22,7 @@ element job { element message { attribute level { message.level } & attribute sequence { text } + & attribute timeStamp { xsd:long } & text }* }? diff --git a/xproc-api/pom.xml b/xproc-api/pom.xml index 813536724..fc546c931 100644 --- a/xproc-api/pom.xml +++ b/xproc-api/pom.xml @@ -6,7 +6,7 @@ org.daisy.pipeline framework-parent - 1.8.1-SNAPSHOT + 1.10.1-SNAPSHOT ../parent