blob: 3dfa6950a6b1fd1d73ff360e1c456ea2dd76219a [file] [log] [blame]
/*
* Copyright 2005 The Apache Software Foundation
*
* 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 org.apache.felix.mosgi.jmx.remotelogger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Constants;
import org.osgi.service.log.LogListener;
import org.osgi.service.log.LogReaderService;
import org.osgi.service.log.LogService;
import org.osgi.service.log.LogEntry;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.NotificationBroadcasterSupport;
import javax.management.AttributeChangeNotification;
import javax.management.MalformedObjectNameException;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Vector;
public class Logger extends NotificationBroadcasterSupport implements LogListener,BundleActivator,ServiceListener, LoggerMBean, Serializable{
private static final String REMOTE_LOGGER_ON_STRING="OSGI:name=Remote Logger";
private ServiceRegistration mbean_sr=null;
private String version=null;
private LogReaderService lrs=null;
private BundleContext bc=null;
private Object logMutex=new Object();
private static final String[] LOG_LVL=new String[] {"","ERROR ","WARNING ","INFO ","DEBUG "};
private Integer logLvl=new Integer(4);
private ObjectName remoteLoggerON=null;
/////////////////////////////////
// LogerMBean Interface //
/////////////////////////////////
public void sendOldLog(){
System.out.println("[remoteLogger.Logger] send old log");
Enumeration oldLog = this.lrs.getLog();
Vector invert=new Vector();
while(oldLog.hasMoreElements()) {
LogEntry le=(LogEntry) (oldLog.nextElement());
invert.insertElementAt(le,0);
}
for (int i=0 ; i<invert.size() ; i++) {
logged( (LogEntry) invert.elementAt(i), true );
}
}
public void setLogLvl(Integer lvl) {
this.logLvl=lvl;
String logLvlToString=(new String[] {"Error", "Warning", "Info", "Debug"})[lvl.intValue()-1];
this.log(LogService.LOG_INFO, "Log level is now \""+logLvlToString+"\".");
System.out.println("[Logger] : modification of log lvl : logLvl="+logLvl+" ("+logLvlToString+")");
}
public Integer getLogLvl() {
return logLvl;
}
///////////////////////////////////////
// ServiceListener Interface //
///////////////////////////////////////
public void serviceChanged(ServiceEvent serviceevent) {
ServiceReference servicereference= serviceevent.getServiceReference();
String as[]=(String[])servicereference.getProperty("objectClass");
switch (serviceevent.getType()) {
case ServiceEvent.REGISTERED :
if (as[0].equals(LogReaderService.class.getName())){
this.registerLogReaderService(servicereference);
}
break;
case ServiceEvent.UNREGISTERING :
if (as[0].equals(LogReaderService.class.getName())){
this.unRegisterLogReaderService(servicereference);
}
break;
}
}
/////////////////////////////////////////
// LogListener Interface //
/////////////////////////////////////////
public void logged(LogEntry log){
logged(log, false);
}
public void logged(LogEntry log, boolean oldLog){
synchronized (logMutex){
if (log.getLevel() <= logLvl.intValue() ) {
String reg=new String("*");
StringBuffer message=new StringBuffer();
try{
long id=log.getBundle().getBundleId();
message.append( ((id<10)?" ":"")+id );
} catch(NullPointerException e){
message.append("Unknown source");
}
String lSymbolicName=log.getBundle().getSymbolicName();
message.append( reg+ ((lSymbolicName!=null)?lSymbolicName:"\"null\"") );
message.append(reg+log.getBundle().getState());
message.append(reg+LOG_LVL[log.getLevel()]);
// into log.getMessage() replaceAll regex char by an other
String msg=log.getMessage();
message.append( reg+ ((msg!=null)?msg.replace('*','X'):"\"null\"") );
this.sendNotification(new AttributeChangeNotification(this.remoteLoggerON, 0, (oldLog)?0:System.currentTimeMillis(), message.toString(), null, "Log", null, null));
}
}
}
//////////////////////////////////
// BundleActivator Interface //
//////////////////////////////////
public void start(BundleContext bc) throws Exception{
this.version=(String)bc.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
this.bc=bc;
this.log(LogService.LOG_INFO, "Remote Logger starting "+version);
java.util.Properties p = new java.util.Properties();
try {
this.remoteLoggerON = new ObjectName(Logger.REMOTE_LOGGER_ON_STRING);
} catch (MalformedObjectNameException mne) {
throw new BundleException("Logger.Logger:objectName invalid", mne);
}
p.put(org.apache.felix.mosgi.jmx.agent.Constants.OBJECTNAME, REMOTE_LOGGER_ON_STRING);
this.mbean_sr = this.bc.registerService(LoggerMBean.class.getName(), this, p);
try{
bc.addServiceListener(this,"(|(objectClass="+LogReaderService.class.getName()+")"+
"(objectClass="+MBeanServer.class.getName()+"))");
}catch(InvalidSyntaxException e){
throw new BundleException("Logger.Logger:filtre LDAP", e);
}
ServiceReference sr=bc.getServiceReference(LogReaderService.class.getName());
if (sr!=null){
this.registerLogReaderService(sr);
}
this.log(LogService.LOG_INFO, "Remote Logger started (logLvl="+logLvl+")"+version);
}
public void stop(BundleContext bc) throws Exception{
this.log(LogService.LOG_INFO, "Stopping remote Logger "+version);
if (this.lrs==null){
System.out.println("ERROR : Logger.stop : there is no logger or reader to stop");
} else {
this.lrs.removeLogListener(this);
this.bc.removeServiceListener(this);
}
this.lrs=null;
this.log(LogService.LOG_INFO, "Remote Logger stopped"+version);
this.mbean_sr.unregister();
this.mbean_sr=null;
this.bc=null;
}
//////////////////////////////
// private methods //
//////////////////////////////
private void registerLogReaderService(ServiceReference sr) {
//System.out.println("mosgi.jmx.remoteLogger.Logger.registerLogReaderService("+sr.toString()+") : oldLog=");
this.lrs=(LogReaderService)this.bc.getService(sr);
this.lrs.addLogListener(this);
}
private void unRegisterLogReaderService(ServiceReference sr) {
if (sr!=null){
this.lrs.removeLogListener(this);
this.lrs=null;
}
}
private void log (int level, String message){
ServiceReference lsn=bc.getServiceReference(LogService.class.getName());
if (lsn!=null){
LogService ls=(LogService)bc.getService(lsn);
ls.log(level, message);
}else{
System.out.println("ERROR : Logger.start : No service "+LogService.class.getName()+" is present");
}
}
}