package com.buglabs.osgi.log; import java.io.PrintStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.log.LogEntry; import org.osgi.service.log.LogListener; import org.osgi.service.log.LogReaderService; import org.osgi.service.log.LogService; /** * This class implements both the LogService and LogReaderServices. * * @author kgilmer * */ public class LogServiceImpl implements LogService, LogReaderService { /** * Number of messages to store before removing the oldest. */ private static final int DEFAULT_LOG_MESSAGE_BUFFER = 32; private static final String DEFAULT_DATE_FORMAT = "MM/dd HH:mm.ss"; /** * In-memory storage for log messages. */ private FixedSizeQueue queue; /** * If true, no log data should be emitted. */ public boolean quiet; /** * Log level that should emit data. */ public int logLevel; public static PrintStream out; public static PrintStream err; public int bufferSize; private List listeners; private String dateFormat; public LogServiceImpl(BundleContext bundleContext) { quiet = bundleContext.getProperty("org.osgi.logging.quiet") != null; if (bundleContext.getProperty("org.osgi.logging.level") != null) { logLevel = Integer.parseInt(bundleContext.getProperty("org.osgi.logging.level")); } else { // By default print all log data. logLevel = LogService.LOG_DEBUG; } // Use the system io stream. This could be augmented in the future to // send to files or servers. out = System.out; err = System.err; if (bundleContext.getProperty("org.osgi.logging.bufferSize") != null) { bufferSize = Integer.parseInt(bundleContext.getProperty("org.osgi.logging.bufferSize")); } else { bufferSize = DEFAULT_LOG_MESSAGE_BUFFER; } queue = new FixedSizeQueue(bufferSize); if (bundleContext.getProperty("org.osgi.logging.date.format") != null) { dateFormat = bundleContext.getProperty("org.osgi.logging.bufferSize"); } else { dateFormat = DEFAULT_DATE_FORMAT; } } public void dispose() { if (listeners != null) { listeners.clear(); } if (queue != null) { queue.clear(); } } public void log(int level, String message) { LogEntry le = new LogEntryImpl(null, level, message, null, System.currentTimeMillis(), null, dateFormat); printLog(le); queue.add(le); notifyListeners(le); } private void printLog(LogEntry le) { if (!quiet && isPrintable(le.getLevel())) { if (le.getLevel() == LogService.LOG_ERROR) { ((LogEntryImpl) le).print(err); } else { ((LogEntryImpl) le).print(out); } } } /** * Should log content for given level be printed? * * @param level * @return */ private boolean isPrintable(int level) { return level <= logLevel; } public void log(int arg0, String arg1, Throwable arg2) { LogEntry le = new LogEntryImpl(null, arg0, arg1, null, System.currentTimeMillis(), arg2, dateFormat); printLog(le); queue.add(le); notifyListeners(le); } public void log(ServiceReference arg0, int arg1, String arg2) { LogEntry le = new LogEntryImpl(null, arg1, arg2, arg0, System.currentTimeMillis(), null, dateFormat); printLog(le); queue.add(le); notifyListeners(le); } public void log(ServiceReference arg0, int arg1, String arg2, Throwable arg3) { LogEntry le = new LogEntryImpl(null, arg1, arg2, arg0, System.currentTimeMillis(), arg3, dateFormat); printLog(le); queue.add(le); notifyListeners(le); } private void notifyListeners(LogEntry le) { if (listeners == null || listeners.size() == 0) { return; } synchronized (listeners) { for (Iterator i = listeners.iterator(); i.hasNext();) { ((LogListener) i.next()).logged(le); } } } public void addLogListener(LogListener arg0) { if (listeners == null) { listeners = new ArrayList(); } synchronized (listeners) { if (!listeners.contains(arg0)) { listeners.add(arg0); } } } public Enumeration getLog() { //To prevent concurrent modification, create a copy of the log and pass it to the client. final List l = new ArrayList(queue); return new Enumeration() { Iterator i = l.iterator(); public boolean hasMoreElements() { return i.hasNext(); } public Object nextElement() { return i.next(); } }; } public void removeLogListener(LogListener arg0) { if (listeners != null) { synchronized (listeners) { listeners.remove(arg0); } } } }