Merge pull request #295 from jbonofre/KARAF-7260
[KARAF-7260] Add included.categories property
diff --git a/collector/log/src/main/cfg/org.apache.karaf.decanter.collector.log.cfg b/collector/log/src/main/cfg/org.apache.karaf.decanter.collector.log.cfg
index 527f805..7e3ea65 100644
--- a/collector/log/src/main/cfg/org.apache.karaf.decanter.collector.log.cfg
+++ b/collector/log/src/main/cfg/org.apache.karaf.decanter.collector.log.cfg
@@ -21,9 +21,12 @@
# Decanter Log collector configuration
#
-# logger categories that the log collector should ignore
-# By default, we ignored all messages coming from Decanter Appenders
-ignored.categories=org.apache.karaf.decanter.appender.*
+# logger categories that the log collector should exclude
+# By default, we exclude all messages coming from Decanter appenders
+excluded.categories=org.apache.karaf.decanter.appender.*
+
+# include only some logger categories, others categories will be excluded by default
+#included.categories=my.logger,another.one
# custom fields
#fields.add.eventType=LOGEvent
diff --git a/collector/log/src/main/java/org/apache/karaf/decanter/collector/log/LogCollector.java b/collector/log/src/main/java/org/apache/karaf/decanter/collector/log/LogCollector.java
index 5ca4ff2..054bff0 100644
--- a/collector/log/src/main/java/org/apache/karaf/decanter/collector/log/LogCollector.java
+++ b/collector/log/src/main/java/org/apache/karaf/decanter/collector/log/LogCollector.java
@@ -56,7 +56,8 @@
private final static Pattern PATTERN = Pattern.compile("[^A-Za-z0-9]");
private Dictionary<String, Object> properties;
- protected String[] ignoredCategories;
+ protected String[] excludedCategories;
+ protected String[] includedCategories;
protected String[] locationDisabledCategories;
@SuppressWarnings("unchecked")
@@ -64,7 +65,13 @@
public void activate(ComponentContext context) {
this.properties = context.getProperties();
if (this.properties.get("ignored.categories") != null) {
- ignoredCategories = ((String)this.properties.get("ignored.categories")).split(",");
+ excludedCategories = ((String)this.properties.get("ignored.categories")).split(",");
+ }
+ if (this.properties.get("excluded.categories") != null) {
+ excludedCategories = ((String)this.properties.get("excluded.categories")).split(",");
+ }
+ if (this.properties.get("included.categories") != null) {
+ includedCategories = ((String)this.properties.get("included.categories")).split(",");
}
if (this.properties.get("location.disabled") != null) {
locationDisabledCategories = ((String) this.properties.get("location.disabled")).split(",");
@@ -86,8 +93,12 @@
}
}
- private void appendInternal(PaxLoggingEvent event) throws Exception {
- if (isIgnored(event.getLoggerName(), ignoredCategories)) {
+ protected void appendInternal(PaxLoggingEvent event) throws Exception {
+ if (includedCategories != null && !filterCategory(event.getLoggerName(), includedCategories)) {
+ LOGGER.debug("{} logger is not in the included list", event.getLoggerName());
+ return;
+ }
+ if (filterCategory(event.getLoggerName(), excludedCategories)) {
LOGGER.debug("{} logger is ignored by the log collector", event.getLoggerName());
return;
}
@@ -100,10 +111,10 @@
data.put("loggerName", event.getLoggerName());
data.put("threadName", event.getThreadName());
data.put("message", event.getMessage());
- data.put("level", event.getLevel().toString());
+ data.put("level", (event.getLevel() != null) ? event.getLevel().toString() : "default");
data.put("renderedMessage", event.getRenderedMessage());
data.put("MDC", event.getProperties());
- if (locationDisabledCategories == null || !isIgnored(event.getLoggerName(), locationDisabledCategories)) {
+ if (locationDisabledCategories == null || !filterCategory(event.getLoggerName(), locationDisabledCategories)) {
putLocation(data, event.getLocationInformation());
}
String[] throwableAr = event.getThrowableStrRep();
@@ -135,10 +146,12 @@
}
private void putLocation(Map<String, Object> data, PaxLocationInfo loc) {
- data.put("loc.class", loc.getClassName());
- data.put("loc.file", loc.getFileName());
- data.put("loc.line", loc.getLineNumber());
- data.put("loc.method", loc.getMethodName());
+ if (loc != null) {
+ data.put("loc.class", loc.getClassName());
+ data.put("loc.file", loc.getFileName());
+ data.put("loc.line", loc.getLineNumber());
+ data.put("loc.method", loc.getMethodName());
+ }
}
private Object join(String[] throwableAr) {
@@ -149,12 +162,12 @@
return builder.toString();
}
- protected boolean isIgnored(String loggerName, String[] ignoreList) {
+ protected boolean filterCategory(String loggerName, String[] filterCategories) {
if (loggerName == null) {
return true;
}
- if (ignoreList != null) {
- for (String cat : ignoreList) {
+ if (filterCategories != null) {
+ for (String cat : filterCategories) {
if (loggerName.matches(cat)) {
return true;
}
diff --git a/collector/log/src/test/java/org/apache/karaf/decanter/collector/log/LogCollectorTest.java b/collector/log/src/test/java/org/apache/karaf/decanter/collector/log/LogCollectorTest.java
index ca109b9..4e3a5ad 100644
--- a/collector/log/src/test/java/org/apache/karaf/decanter/collector/log/LogCollectorTest.java
+++ b/collector/log/src/test/java/org/apache/karaf/decanter/collector/log/LogCollectorTest.java
@@ -16,7 +16,13 @@
*/
package org.apache.karaf.decanter.collector.log;
+import org.apache.log4j.Category;
+import org.apache.log4j.spi.LoggingEvent;
import org.junit.Test;
+import org.ops4j.pax.logging.service.internal.spi.PaxLoggingEventImpl;
+import org.ops4j.pax.logging.spi.PaxLevel;
+import org.ops4j.pax.logging.spi.PaxLocationInfo;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@@ -25,10 +31,7 @@
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
+import java.util.*;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
@@ -38,10 +41,10 @@
@Test
public void testCleanLoggerName() {
- LogCollector appender = new LogCollector();
+ LogCollector collector = new LogCollector();
String loggerName = "wrong$Pattern%For&event!Name";
- String cleanedLoggerName = appender.cleanLoggerName(loggerName);
+ String cleanedLoggerName = collector.cleanLoggerName(loggerName);
assertThat(cleanedLoggerName, not(containsString("%")));
assertThat(cleanedLoggerName, not(containsString("$")));
@@ -52,56 +55,175 @@
@Test
public void testIgnoredLoggerCategories() {
- LogCollector appender = new LogCollector();
+ LogCollector collector = new LogCollector();
ComponentContext componentContext = new ComponentContextMock();
componentContext.getProperties().put("ignored.categories", "org.apache.karaf.decanter.collector.log.*,test,other");
- appender.activate(componentContext);
+ collector.activate(componentContext);
- assertEquals("org.apache.karaf.decanter.collector.log.*", appender.ignoredCategories[0]);
- assertEquals("test", appender.ignoredCategories[1]);
- assertEquals("other", appender.ignoredCategories[2]);
+ assertEquals("org.apache.karaf.decanter.collector.log.*", collector.excludedCategories[0]);
+ assertEquals("test", collector.excludedCategories[1]);
+ assertEquals("other", collector.excludedCategories[2]);
- assertFalse(appender.isIgnored("org.apache.karaf.decanter.other", appender.ignoredCategories));
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.collector.log", appender.ignoredCategories));
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.collector.log.LogEvent", appender.ignoredCategories));
+ assertFalse(collector.filterCategory("org.apache.karaf.decanter.other", collector.excludedCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log", collector.excludedCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log.LogEvent", collector.excludedCategories));
+ }
+
+ @Test
+ public void testExcludedLoggerCategories() {
+ LogCollector collector = new LogCollector();
+
+ ComponentContext componentContext = new ComponentContextMock();
+ componentContext.getProperties().put("excluded.categories", "org.apache.karaf.decanter.collector.log.*,test,other");
+
+ collector.activate(componentContext);
+
+ assertEquals("org.apache.karaf.decanter.collector.log.*", collector.excludedCategories[0]);
+ assertEquals("test", collector.excludedCategories[1]);
+ assertEquals("other", collector.excludedCategories[2]);
+
+ assertFalse(collector.filterCategory("org.apache.karaf.decanter.other", collector.excludedCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log", collector.excludedCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log.LogEvent", collector.excludedCategories));
+ }
+
+ @Test
+ public void testIncludedLoggerCategories() {
+ LogCollector collector = new LogCollector();
+
+ ComponentContext componentContext = new ComponentContextMock();
+ componentContext.getProperties().put("included.categories", "foo,bar");
+
+ collector.activate(componentContext);
+
+ assertEquals("foo", collector.includedCategories[0]);
+ assertEquals("bar", collector.includedCategories[1]);
+
+ assertTrue(collector.filterCategory("foo", collector.includedCategories));
+ assertTrue(collector.filterCategory("bar", collector.includedCategories));
+ assertFalse(collector.filterCategory("other", collector.includedCategories));
+ }
+
+ @Test
+ public void testCollectorProcess() throws Exception {
+ DispatcherMock dispatcher = new DispatcherMock();
+
+ LogCollector collector = new LogCollector();
+ collector.dispatcher = dispatcher;
+ collector.activate(new ComponentContextMock());
+
+ collector.appendInternal(new PaxLoggingEventMock("foo", "This is a test"));
+ collector.appendInternal(new PaxLoggingEventMock("bar", "Another test"));
+
+ assertEquals(2, dispatcher.postEvents.size());
+
+ assertEquals("foo", dispatcher.postEvents.get(0).getProperty("loggerName"));
+ assertEquals("This is a test", dispatcher.postEvents.get(0).getProperty("message"));
+
+ assertEquals("bar", dispatcher.postEvents.get(1).getProperty("loggerName"));
+ assertEquals("Another test", dispatcher.postEvents.get(1).getProperty("message"));
+ }
+
+ @Test
+ public void testExcludedCategoriesCollectorProcess() throws Exception {
+ DispatcherMock dispatcher = new DispatcherMock();
+
+ ComponentContextMock componentContext = new ComponentContextMock();
+ componentContext.getProperties().put("excluded.categories", "my.excluded.logger");
+
+ LogCollector collector = new LogCollector();
+ collector.dispatcher = dispatcher;
+ collector.activate(componentContext);
+
+ collector.appendInternal(new PaxLoggingEventMock("foo", "This is a test"));
+ collector.appendInternal(new PaxLoggingEventMock("my.excluded.logger", "excluded"));
+
+ assertEquals(1, dispatcher.postEvents.size());
+
+ assertEquals("foo", dispatcher.postEvents.get(0).getProperty("loggerName"));
+ assertEquals("This is a test", dispatcher.postEvents.get(0).getProperty("message"));
+ }
+
+ @Test
+ public void testIncludedCategoriesCollectorProcess() throws Exception {
+ DispatcherMock dispatcherMock = new DispatcherMock();
+
+ ComponentContextMock componentContext = new ComponentContextMock();
+ componentContext.getProperties().put("included.categories", "my.logger");
+
+ LogCollector collector = new LogCollector();
+ collector.dispatcher = dispatcherMock;
+ collector.activate(componentContext);
+
+ collector.appendInternal(new PaxLoggingEventMock("my.logger", "This is a test"));
+ collector.appendInternal(new PaxLoggingEventMock("other.logger", "another"));
+ collector.appendInternal(new PaxLoggingEventMock("bar", "bar"));
+
+ assertEquals(1, dispatcherMock.postEvents.size());
+
+ assertEquals("my.logger", dispatcherMock.postEvents.get(0).getProperty("loggerName"));
+ assertEquals("This is a test", dispatcherMock.postEvents.get(0).getProperty("message"));
+ }
+
+ @Test
+ public void testExcludedIncludedCategoriesCollectorProcess() throws Exception {
+ DispatcherMock dispatcherMock = new DispatcherMock();
+
+ ComponentContextMock componentContextMock = new ComponentContextMock();
+ componentContextMock.getProperties().put("included.categories", "my.included.logger,my.includedexcluded.logger");
+ componentContextMock.getProperties().put("excluded.categories", "my.includedexcluded.logger");
+
+ LogCollector collector = new LogCollector();
+ collector.dispatcher = dispatcherMock;
+ collector.activate(componentContextMock);
+
+ collector.appendInternal(new PaxLoggingEventMock("foo", "This is foo"));
+ collector.appendInternal(new PaxLoggingEventMock("bar", "This is bar"));
+ collector.appendInternal(new PaxLoggingEventMock("my.included.logger", "This should be included"));
+ collector.appendInternal(new PaxLoggingEventMock("my.includedexcluded.logger", "This should be excluded"));
+
+ assertEquals(1, dispatcherMock.postEvents.size());
+
+ assertEquals("my.included.logger", dispatcherMock.postEvents.get(0).getProperty("loggerName"));
+ assertEquals("This should be included", dispatcherMock.postEvents.get(0).getProperty("message"));
}
@Test
public void testDisabledLocationCategories() {
- LogCollector appender = new LogCollector();
+ LogCollector collector = new LogCollector();
ComponentContext componentContext = new ComponentContextMock();
componentContext.getProperties().put("location.disabled", "org.apache.karaf.decanter.collector.log.*,test,other");
- appender.activate(componentContext);
+ collector.activate(componentContext);
- assertEquals("org.apache.karaf.decanter.collector.log.*", appender.locationDisabledCategories[0]);
- assertEquals("test", appender.locationDisabledCategories[1]);
- assertEquals("other", appender.locationDisabledCategories[2]);
+ assertEquals("org.apache.karaf.decanter.collector.log.*", collector.locationDisabledCategories[0]);
+ assertEquals("test", collector.locationDisabledCategories[1]);
+ assertEquals("other", collector.locationDisabledCategories[2]);
- assertFalse(appender.isIgnored("org.apache.karaf.decanter.other", appender.locationDisabledCategories));
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.collector.log", appender.locationDisabledCategories));
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.collector.log.LogEvent", appender.locationDisabledCategories));
+ assertFalse(collector.filterCategory("org.apache.karaf.decanter.other", collector.locationDisabledCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log", collector.locationDisabledCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log.LogEvent", collector.locationDisabledCategories));
}
@Test
public void testDisabledLocationCategoriesAllWildcard() {
- LogCollector appender = new LogCollector();
+ LogCollector collector = new LogCollector();
ComponentContext componentContext = new ComponentContextMock();
componentContext.getProperties().put("location.disabled", ".*,test,other");
- appender.activate(componentContext);
+ collector.activate(componentContext);
- assertEquals(".*", appender.locationDisabledCategories[0]);
- assertEquals("test", appender.locationDisabledCategories[1]);
- assertEquals("other", appender.locationDisabledCategories[2]);
+ assertEquals(".*", collector.locationDisabledCategories[0]);
+ assertEquals("test", collector.locationDisabledCategories[1]);
+ assertEquals("other", collector.locationDisabledCategories[2]);
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.other", appender.locationDisabledCategories));
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.collector.log", appender.locationDisabledCategories));
- assertTrue(appender.isIgnored("org.apache.karaf.decanter.collector.log.LogEvent", appender.locationDisabledCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.other", collector.locationDisabledCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log", collector.locationDisabledCategories));
+ assertTrue(collector.filterCategory("org.apache.karaf.decanter.collector.log.LogEvent", collector.locationDisabledCategories));
}
private class ComponentContextMock implements ComponentContext {
@@ -187,4 +309,70 @@
}
}
+ private class PaxLoggingEventMock implements PaxLoggingEvent {
+
+ public String loggerName;
+ public String message;
+
+ public PaxLoggingEventMock(String loggerName, String message) {
+ this.loggerName = loggerName;
+ this.message = message;
+ }
+
+ @Override
+ public PaxLocationInfo getLocationInformation() {
+ return null;
+ }
+
+ @Override
+ public PaxLevel getLevel() {
+ return null;
+ }
+
+ @Override
+ public String getLoggerName() {
+ return this.loggerName;
+ }
+
+ @Override
+ public String getFQNOfLoggerClass() {
+ return null;
+ }
+
+ @Override
+ public String getMessage() {
+ return this.message;
+ }
+
+ @Override
+ public String getRenderedMessage() {
+ return null;
+ }
+
+ @Override
+ public String getThreadName() {
+ return null;
+ }
+
+ @Override
+ public String[] getThrowableStrRep() {
+ return new String[0];
+ }
+
+ @Override
+ public boolean locationInformationExists() {
+ return false;
+ }
+
+ @Override
+ public long getTimeStamp() {
+ return 0;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return null;
+ }
+ }
+
}
diff --git a/collector/utils/src/main/java/org/apache/karaf/decanter/collector/utils/PropertiesPreparator.java b/collector/utils/src/main/java/org/apache/karaf/decanter/collector/utils/PropertiesPreparator.java
index 6c24a3f..0724839 100644
--- a/collector/utils/src/main/java/org/apache/karaf/decanter/collector/utils/PropertiesPreparator.java
+++ b/collector/utils/src/main/java/org/apache/karaf/decanter/collector/utils/PropertiesPreparator.java
@@ -61,31 +61,33 @@
data.put("hostName", hostName);
// custom fields
- Enumeration<String> keys = properties.keys();
- while (keys.hasMoreElements()) {
- String key = keys.nextElement();
- if (key.startsWith(FIELDS_ADD)) {
- if ("UUID".equals(properties.get(key).toString().trim())) {
- String uuid = UUID.randomUUID().toString();
- data.put(key.substring(FIELDS_ADD.length()), uuid);
- } else if ("TIMESTAMP".equals(properties.get(key).toString().trim())) {
- Date date = new Date();
- data.put(key.substring(FIELDS_ADD.length()), tsFormat.format(date));
+ if (properties != null) {
+ Enumeration<String> keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ if (key.startsWith(FIELDS_ADD)) {
+ if ("UUID".equals(properties.get(key).toString().trim())) {
+ String uuid = UUID.randomUUID().toString();
+ data.put(key.substring(FIELDS_ADD.length()), uuid);
+ } else if ("TIMESTAMP".equals(properties.get(key).toString().trim())) {
+ Date date = new Date();
+ data.put(key.substring(FIELDS_ADD.length()), tsFormat.format(date));
+ } else {
+ data.put(key.substring(FIELDS_ADD.length()), properties.get(key));
+ }
+ } else if (key.startsWith(FIELDS_RENAME)) {
+ if (data.containsKey(key.substring(FIELDS_RENAME.length()))) {
+ Object value = data.get(key.substring(FIELDS_RENAME.length()));
+ data.remove(key.substring(FIELDS_RENAME.length()));
+ data.put(properties.get(key).toString().trim(), value);
+ }
+ } else if (key.startsWith(FIELDS_REMOVE)) {
+ if (data.containsKey(key.substring(FIELDS_REMOVE.length()))) {
+ data.remove(key.substring(FIELDS_REMOVE.length()));
+ }
} else {
- data.put(key.substring(FIELDS_ADD.length()), properties.get(key));
+ data.put(key, properties.get(key));
}
- } else if (key.startsWith(FIELDS_RENAME)) {
- if (data.containsKey(key.substring(FIELDS_RENAME.length()))) {
- Object value = data.get(key.substring(FIELDS_RENAME.length()));
- data.remove(key.substring(FIELDS_RENAME.length()));
- data.put(properties.get(key).toString().trim(), value);
- }
- } else if (key.startsWith(FIELDS_REMOVE)) {
- if (data.containsKey(key.substring(FIELDS_REMOVE.length()))) {
- data.remove(key.substring(FIELDS_REMOVE.length()));
- }
- } else {
- data.put(key, properties.get(key));
}
}
}
diff --git a/manual/src/main/asciidoc/user-guide/collectors.adoc b/manual/src/main/asciidoc/user-guide/collectors.adoc
index 0a986de..1c69523 100644
--- a/manual/src/main/asciidoc/user-guide/collectors.adoc
+++ b/manual/src/main/asciidoc/user-guide/collectors.adoc
@@ -54,6 +54,24 @@
=====================================================================
+Optionally, you can select the log categories you want to exclude or include in the logger.
+
+In the `etc/org.apache.karaf.collector.log.cfg` configuration file, you can set `excluded.categories` (comma separated list of loggers):
+
+----
+excluded.categories=ignored.logger
+----
+
+With this property, the log collector will ignore any log events/messages coming from `ignored.logger` logger.
+
+On the other hand, you can include only some logger with the `included.categories` (comma separated list of loggers):
+
+----
+included.categories=my.logger
+----
+
+With this property, the log collector will only consider log events/messages coming from `included.categories` logger, other loggers will be ignored.
+
==== CXF Logging feature integration
The link:http://cxf.apache.org/docs/message-logging.html[CXF message logging] nicely integrates with Decanter. Simply add the link:https://github.com/apache/cxf/blob/master/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java[org.apache.cxf.ext.logging.LoggingFeature] to your service.