diff options
author | Thomas Watson | 2017-03-31 14:47:31 +0000 |
---|---|---|
committer | Thomas Watson | 2017-06-16 12:38:08 +0000 |
commit | 1bc1071713d4d94f1c7200fe1a90f806256b7554 (patch) | |
tree | 3a341b5a920b5e4d72462c7f3c914815e346c5ee /bundles/org.eclipse.osgi/container/src/org/eclipse | |
parent | 7b23ce8d04850e284d6c690671a02ea3c5df7655 (diff) | |
download | rt.equinox.framework-1bc1071713d4d94f1c7200fe1a90f806256b7554.tar.gz rt.equinox.framework-1bc1071713d4d94f1c7200fe1a90f806256b7554.tar.xz rt.equinox.framework-1bc1071713d4d94f1c7200fe1a90f806256b7554.zip |
[bug 486950] [osgi R7] log service is being updated
Initial implementation. Includes Java 6/7 aspects only (e.g., no LogStream, etc.).
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse')
5 files changed, 470 insertions, 17 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/Arguments.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/Arguments.java new file mode 100644 index 000000000..187b7b2a5 --- /dev/null +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/Arguments.java @@ -0,0 +1,56 @@ +package org.eclipse.osgi.internal.log; + +import org.osgi.framework.ServiceReference; + +public class Arguments { + private final Object[] arguments; + private final ServiceReference<?> serviceReference; + private final Throwable throwable; + + public Arguments(Object... arguments) { + if (arguments == null || arguments.length == 0) { + this.arguments = new Object[0]; + serviceReference = null; + throwable = null; + return; + } + int length = arguments.length; + ServiceReference<?> context = null; + Throwable exception = null; + Object object = arguments[arguments.length - 1]; + if (object instanceof Throwable) { + length--; + exception = (Throwable) object; + if (arguments.length > 1) { + object = arguments[arguments.length - 2]; + if (object instanceof ServiceReference) { + length--; + context = (ServiceReference<?>) object; + } + } + } else if (object instanceof ServiceReference) { + length--; + context = (ServiceReference<?>) object; + } + serviceReference = context; + throwable = exception; + this.arguments = new Object[length]; + System.arraycopy(arguments, 0, this.arguments, 0, length); + } + + public Object[] arguments() { + return arguments; + } + + public boolean isEmpty() { + return arguments == null || arguments.length == 0; + } + + public ServiceReference<?> serviceReference() { + return serviceReference; + } + + public Throwable throwable() { + return throwable; + } +} diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogEntryImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogEntryImpl.java index eb30db5ee..ee492f5f6 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogEntryImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogEntryImpl.java @@ -13,6 +13,7 @@ import org.eclipse.equinox.log.ExtendedLogEntry; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; import org.osgi.service.log.LogEntry; +import org.osgi.service.log.LogLevel; public class ExtendedLogEntryImpl implements ExtendedLogEntry, LogEntry { @@ -30,6 +31,7 @@ public class ExtendedLogEntryImpl implements ExtendedLogEntry, LogEntry { private final long threadId; private final String threadName; private final long sequenceNumber; + private final StackTraceElement stackTraceElement; private static Map<Thread, Long> createThreadIdMap() { try { @@ -68,6 +70,8 @@ public class ExtendedLogEntryImpl implements ExtendedLogEntry, LogEntry { this.threadId = getId(currentThread); this.sequenceNumber = nextSequenceNumber++; } + + stackTraceElement = currentThread.getStackTrace()[2]; } public String getLoggerName() { @@ -117,4 +121,24 @@ public class ExtendedLogEntryImpl implements ExtendedLogEntry, LogEntry { public Object getContext() { return contextObject; } + + @Override + public LogLevel getLogLevel() { + return LogLevel.values()[getLevel()]; + } + + @Override + public long getSequence() { + return getSequenceNumber(); + } + + @Override + public String getThreadInfo() { + return getThreadName(); + } + + @Override + public StackTraceElement getLocation() { + return stackTraceElement; + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogServiceImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogServiceImpl.java index 606a52b90..ab8dbb213 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogServiceImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/ExtendedLogServiceImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2016 Cognos Incorporated, IBM Corporation and others + * Copyright (c) 2006, 2012 Cognos Incorporated, IBM Corporation and others * All rights reserved. This program and the accompanying materials are made * available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at @@ -8,21 +8,23 @@ package org.eclipse.osgi.internal.log; import java.util.HashMap; +import java.util.Map; import org.eclipse.equinox.log.ExtendedLogService; import org.eclipse.equinox.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; -import org.osgi.service.log.LogService; -public class ExtendedLogServiceImpl implements ExtendedLogService, LogService { +public class ExtendedLogServiceImpl implements ExtendedLogService { private final ExtendedLogServiceFactory factory; private volatile Bundle bundle; - private final HashMap<String, Logger> loggerCache = new HashMap<>(); + private final Map<Class<? extends org.osgi.service.log.Logger>, Map<String, Logger>> loggerCache = new HashMap<>(); public ExtendedLogServiceImpl(ExtendedLogServiceFactory factory, Bundle bundle) { this.factory = factory; this.bundle = bundle; + loggerCache.put(org.osgi.service.log.Logger.class, new HashMap<String, Logger>()); + loggerCache.put(org.osgi.service.log.FormatterLogger.class, new HashMap<String, Logger>()); } public void log(int level, String message) { @@ -40,7 +42,7 @@ public class ExtendedLogServiceImpl implements ExtendedLogService, LogService { @SuppressWarnings("rawtypes") public void log(ServiceReference sr, int level, String message, Throwable exception) { - getLogger(null).log(sr, level, message, exception); + getLogger((String) null).log(sr, level, message, exception); } public void log(Object context, int level, String message) { @@ -48,16 +50,11 @@ public class ExtendedLogServiceImpl implements ExtendedLogService, LogService { } public void log(Object context, int level, String message, Throwable exception) { - getLogger(null).log(context, level, message, exception); + getLogger((String) null).log(context, level, message, exception); } - public synchronized Logger getLogger(String name) { - Logger logger = loggerCache.get(name); - if (logger == null) { - logger = new LoggerImpl(this, name); - loggerCache.put(name, logger); - } - return logger; + public Logger getLogger(String name) { + return (Logger) getLogger(name, org.osgi.service.log.Logger.class); } public Logger getLogger(Bundle logBundle, String name) { @@ -70,11 +67,11 @@ public class ExtendedLogServiceImpl implements ExtendedLogService, LogService { } public String getName() { - return getLogger(null).getName(); + return getLogger((String) null).getName(); } public boolean isLoggable(int level) { - return getLogger(null).isLoggable(level); + return getLogger((String) null).isLoggable(level); } // package private methods called from Logger @@ -90,4 +87,173 @@ public class ExtendedLogServiceImpl implements ExtendedLogService, LogService { void setBundle(Bundle bundle) { this.bundle = bundle; } + + @Override + public org.osgi.service.log.Logger getLogger(Class<?> clazz) { + return getLogger(clazz.getName()); + } + + @Override + public synchronized <L extends org.osgi.service.log.Logger> L getLogger(String name, Class<L> loggerType) { + Map<String, Logger> loggers = loggerCache.get(loggerType); + if (loggers == null) { + throw new IllegalArgumentException(loggerType.getName()); + } + Logger logger = loggers.get(name); + if (logger == null) { + logger = new FormatterLoggerImpl(this, name); + loggers.put(name, logger); + } + return loggerType.cast(logger); + } + + @Override + public <L extends org.osgi.service.log.Logger> L getLogger(Class<?> clazz, Class<L> loggerType) { + return getLogger(clazz.getName(), loggerType); + } + + @Override + public boolean isTraceEnabled() { + return getLogger((String) null).isTraceEnabled(); + } + + @Override + public void trace(String message) { + getLogger((String) null).trace(message); + } + + @Override + public void trace(String format, Object arg) { + getLogger((String) null).trace(format, arg); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + getLogger((String) null).trace(format, arg1, arg2); + } + + @Override + public void trace(String format, Object... arguments) { + getLogger((String) null).trace(format, arguments); + } + + @Override + public boolean isDebugEnabled() { + return getLogger((String) null).isDebugEnabled(); + } + + @Override + public void debug(String message) { + getLogger((String) null).debug(message); + } + + @Override + public void debug(String format, Object arg) { + getLogger((String) null).debug(format, arg); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + getLogger((String) null).debug(format, arg1, arg2); + } + + @Override + public void debug(String format, Object... arguments) { + getLogger((String) null).debug(format, arguments); + } + + @Override + public boolean isInfoEnabled() { + return getLogger((String) null).isInfoEnabled(); + } + + @Override + public void info(String message) { + getLogger((String) null).info(message); + } + + @Override + public void info(String format, Object arg) { + getLogger((String) null).info(format, arg); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + getLogger((String) null).info(format, arg1, arg2); + } + + @Override + public void info(String format, Object... arguments) { + getLogger((String) null).info(format, arguments); + } + + @Override + public boolean isWarnEnabled() { + return getLogger((String) null).isWarnEnabled(); + } + + @Override + public void warn(String message) { + getLogger((String) null).warn(message); + } + + @Override + public void warn(String format, Object arg) { + getLogger((String) null).warn(format, arg); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + getLogger((String) null).warn(format, arg1, arg2); + } + + @Override + public void warn(String format, Object... arguments) { + getLogger((String) null).warn(format, arguments); + } + + @Override + public boolean isErrorEnabled() { + return getLogger((String) null).isErrorEnabled(); + } + + @Override + public void error(String message) { + getLogger((String) null).error(message); + } + + @Override + public void error(String format, Object arg) { + getLogger((String) null).error(format, arg); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + getLogger((String) null).error(format, arg1, arg2); + } + + @Override + public void error(String format, Object... arguments) { + getLogger((String) null).error(format, arguments); + } + + @Override + public void audit(String message) { + getLogger((String) null).audit(message); + } + + @Override + public void audit(String format, Object arg) { + getLogger((String) null).audit(format, arg); + } + + @Override + public void audit(String format, Object arg1, Object arg2) { + getLogger((String) null).audit(format, arg1, arg2); + } + + @Override + public void audit(String format, Object... arguments) { + getLogger((String) null).audit(format, arguments); + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/FormatterLoggerImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/FormatterLoggerImpl.java new file mode 100644 index 000000000..d3ab1e478 --- /dev/null +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/FormatterLoggerImpl.java @@ -0,0 +1,17 @@ +package org.eclipse.osgi.internal.log; + +import org.osgi.service.log.FormatterLogger; +import org.osgi.service.log.LogLevel; + +public class FormatterLoggerImpl extends LoggerImpl implements FormatterLogger { + public FormatterLoggerImpl(ExtendedLogServiceImpl logServiceImpl, String name) { + super(logServiceImpl, name); + } + + @Override + protected void log(LogLevel level, String format, Object... arguments) { + Arguments processedArguments = new Arguments(arguments); + String message = String.format(format, processedArguments.arguments()); + logServiceImpl.log(name, processedArguments.serviceReference(), level.ordinal(), message, processedArguments.throwable()); + } +} diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/LoggerImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/LoggerImpl.java index 3fdfb32b8..792bbd087 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/LoggerImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/LoggerImpl.java @@ -7,13 +7,16 @@ ******************************************************************************/ package org.eclipse.osgi.internal.log; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.equinox.log.Logger; import org.osgi.framework.ServiceReference; +import org.osgi.service.log.LogLevel; public class LoggerImpl implements Logger { - private final ExtendedLogServiceImpl logServiceImpl; - private final String name; + protected final ExtendedLogServiceImpl logServiceImpl; + protected final String name; public LoggerImpl(ExtendedLogServiceImpl logServiceImpl, String name) { this.logServiceImpl = logServiceImpl; @@ -53,4 +56,191 @@ public class LoggerImpl implements Logger { public void log(Object context, int level, String message, Throwable exception) { logServiceImpl.log(name, context, level, message, exception); } + + @Override + public boolean isTraceEnabled() { + return isLoggable(LogLevel.TRACE.ordinal()); + } + + @Override + public void trace(String message) { + trace(message, (Object) null); + } + + @Override + public void trace(String format, Object arg) { + trace(format, arg, null); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + trace(format, new Object[] {arg1, arg2}); + } + + @Override + public void trace(String format, Object... arguments) { + log(LogLevel.TRACE, format, arguments); + } + + @Override + public boolean isDebugEnabled() { + return isLoggable(LogLevel.DEBUG.ordinal()); + } + + @Override + public void debug(String message) { + debug(message, (Object) null); + } + + @Override + public void debug(String format, Object arg) { + debug(format, arg, null); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + debug(format, new Object[] {arg1, arg2}); + } + + @Override + public void debug(String format, Object... arguments) { + log(LogLevel.DEBUG, format, arguments); + } + + @Override + public boolean isInfoEnabled() { + return isLoggable(LogLevel.INFO.ordinal()); + } + + @Override + public void info(String message) { + info(message, (Object) null); + } + + @Override + public void info(String format, Object arg) { + info(format, arg, null); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + info(format, new Object[] {arg1, arg2}); + } + + @Override + public void info(String format, Object... arguments) { + log(LogLevel.INFO, format, arguments); + } + + @Override + public boolean isWarnEnabled() { + return isLoggable(LogLevel.WARN.ordinal()); + } + + @Override + public void warn(String message) { + warn(message, (Object) null); + } + + @Override + public void warn(String format, Object arg) { + warn(format, arg, null); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + warn(format, new Object[] {arg1, arg2}); + } + + @Override + public void warn(String format, Object... arguments) { + log(LogLevel.WARN, format, arguments); + } + + @Override + public boolean isErrorEnabled() { + return isLoggable(LogLevel.ERROR.ordinal()); + } + + @Override + public void error(String message) { + error(message, (Object) null); + } + + @Override + public void error(String format, Object arg) { + error(format, arg, null); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + error(format, new Object[] {arg1, arg2}); + } + + @Override + public void error(String format, Object... arguments) { + log(LogLevel.ERROR, format, arguments); + } + + @Override + public void audit(String message) { + audit(message, (Object) null); + } + + @Override + public void audit(String format, Object arg) { + audit(format, arg, null); + } + + @Override + public void audit(String format, Object arg1, Object arg2) { + audit(format, new Object[] {arg1, arg2}); + } + + @Override + public void audit(String format, Object... arguments) { + log(LogLevel.AUDIT, format, arguments); + } + + private static final Pattern pattern = Pattern.compile("(\\\\?)(\\\\?)(\\{\\})"); //$NON-NLS-1$ + + protected void log(LogLevel level, String format, Object... arguments) { + Arguments processedArguments = new Arguments(arguments); + if (processedArguments.isEmpty()) { + logServiceImpl.log(name, processedArguments.serviceReference(), level.ordinal(), format, processedArguments.throwable()); + return; + } + Matcher matcher = pattern.matcher(format); + char[] chars = format.toCharArray(); + int offset = 0; + StringBuilder message = new StringBuilder(format.length() * 2); + for (Object argument : processedArguments.arguments()) { + // By design, the message will continue to be formatted for as long as arguments remain. + // Once all arguments have been processed, formatting stops. This means some escape characters + // and place holders may remain unconsumed. This matches SLF4J behavior. + while (matcher.find()) { + if (matcher.group(2).isEmpty()) { + if (matcher.group(1).isEmpty()) { + // {} Handle curly brackets as normal. + offset = append(message, matcher, chars, offset, matcher.start(3) - offset, argument); + break; + } + // \{} Ignore curly brackets. Consume backslash. + offset = append(message, matcher, chars, offset, matcher.start(3) - offset - 1, matcher.group(3)); + } else { + // \\{} Handle curly brackets as normal. Consume one backslash. + offset = append(message, matcher, chars, offset, matcher.start(3) - offset - 1, argument); + break; + } + } + } + message.append(chars, offset, chars.length - offset); + logServiceImpl.log(name, processedArguments.serviceReference(), level.ordinal(), message.toString(), processedArguments.throwable()); + } + + private static int append(StringBuilder builder, Matcher matcher, char[] chars, int offset, int length, Object argument) { + builder.append(chars, offset, length); + builder.append(argument); + return matcher.end(3); + } } |