You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ch...@apache.org on 2017/11/20 12:53:38 UTC
[sling-org-apache-sling-commons-log] 01/03: SLING-3049 - Make
Logback Stacktrace Packaging data support OSGi aware
This is an automated email from the ASF dual-hosted git repository.
chetanm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-log.git
commit 7365377ae3fd6beaaeaf63575fd52f61a82012bb
Author: Chetan Mehrotra <ch...@apache.org>
AuthorDate: Sat Oct 28 16:20:16 2017 +0530
SLING-3049 - Make Logback Stacktrace Packaging data support OSGi aware
---
pom.xml | 12 ++
.../commons/log/logback/internal/LogConfig.java | 13 ++
.../log/logback/internal/LogConfigManager.java | 4 +
.../log/logback/internal/LogbackManager.java | 33 +++-
.../log/logback/internal/SlingLogPanel.java | 4 +-
.../stacktrace/OSGiAwareExceptionHandling.java | 61 +++++++
.../internal/stacktrace/PackageInfoCollector.java | 60 +++++++
.../logback/integration/ITConfigAdminSupport.java | 2 +-
.../log/logback/integration/ITPackagingData.java | 191 +++++++++++++++++++++
.../logback/integration/PackagingDataTestUtil.java | 49 ++++++
.../integration/bundle/PackageDataActivator.java | 43 +++++
.../logback/integration/bundle/TestRunnable.java | 32 ++++
.../stacktrace/PackageInfoCollectorTest.java | 33 ++++
13 files changed, 531 insertions(+), 6 deletions(-)
diff --git a/pom.xml b/pom.xml
index d9da7b1..0b5fca3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -326,6 +326,18 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>bndlib</artifactId>
+ <version>2.4.0</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java
index 909c963..ea13ce9 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfig.java
@@ -27,6 +27,8 @@ import java.util.regex.Pattern;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.pattern.PostCompileProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,6 +57,8 @@ public class LogConfig {
private final boolean resetToDefault;
+ private PostCompileProcessor<ILoggingEvent> postProcessor;
+
LogConfig(LogWriterProvider logWriterProvider, final String pattern, Set<String> categories, Level logLevel,
String logWriterName, final boolean isAdditiv, String configPid, LoggerContext loggerContext, boolean resetToDefault) {
this.logWriterProvider = logWriterProvider;
@@ -145,6 +149,11 @@ public class LogConfig {
pl.setPattern(logBackPattern);
pl.setOutputPatternAsHeader(false);
pl.setContext(loggerContext);
+
+ if (postProcessor != null) {
+ pl.setPostCompileProcessor(postProcessor);
+ }
+
pl.start();
return pl;
}
@@ -155,6 +164,10 @@ public class LogConfig {
+ logLevel + ", logWriterName='" + logWriterName + '\'' + '}';
}
+ public void setPostProcessor(PostCompileProcessor<ILoggingEvent> postProcessor) {
+ this.postProcessor = postProcessor;
+ }
+
public interface LogWriterProvider {
LogWriter getLogWriter(String writerName);
}
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java
index 61c3295..a001a53 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/LogConfigManager.java
@@ -42,6 +42,7 @@ import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.util.ContextUtil;
import org.apache.sling.commons.log.logback.internal.config.ConfigAdminSupport;
import org.apache.sling.commons.log.logback.internal.config.ConfigurationException;
+import org.apache.sling.commons.log.logback.internal.stacktrace.OSGiAwareExceptionHandling;
import org.apache.sling.commons.log.logback.internal.util.LoggerSpecificEncoder;
import org.apache.sling.commons.log.logback.internal.util.Util;
import org.osgi.framework.BundleContext;
@@ -566,6 +567,9 @@ public class LogConfigManager implements LogbackResetListener, LogConfig.LogWrit
// create or modify existing configuration object
final LogConfig newConfig = new LogConfig(this, pattern, categories, logLevel, fileName, additiv,
pid, loggerContext, resetToDefault);
+ if (isPackagingDataEnabled()) {
+ newConfig.setPostProcessor(new OSGiAwareExceptionHandling(logbackManager.getPackageInfoCollector()));
+ }
LogConfig oldConfig = configByPid.get(pid);
if (oldConfig != null) {
configByCategory.keySet().removeAll(oldConfig.getCategories());
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java b/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
index a0e7346..9f357c3 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
@@ -34,6 +34,7 @@ import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.apache.sling.commons.log.logback.internal.AppenderTracker.AppenderInfo;
+import org.apache.sling.commons.log.logback.internal.stacktrace.PackageInfoCollector;
import org.apache.sling.commons.log.logback.internal.util.SlingRollingFileAppender;
import org.apache.sling.commons.log.logback.internal.util.SlingStatusPrinter;
import org.apache.sling.commons.log.logback.webconsole.LogPanel;
@@ -44,6 +45,7 @@ import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.hooks.weaving.WeavingHook;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;
@@ -85,6 +87,8 @@ public class LogbackManager extends LoggerContextAwareBase {
*/
private static final String SLING_LOG_ROOT = "sling.log.root";
+ public static final String PACKAGE_INFO_COLLECTOR_DESC = "Sling Log Package Info Collector";
+
private final BundleContext bundleContext;
private final String rootDir;
@@ -126,6 +130,8 @@ public class LogbackManager extends LoggerContextAwareBase {
private final boolean bridgeHandlerInstalled;
+ private final PackageInfoCollector packageInfoCollector = new PackageInfoCollector();
+
/**
* Time at which reset started. Used as the threshold for logging error
* messages from status printer
@@ -307,6 +313,10 @@ public class LogbackManager extends LoggerContextAwareBase {
ic.addSubstitutionProperty("sling.home", rootDir);
}
+ public PackageInfoCollector getPackageInfoCollector() {
+ return packageInfoCollector;
+ }
+
public URL getDefaultConfig() {
return getClass().getClassLoader().getResource("logback-empty.xml");
}
@@ -489,8 +499,9 @@ public class LogbackManager extends LoggerContextAwareBase {
addInfo("OsgiIntegrationListener : context reset detected. Adding LogManager to context map and firing"
+ " listeners");
- context.setPackagingDataEnabled(logConfigManager.isPackagingDataEnabled());
+ context.setPackagingDataEnabled(false);
context.setMaxCallerDataDepth(logConfigManager.getMaxCallerDataDepth());
+ registerPackageInfoCollector();
// Attach a console appender to handle logging untill we configure
// one. This would be removed in RootLoggerListener.reset
@@ -646,7 +657,7 @@ public class LogbackManager extends LoggerContextAwareBase {
public LoggerStateContext determineLoggerState() {
final List<Logger> loggers = getLoggerContext().getLoggerList();
- final LoggerStateContext ctx = new LoggerStateContext(loggers);
+ final LoggerStateContext ctx = new LoggerStateContext(loggers, packageInfoCollector);
//Distinguish between Logger configured via
//1. OSGi Config - The ones configured via ConfigAdmin
@@ -708,8 +719,11 @@ public class LogbackManager extends LoggerContextAwareBase {
final Map<ServiceReference,TurboFilter> turboFilters;
- LoggerStateContext(List<Logger> allLoggers) {
+ final PackageInfoCollector packageInfoCollector;
+
+ LoggerStateContext(List<Logger> allLoggers, PackageInfoCollector packageInfoCollector) {
this.allLoggers = allLoggers;
+ this.packageInfoCollector = packageInfoCollector;
for (AppenderTracker.AppenderInfo ai : getAppenderTracker().getAppenderInfos()) {
dynamicAppenders.put(ai.appender, ai);
}
@@ -796,4 +810,17 @@ public class LogbackManager extends LoggerContextAwareBase {
}, props));
}
+ private void registerPackageInfoCollector() {
+ //Weaving hook once registered would not be removed upon config changed
+ if (logConfigManager.isPackagingDataEnabled()) {
+ Properties props = new Properties();
+ props.put(Constants.SERVICE_VENDOR, "Apache Software Foundation");
+ props.put(Constants.SERVICE_DESCRIPTION, PACKAGE_INFO_COLLECTOR_DESC);
+
+ registrations.add(bundleContext.registerService(WeavingHook.class.getName(),
+ packageInfoCollector, props));
+ }
+ }
+
+
}
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java b/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
index 0d6975d..84a2728 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
@@ -176,8 +176,8 @@ public class SlingLogPanel implements LogPanel {
private void appendLoggerStatus(PrintWriter pw, LoggerStateContext ctx) {
pw.printf(
- "<p class='statline'>Log Service Stats: %d categories, %d appender, %d Dynamic appenders</p>%n",
- ctx.getNumberOfLoggers(), ctx.getNumOfAppenders(), ctx.getNumOfDynamicAppenders());
+ "<p class='statline'>Log Service Stats: %d categories, %d appender, %d Dynamic appenders, %d Packages</p>%n",
+ ctx.getNumberOfLoggers(), ctx.getNumOfAppenders(), ctx.getNumOfDynamicAppenders(), ctx.packageInfoCollector.size());
}
private void appendOsgiConfiguredLoggerData(final PrintWriter pw, final String consoleAppRoot) {
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/stacktrace/OSGiAwareExceptionHandling.java b/src/main/java/org/apache/sling/commons/log/logback/internal/stacktrace/OSGiAwareExceptionHandling.java
new file mode 100644
index 0000000..45c8aeb
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/stacktrace/OSGiAwareExceptionHandling.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.log.logback.internal.stacktrace;
+
+import ch.qos.logback.classic.pattern.EnsureExceptionHandling;
+import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.classic.spi.StackTraceElementProxy;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.pattern.Converter;
+import ch.qos.logback.core.pattern.ConverterUtil;
+
+public class OSGiAwareExceptionHandling extends EnsureExceptionHandling {
+ private final PackageInfoCollector collector;
+
+ public OSGiAwareExceptionHandling(PackageInfoCollector collector) {
+ this.collector = collector;
+ }
+
+ @Override
+ public void process(Context context, Converter<ILoggingEvent> head) {
+ if (head == null) {
+ // this should never happen
+ throw new IllegalArgumentException("cannot process empty chain");
+ }
+ if (!chainHandlesThrowable(head)) {
+ Converter<ILoggingEvent> tail = ConverterUtil.findTail(head);
+ Converter<ILoggingEvent> exConverter = new OSGiAwareConverter();
+ tail.setNext(exConverter);
+ }
+ }
+
+ private class OSGiAwareConverter extends ExtendedThrowableProxyConverter {
+ @Override
+ protected void extraData(StringBuilder builder, StackTraceElementProxy step) {
+ if (step != null) {
+ String version = collector.getVersion(step.getStackTraceElement().getClassName());
+ if (version != null) {
+ builder.append(" [").append(version).append(']');
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/stacktrace/PackageInfoCollector.java b/src/main/java/org/apache/sling/commons/log/logback/internal/stacktrace/PackageInfoCollector.java
new file mode 100644
index 0000000..36cde17
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/stacktrace/PackageInfoCollector.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.log.logback.internal.stacktrace;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClass;
+
+public class PackageInfoCollector implements WeavingHook{
+ private final Map<String, String> pkgVersionMapping = new ConcurrentHashMap<>();
+
+ @Override
+ public void weave(WovenClass wovenClass) {
+ add(wovenClass.getBundleWiring().getBundle(), wovenClass.getClassName());
+ }
+
+ public int size() {
+ return pkgVersionMapping.size();
+ }
+
+ void add(Bundle bundle, String className) {
+ pkgVersionMapping.put(getPackageName(className), bundle.getVersion().toString());
+ }
+
+ String getVersion(String className) {
+ if (className == null) {
+ return null;
+ }
+ String packageName = getPackageName(className);
+ return pkgVersionMapping.get(packageName);
+ }
+
+ static String getPackageName(String className) {
+ int lastIndexOfDot = className.lastIndexOf('.');
+ String result = "";
+ if (lastIndexOfDot > 0){
+ result = className.substring(0, lastIndexOfDot);
+ }
+ return result;
+ }
+}
diff --git a/src/test/java/org/apache/sling/commons/log/logback/integration/ITConfigAdminSupport.java b/src/test/java/org/apache/sling/commons/log/logback/integration/ITConfigAdminSupport.java
index b4c1dc6..c039fec 100644
--- a/src/test/java/org/apache/sling/commons/log/logback/integration/ITConfigAdminSupport.java
+++ b/src/test/java/org/apache/sling/commons/log/logback/integration/ITConfigAdminSupport.java
@@ -172,7 +172,7 @@ public class ITConfigAdminSupport extends LogTestBase {
// Set log level to debug for Root logger
Configuration config = ca.getConfiguration(PID, null);
Dictionary<String, Object> p = new Hashtable<String, Object>();
- p.put(LOG_PACKAGING_DATA, Boolean.FALSE);
+ p.put(LOG_PACKAGING_DATA, Boolean.TRUE);
p.put(LOG_LEVEL, "INFO");
config.update(p);
diff --git a/src/test/java/org/apache/sling/commons/log/logback/integration/ITPackagingData.java b/src/test/java/org/apache/sling/commons/log/logback/integration/ITPackagingData.java
new file mode 100644
index 0000000..adc44ca
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/log/logback/integration/ITPackagingData.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.log.logback.integration;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import ch.qos.logback.classic.LoggerContext;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.sling.commons.log.logback.integration.bundle.PackageDataActivator;
+import org.apache.sling.commons.log.logback.internal.LogbackManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.sling.commons.log.logback.integration.ITConfigAdminSupport.PID;
+import static org.apache.sling.commons.log.logback.internal.LogConfigManager.FACTORY_PID_CONFIGS;
+import static org.apache.sling.commons.log.logback.internal.LogConfigManager.LOGBACK_FILE;
+import static org.apache.sling.commons.log.logback.internal.LogConfigManager.LOG_FILE;
+import static org.apache.sling.commons.log.logback.internal.LogConfigManager.LOG_LEVEL;
+import static org.apache.sling.commons.log.logback.internal.LogConfigManager.LOG_LOGGERS;
+import static org.apache.sling.commons.log.logback.internal.LogConfigManager.LOG_PACKAGING_DATA;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class ITPackagingData extends LogTestBase {
+
+ @Inject
+ private BundleContext bundleContext;
+
+ @Inject
+ private ConfigurationAdmin ca;
+
+ @Override
+ protected Option addExtraOptions() {
+ return composite(
+ configAdmin(),
+ mavenBundle("org.ops4j.pax.tinybundles", "tinybundles").versionAsInProject(),
+ mavenBundle("biz.aQute.bnd", "bndlib").versionAsInProject(),
+ mavenBundle("commons-io", "commons-io").versionAsInProject()
+ );
+ }
+
+ @Test
+ public void defaultWorking() throws Exception{
+ ServiceTracker<WeavingHook, WeavingHook> tracker = createWeavingHookTracker();
+ tracker.open();
+
+ assertNull(tracker.getService());
+ tracker.close();
+ }
+
+ @Test
+ public void packagingEnabled() throws Exception{
+ // Set log level to debug for Root logger
+ Configuration config = ca.getConfiguration(PID, null);
+ Dictionary<String, Object> p = new Hashtable<String, Object>();
+ p.put(LOG_PACKAGING_DATA, Boolean.TRUE);
+ p.put(LOG_LEVEL, "INFO");
+ config.update(p);
+
+ delay();
+
+ ServiceTracker<WeavingHook, WeavingHook> tracker = createWeavingHookTracker();
+ tracker.open();
+
+ assertNotNull(tracker.getService());
+ tracker.close();
+ }
+
+ @Test
+ public void packageDataWorking() throws Exception{
+ // Enable packaging
+ Configuration config = ca.getConfiguration(PID, null);
+ Dictionary<String, Object> p = new Hashtable<String, Object>();
+ p.put(LOG_PACKAGING_DATA, Boolean.TRUE);
+ p.put(LOG_LEVEL, "INFO");
+ config.update(p);
+ delay();
+
+ //Configure a file logger for test class
+ Configuration config2 = ca.createFactoryConfiguration(FACTORY_PID_CONFIGS, null);
+ Dictionary<String, Object> p2 = new Hashtable<String, Object>();
+ p2.put(LOG_LOGGERS, new String[] {
+ PackageDataActivator.LOGGER_NAME
+ });
+ String logFileName = "logs/package-test.log";
+ p2.put(LOG_FILE, logFileName);
+ p2.put(LOG_LEVEL, "INFO");
+ config2.update(p2);
+ delay();
+
+
+ //Ensure that weaving hook comes up
+ ServiceTracker<WeavingHook, WeavingHook> tracker = createWeavingHookTracker();
+ tracker.open();
+ tracker.waitForService(60*1000);
+
+ //Now install the test bundle such that hook picks it up
+ InputStream inp = PackagingDataTestUtil.createTestBundle();
+ Bundle b = bundleContext.installBundle("test", inp);
+ b.start();
+
+ //Now wait for runnable registered by the test bundle
+ ServiceTracker<Runnable, Runnable> runableTracker = createTracker(Runnable.class, PackageDataActivator.LOGGER_NAME);
+ runableTracker.open();
+
+ //Now invoke the method to trigger logger call with exception
+ Runnable r = runableTracker.waitForService(60*1000);
+ r.run();
+
+ //Now read the log file content to assert that stacktrace has version present
+ String slingHome = System.getProperty("sling.home");
+ File logFile = new File(FilenameUtils.concat(slingHome, logFileName));
+ String logFileContent = FileUtils.readFileToString(logFile);
+
+ System.out.println("--------------------");
+ System.out.println(logFileContent);
+ System.out.println("--------------------");
+
+ List<String> lines = FileUtils.readLines(logFile);
+ String testLine = null;
+ for (String l : lines) {
+ if (l.contains("org.apache.sling.commons.log.logback.integration.bundle.TestRunnable.run(")){
+ testLine = l;
+ break;
+ }
+ }
+ assertNotNull(testLine);
+ assertThat(testLine, containsString("["+PackagingDataTestUtil.TEST_BUNDLE_VERSION+"]"));
+
+ //Check that default logback support is still disabled
+ assertFalse(((LoggerContext) LoggerFactory.getILoggerFactory()).isPackagingDataEnabled());
+ }
+
+ private ServiceTracker<WeavingHook, WeavingHook> createWeavingHookTracker() throws InvalidSyntaxException {
+ return createTracker(WeavingHook.class, LogbackManager.PACKAGE_INFO_COLLECTOR_DESC);
+ }
+
+ private <T> ServiceTracker<T,T> createTracker(Class<T> clazz, String desc) throws InvalidSyntaxException {
+ String filter = String.format("(&(%s=%s)(%s=%s))", Constants.OBJECTCLASS, clazz.getName(),
+ Constants.SERVICE_DESCRIPTION, desc);
+ Filter f = FrameworkUtil.createFilter(filter);
+ return new ServiceTracker<>(bundleContext, f, null);
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/commons/log/logback/integration/PackagingDataTestUtil.java b/src/test/java/org/apache/sling/commons/log/logback/integration/PackagingDataTestUtil.java
new file mode 100644
index 0000000..db5c5ed
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/log/logback/integration/PackagingDataTestUtil.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.log.logback.integration;
+
+import java.io.InputStream;
+
+import org.apache.sling.commons.log.logback.integration.bundle.PackageDataActivator;
+import org.apache.sling.commons.log.logback.integration.bundle.TestRunnable;
+import org.ops4j.pax.tinybundles.core.InnerClassStrategy;
+import org.osgi.framework.Constants;
+
+import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * Have to use a separate class due to TinyBundles having issue and recommends put bundle
+ * creation logic in separate class
+ */
+public class PackagingDataTestUtil {
+
+ public static final String TEST_BUNDLE_VERSION = "0.0.7";
+
+ public static InputStream createTestBundle() {
+ return bundle()
+ .set(Constants.BUNDLE_ACTIVATOR, PackageDataActivator.class.getName())
+ .set(Constants.BUNDLE_SYMBOLICNAME, "packagedatatest")
+ .set(Constants.BUNDLE_VERSION, TEST_BUNDLE_VERSION)
+ .add(PackageDataActivator.class, InnerClassStrategy.NONE)
+ .add(TestRunnable.class, InnerClassStrategy.NONE)
+ .build(withBnd());
+ }
+}
diff --git a/src/test/java/org/apache/sling/commons/log/logback/integration/bundle/PackageDataActivator.java b/src/test/java/org/apache/sling/commons/log/logback/integration/bundle/PackageDataActivator.java
new file mode 100644
index 0000000..18155a2
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/log/logback/integration/bundle/PackageDataActivator.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.log.logback.integration.bundle;
+
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+public class PackageDataActivator implements BundleActivator {
+ public static final String LOGGER_NAME = "test.PackageDataActivator";
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ Hashtable props = new Hashtable();
+ props.put(Constants.SERVICE_DESCRIPTION, LOGGER_NAME);
+ context.registerService(Runnable.class.getName(), new TestRunnable(), props);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/commons/log/logback/integration/bundle/TestRunnable.java b/src/test/java/org/apache/sling/commons/log/logback/integration/bundle/TestRunnable.java
new file mode 100644
index 0000000..ede6f69
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/log/logback/integration/bundle/TestRunnable.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.log.logback.integration.bundle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestRunnable implements Runnable {
+ private final Logger log = LoggerFactory.getLogger(PackageDataActivator.LOGGER_NAME);
+
+ @Override
+ public void run() {
+ log.warn("==PackageDataActivator==", new Exception());
+ }
+}
diff --git a/src/test/java/org/apache/sling/commons/log/logback/internal/stacktrace/PackageInfoCollectorTest.java b/src/test/java/org/apache/sling/commons/log/logback/internal/stacktrace/PackageInfoCollectorTest.java
new file mode 100644
index 0000000..f3ec3f5
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/log/logback/internal/stacktrace/PackageInfoCollectorTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.commons.log.logback.internal.stacktrace;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class PackageInfoCollectorTest {
+ @Test
+ public void packageName() throws Exception{
+ assertEquals("com.foo", PackageInfoCollector.getPackageName("com.foo.TestClass"));
+ assertEquals("", PackageInfoCollector.getPackageName("packageInDefaultClass"));
+ }
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.