| /******************************************************************************* |
| * Copyright (c) 2007, 2016 IBM Corporation |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| package org.eclipse.osgi.internal.log; |
| |
| import java.lang.reflect.*; |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| import org.eclipse.equinox.log.SynchronousLogListener; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.log.LogEntry; |
| import org.osgi.service.log.LogService; |
| |
| public class EventAdminLogListener implements SynchronousLogListener { |
| |
| // constants for Event topic substring |
| public static final String TOPIC = "org/osgi/service/log/LogEntry"; //$NON-NLS-1$ |
| public static final char TOPIC_SEPARATOR = '/'; |
| // constants for Event types |
| public static final String LOG_ERROR = "LOG_ERROR"; //$NON-NLS-1$ |
| public static final String LOG_WARNING = "LOG_WARNING"; //$NON-NLS-1$ |
| public static final String LOG_INFO = "LOG_INFO"; //$NON-NLS-1$ |
| public static final String LOG_DEBUG = "LOG_DEBUG"; //$NON-NLS-1$ |
| public static final String LOG_OTHER = "LOG_OTHER"; //$NON-NLS-1$ |
| // constants for Event properties |
| public static final String TIMESTAMP = "timestamp"; //$NON-NLS-1$ |
| public static final String MESSAGE = "message"; //$NON-NLS-1$ |
| public static final String LOG_LEVEL = "log.level"; //$NON-NLS-1$ |
| public static final String LOG_ENTRY = "log.entry"; //$NON-NLS-1$ |
| public static final String SERVICE = "service"; //$NON-NLS-1$ |
| public static final String SERVICE_ID = "service.id"; //$NON-NLS-1$ |
| public static final String SERVICE_OBJECTCLASS = "service.objectClass"; //$NON-NLS-1$ |
| public static final String SERVICE_PID = "service.pid"; //$NON-NLS-1$ |
| public static final String BUNDLE = "bundle"; //$NON-NLS-1$ |
| public static final String BUNDLE_ID = "bundle.id"; //$NON-NLS-1$ |
| public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName"; //$NON-NLS-1$ |
| public static final String EVENT = "event"; //$NON-NLS-1$ |
| public static final String EXCEPTION = "exception"; //$NON-NLS-1$ |
| public static final String EXCEPTION_CLASS = "exception.class"; //$NON-NLS-1$ |
| public static final String EXCEPTION_MESSAGE = "exception.message"; //$NON-NLS-1$ |
| |
| private final Object eventAdmin; |
| private final Method postEvent; |
| private final Constructor<?> event; |
| |
| public EventAdminLogListener(Object eventAdmin) throws ClassNotFoundException, NoSuchMethodException { |
| this.eventAdmin = eventAdmin; |
| Class<?> eventAdminClass = eventAdmin.getClass(); |
| ClassLoader cl = eventAdminClass.getClassLoader(); |
| Class<?> eventClass = cl.loadClass("org.osgi.service.event.Event"); //$NON-NLS-1$ |
| |
| postEvent = eventAdminClass.getMethod("postEvent", eventClass); //$NON-NLS-1$ |
| event = eventClass.getConstructor(String.class, Dictionary.class); |
| } |
| |
| @Override |
| public void logged(LogEntry entry) { |
| try { |
| Object convertedEvent = convertEvent(entry); |
| postEvent.invoke(eventAdmin, convertedEvent); |
| } catch (InvocationTargetException e) { |
| Throwable t = e.getTargetException(); |
| if ((t instanceof RuntimeException)) |
| throw (RuntimeException) t; |
| if ((t instanceof Error)) |
| throw (Error) t; |
| // unexpected |
| throw new RuntimeException(e); |
| } catch (IllegalAccessException | InstantiationException e) { |
| // unexpected |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private Object convertEvent(LogEntry entry) throws InstantiationException, IllegalAccessException, InvocationTargetException { |
| String topic = TOPIC; |
| int level = entry.getLevel(); |
| switch (level) { |
| case LogService.LOG_ERROR : |
| topic += TOPIC_SEPARATOR + LOG_ERROR; |
| break; |
| case LogService.LOG_WARNING : |
| topic += TOPIC_SEPARATOR + LOG_WARNING; |
| break; |
| case LogService.LOG_INFO : |
| topic += TOPIC_SEPARATOR + LOG_INFO; |
| break; |
| case LogService.LOG_DEBUG : |
| topic += TOPIC_SEPARATOR + LOG_DEBUG; |
| break; |
| default : // other log levels are represented by LOG_OTHER |
| topic += TOPIC_SEPARATOR + LOG_OTHER; |
| } |
| Hashtable<String, Object> properties = new Hashtable<>(); |
| Bundle bundle = entry.getBundle(); |
| if (bundle == null) { |
| throw new RuntimeException("LogEntry.getBundle() returns null"); //$NON-NLS-1$ |
| } |
| putBundleProperties(properties, bundle); |
| Throwable t = entry.getException(); |
| if (t != null) { |
| putExceptionProperties(properties, t); |
| } |
| ServiceReference<?> ref = entry.getServiceReference(); |
| if (ref != null) { |
| putServiceReferenceProperties(properties, ref); |
| } |
| properties.put(LOG_ENTRY, entry); |
| properties.put(LOG_LEVEL, Integer.valueOf(entry.getLevel())); |
| if (entry.getMessage() != null) |
| properties.put(MESSAGE, entry.getMessage()); |
| properties.put(TIMESTAMP, new Long(entry.getTime())); |
| return event.newInstance(topic, properties); |
| } |
| |
| public static void putServiceReferenceProperties(Hashtable<String, Object> properties, ServiceReference<?> ref) { |
| properties.put(SERVICE, ref); |
| properties.put(SERVICE_ID, ref.getProperty(org.osgi.framework.Constants.SERVICE_ID)); |
| Object o = ref.getProperty(org.osgi.framework.Constants.SERVICE_PID); |
| if ((o != null) && (o instanceof String)) { |
| properties.put(SERVICE_PID, o); |
| } |
| Object o2 = ref.getProperty(org.osgi.framework.Constants.OBJECTCLASS); |
| if ((o2 != null) && (o2 instanceof String[])) { |
| properties.put(SERVICE_OBJECTCLASS, o2); |
| } |
| } |
| |
| public static void putBundleProperties(Hashtable<String, Object> properties, Bundle bundle) { |
| properties.put(BUNDLE_ID, new Long(bundle.getBundleId())); |
| String symbolicName = bundle.getSymbolicName(); |
| if (symbolicName != null) { |
| properties.put(BUNDLE_SYMBOLICNAME, symbolicName); |
| } |
| properties.put(BUNDLE, bundle); |
| } |
| |
| public static void putExceptionProperties(Hashtable<String, Object> properties, Throwable t) { |
| properties.put(EXCEPTION, t); |
| properties.put(EXCEPTION_CLASS, t.getClass().getName()); |
| String message = t.getMessage(); |
| if (message != null) { |
| properties.put(EXCEPTION_MESSAGE, t.getMessage()); |
| } |
| } |
| } |