/* * Dog - Core * * Copyright (c) 2013 Luigi De Russis * * Licensed 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 it.polito.elite.dog.core.log.console; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Dictionary; import java.util.HashMap; import java.util.Vector; import java.util.concurrent.atomic.AtomicReference; import org.osgi.framework.BundleContext; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; 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 a Console Logger, by using the OSGi LogService. It can * also receive configuration data for enabling/disabling the output of the * standard OSGi log levels (error, warning, debug, and info). * * @author <a href="mailto:luigi.derussis@polito.it">Luigi De Russis</a> * @see <a href="http://elite.polito.it">http://elite.polito.it</a> * @since September, 2013 * */ public class ConsoleLog implements LogListener, ManagedService { // the registered LogReaderService private AtomicReference<LogReaderService> registeredLogReader; // log types public static String[] logTypes = new String[] { "ERROR", "WARNING", "DEBUG", "INFO" }; // enable or disable the output public static enum LogWriter { Console, None }; // the table for setting the desired log levels private HashMap<Integer, Vector<LogWriter>> loggerWriterTable; /** * Default constructor */ public ConsoleLog() { // initialize atomic references this.registeredLogReader = new AtomicReference<LogReaderService>(); } /** * Activate this component (after its bind) * * @param bundleContext * the bundle context */ public void activate(BundleContext bundleContext) { // init the table for setting the desired log levels this.loggerWriterTable = new HashMap<Integer, Vector<LogWriter>>(); this.createDefaultWriterTable(); } /** * Deactivate this component (before its unbind) */ public void deactivate() { // clear everything this.loggerWriterTable.clear(); // set everything to null this.loggerWriterTable = null; } /** * Initialize the table for setting the desired log levels: by default, it * shows all the log in the console */ private void createDefaultWriterTable() { Vector<LogWriter> vectWriter = new Vector<LogWriter>(); vectWriter.add(LogWriter.Console); this.loggerWriterTable.put(LogService.LOG_INFO, vectWriter); this.loggerWriterTable.put(LogService.LOG_DEBUG, vectWriter); this.loggerWriterTable.put(LogService.LOG_ERROR, vectWriter); this.loggerWriterTable.put(LogService.LOG_WARNING, vectWriter); } /** * Bind the component (before its activation) * * @param reader * the required LogReaderService */ public void addedLogReaderService(LogReaderService reader) { // store the registered log reader service this.registeredLogReader.set(reader); // add the current class as log listener reader.addLogListener(this); } /** * Unbind the component (after its deactivation) * * @param reader * the LogReaderService to unbind */ public void removedLogReaderService(LogReaderService reader) { // remove the current class as log listener reader.removeLogListener(this); // remove the previous registered log reader service this.registeredLogReader.compareAndSet(reader, null); } /** * Perform the effective log action */ @Override public void logged(LogEntry entry) { // get the log level int logEntryType = entry.getLevel(); // show logs according to the configured log levels if (this.loggerWriterTable != null && this.loggerWriterTable.containsKey(logEntryType)) { Vector<LogWriter> writers = this.loggerWriterTable.get(logEntryType); if (writers != null) { for (LogWriter writer : writers) { switch (writer) { case Console: System.out.println("LOG " + this.getLogLevel(entry) + " [" + entry.getBundle().getSymbolicName() + "] " + entry.getMessage() + "\n"); break; default: break; } } } } } /** * Convert OSGi log levels to bundle-related log levels (and add the current * timestamp) * * @param entry * the log entry to display * @return the human readable log level information (plus a timestamp) */ private String getLogLevel(LogEntry entry) { // get the time StringBuilder sb = new StringBuilder(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd hh:mm:ss"); sb.append(sdf.format(Calendar.getInstance().getTime())); // log levels switch (entry.getLevel()) { case LogService.LOG_DEBUG: sb.append(" DEBUG"); break; case LogService.LOG_ERROR: sb.append(" ERROR"); break; case LogService.LOG_INFO: sb.append(" INFO"); break; case LogService.LOG_WARNING: sb.append(" WARNING"); break; default: break; } return sb.toString(); } /** * Configuration data received from the Configuration Admin */ @Override public void updated(Dictionary<String, ?> properties) throws ConfigurationException { // maybe the received configuration is not for me... if (properties != null) { // set each log level to console or none, according to configuration // data String errorWriters = (String) properties.get("ERROR"); if (errorWriters != null) { this.setWriters(LogService.LOG_ERROR, errorWriters); } String debugWriters = (String) properties.get("DEBUG"); if (debugWriters != null) { this.setWriters(LogService.LOG_DEBUG, debugWriters); } String wariningWriters = (String) properties.get("WARNING"); if (wariningWriters != null) { this.setWriters(LogService.LOG_WARNING, wariningWriters); } String infoWriters = (String) properties.get("INFO"); if (infoWriters != null) { this.setWriters(LogService.LOG_INFO, infoWriters); } } } /** * Set the given log level to console or none, according to configuration * data received * * @param logLevel * the log level to set * @param writers * console or none, i.e., show or not show the log associated to * the given level */ private void setWriters(int logLevel, String writers) { String ws[] = writers.split(","); Vector<LogWriter> vect = new Vector<LogWriter>(); for (String writer : ws) { try { LogWriter lw = LogWriter.valueOf(writer); vect.add(lw); } catch (Exception e) { e.printStackTrace(); } } this.loggerWriterTable.put(logLevel, vect); } }