/* * This file is protected by Copyright. Please refer to the COPYRIGHT file * distributed with this source distribution. * * This file is part of REDHAWK core. * * REDHAWK core is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package org.ossie.component; import java.util.ArrayList; import java.util.Arrays; import java.util.UUID; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.ossie.logging.logging; import CF.UnknownProperties; import CF.UnknownIdentifier; import CF.InvalidIdentifier; /** Loggging Class that implements all the features for the Logging IDL interface */ abstract public class Logging { /** * LoggingListener * This interface allows developers to modify the normal behavior when a request to * change the logging level or configuration context. * * Developers can provide an interface to the Resource through the * setNewLoggingListener method. */ public interface ConfigurationChangeListener { /** * logLevelChanged * * This method is called when a logging level request is made for this resource. The name of the * the logger to affect and the new level are provided. Logging level values are defined by the * CF::LogLevels constants. * * @param logId name of the logger to change the level, logId=="" is the root logger * @param newLevel the new logging level to apply * */ public void logLevelChanged( String logId, int newLevel ); /** * logConfigChanged * * This method is called when the logging configuration change is requested. The configuration * data follows the log4j configuration format (java props or xml). * * @param config_data the log4j formatted configuration data, either java properties or xml. */ public void logConfigChanged( String config_data ); } /** internal log4j logger object */ protected Logger _logger; /** log identifier, by default uses root logger or "" **/ protected String logName; /** current log level assigned to the resource **/ protected int logLevel; /** current string used configure the log **/ protected String logConfig; /** callback listener **/ protected ConfigurationChangeListener logListener; /** logging macro definitions maintained by resource */ protected logging.MacroTable loggingMacros; /** logging context assigned to resource */ protected logging.ResourceCtx loggingCtx=null; /** holds the url for the logging configuration */ protected String loggingURL; /** Constructor that sets the base logging context for a resource. The logger that is passed in is established by Domain base classes: Resource, Device, and Service, to maintain backwards compatablity. The logger name for Java logging resources will evalute to the actual class name of the resource. */ public Logging ( Logger establishedLogger, String logName ) { if ( establishedLogger != null ) { // retain handle to underlying classes logger so we can configure // as needed _logger = establishedLogger; } else { _logger = Logger.getLogger(logName); } this.logName=logName; this.logLevel=CF.LogLevels.INFO; this.logConfig =""; this.logListener=null; this.loggingCtx = null; this.loggingURL = null; this.loggingMacros=logging.GetDefaultMacros(); logging.ResolveHostInfo( this.loggingMacros ); } /////////////////////////////////////////////////////////////////////// // // Logging Configuration Section // /////////////////////////////////////////////////////////////////////// /** * setNewLoggingListener * * Assign callback listeners for log level changes and log configuration * changes * * @param Resource.LoggingListener callback interface definition * */ public void setNewLoggingListener( ConfigurationChangeListener newListener ) { this.logListener = newListener; } /** * getLogger * * @returns Logger return the logger assigned to this resource */ public Logger getLogger() { return _logger; } /** * getLogger * * return the logger assigned to this resource * @param String name of logger to retrieve * @param boolan true, will reassign new logger to the resource, false do not assign * @returns Logger return the named logger */ public Logger getLogger( String logid, boolean assignToResource ) { Logger log =null; if ( logid != null ) { log = Logger.getLogger( logid ); } if ( assignToResource && log != null ) { _logger = log; } return log; } /** * setLogger * * Override the default resource logger and name.. * * @param logging.Logger logger to use * @param String name of the logger */ public void setLogger( Logger logger, String logName ) { if ( logger != null ) { // retain handle to underlying classes logger so we can configure // as needed _logger = logger; } else { _logger = Logger.getLogger(logName); } this.logName=logName; } /** * setLoggingMacros * * Use the logging resource context class to set any logging macro definitions. * * @param logging.Resource a content class from the logging.ResourceCtx tree */ public void setLoggingMacros( logging.MacroTable newTbl, boolean applyCtx ) { if ( newTbl != null ) { this.loggingMacros = newTbl; this.loggingCtx.apply( this.loggingMacros ); } } /** * setResourceContext * * Use the logging resource context class to set any logging macro definitions. * * @param logging.Resource a content class from the logging.ResourceCtx tree */ public void setResourceContext( logging.ResourceCtx ctx ) { if ( ctx != null ) { ctx.apply( this.loggingMacros ); this.loggingCtx = ctx; } } /** * setLoggingContext * * Set the logging configuration and logging level for this resource * * @param logging.Resource a content class from the logging.ResourceCtx tree */ public void setLoggingContext( logging.ResourceCtx ctx ) { // apply any context data if ( ctx != null ) { ctx.apply( this.loggingMacros ); this.loggingCtx = ctx; } else if ( this.loggingCtx != null ) { this.loggingCtx.apply( this.loggingMacros ); } // call setLogConfigURL to load configuration and set log4j if ( this.loggingURL != null ) { setLogConfigURL( this.loggingURL ); } try { // set log level for this logger setLogLevel( this.logName, this.logLevel ); } catch( Exception e ){ } } /** * saveLoggingContext * * Set the logging configuration and logging level for this resource. This original * configuration context for log4j is applied to the library before a Domain resource * is actually constructed. * * The logging configuration information is retained by this class for the underlying * Domain resource. Additionaly, the EventChannelManager accessible via the Domain * can now be used by the RH_LogEventAppender. * * * @param String URL of the logging configuration file to load * @param int oldstyle_loglevel used from command line startup of a resource * @param logging.Resource a content class from the logging.ResourceCtx tree */ public void saveLoggingContext( String logcfg_url, int oldstyle_loglevel, logging.ResourceCtx ctx, org.ossie.events.Manager ECM ) { // apply any context data if ( ctx != null ) { ctx.apply( this.loggingMacros ); this.loggingCtx = ctx; } // save off configuration that we are given try{ this.loggingURL = logcfg_url; if ( logcfg_url == null || logcfg_url == "" ) { this.logConfig= logging.GetDefaultConfig(); } else { String cfg_data=""; cfg_data = logging.GetConfigFileContents(logcfg_url); if ( cfg_data.length() > 0 ){ // process file with macro expansion.... this.logConfig = logging.ExpandMacros(cfg_data, loggingMacros ); } else { _logger.warn( "URL contents could not be resolved, url: " + logcfg_url ); } } } catch( Exception e ){ _logger.warn( "Exception caught during logging configuration using URL, url: "+ logcfg_url ); } if ( oldstyle_loglevel > -1 ) { logLevel = logging.ConvertLogLevel(oldstyle_loglevel); try { if ( _logger != null ) { _logger.setLevel( logging.ConvertLogLevelToLog4(oldstyle_loglevel) ); } else { setLogLevel( logName, logging.ConvertLogLevel(oldstyle_loglevel) ); } } catch( Exception e ){ } } else { // grab root logger's level logLevel = logging.ConvertLog4ToCFLevel( Logger.getRootLogger().getLevel() ); } // attach this resource to any special appenders that require access to domain resources // set the resource context for the logging library to use // for event channel appenders... needs to occur after // Domain awareness is established logging.SetEventChannelManager( ECM ); } public void setEventChannelManager( org.ossie.events.Manager ECM ) { logging.SetEventChannelManager( ECM ); } /** * setLoggingContext * * Set the logging configuration and logging level for this resource. * * @param String URL of the logging configuration file to load * @param int oldstyle_loglevel used from command line startup of a resource * @param logging.Resource a content class from the logging.ResourceCtx tree */ public void setLoggingContext( String logcfg_url, int oldstyle_loglevel, logging.ResourceCtx ctx ) { // test we have a logging URI if ( logcfg_url == null || logcfg_url == "" ) { logging.ConfigureDefault(); } else { // apply any context data if ( ctx != null ) { ctx.apply( this.loggingMacros ); this.loggingCtx = ctx; } // call setLogConfigURL to load configuration and set log4j if ( logcfg_url != null ) { setLogConfigURL( logcfg_url ); } } try { if ( oldstyle_loglevel > -1 ) { // set log level for this logger setLogLevel( logName, logging.ConvertLogLevel(oldstyle_loglevel) ); } else { // grab root logger's level logLevel = logging.ConvertLog4ToCFLevel( Logger.getRootLogger().getLevel() ); } } catch( Exception e ){ } } ////////////////////////////////////////////////////////////////////////////// // // LogConfiguration IDL Support // ////////////////////////////////////////////////////////////////////////////// /** * log_level * * Return the current logging level as defined by the Logging Interface IDL * * @return int value of a CF::LogLevels enumeration */ public int log_level() { if ( _logger != null ) { Level logger_level = _logger.getLevel(); Level cur_loglevel= logging.ConvertToLog4Level(logLevel); if ( logger_level != null && logger_level != cur_loglevel ) { logLevel = logging.ConvertLog4ToCFLevel(logger_level); } } return logLevel; } /** * log_level * * Set the logging level for the logger assigned to the resource. If a callback listener * is assigned to the resource then invoke the listener to handle the assignment * * @param int value of a CF::LogLevels enumeration */ public void log_level( int newLogLevel ) { if ( this.logListener != null ) { logLevel = newLogLevel; this.logListener.logLevelChanged( logName, newLogLevel ); } else { logLevel = newLogLevel; Level tlevel= logging.ConvertToLog4Level(newLogLevel); if ( _logger != null ) { _logger.setLevel(tlevel); } else { Logger.getRootLogger().setLevel(tlevel); } } } /** * setLogLevel * * Set the logging level for a named logger associated with this resource. If a callback listener * is assigned to the resource then invoke the listener to handle the assignment * * @param int value of a CF::LogLevels enumeration */ public void setLogLevel( String logger_id, int newLogLevel ) throws UnknownIdentifier { if ( this.logListener != null ) { if ( logger_id == logName ){ this.logLevel = newLogLevel; } this.logListener.logLevelChanged( logger_id, newLogLevel ); } else { Level tlevel=Level.INFO; tlevel = logging.ConvertToLog4Level(newLogLevel); if ( logger_id != null ){ Logger logger = Logger.getLogger( logger_id ); if ( logger != null ) { logger.setLevel( tlevel ); if ( logger_id == logName ) { logLevel=newLogLevel; } } } else { Logger.getRootLogger().setLevel(tlevel); } } } /** * getLogConfig * * return the logging configration information used to configure the log4j library * * @returns String contents of the configuration file */ public String getLogConfig() { return logConfig; } /** * setLogConfig * * Process the config_contents param as the contents for the log4j configuration * information. * * First, run the configuration information against the current macro defintion * list and then assigned that data to the log4j library. If this operation * completed sucessfully, the new configuration is saved. * * * @param String contents of the configuration file */ public void setLogConfig( String config_contents ) { if ( this.logListener != null ) { String lcfg = logging.ExpandMacros( config_contents, loggingMacros ); this.logListener.logConfigChanged( lcfg ); this.logConfig = lcfg; } else { try { String newcfg=""; newcfg = logging.Configure( config_contents, loggingMacros ); this.logConfig = newcfg; } catch( Exception e ) { _logger.warn("setLogConfig failed, reason:" + e.getMessage() ); } } } /** * setLogConfig * * Use the config_url value to read in the contents of the file as the new log4j * configuration context. If the file is sucessfully loaded then setLogConfig * is called to finish the processing. * * @param String URL of file to load */ public void setLogConfigURL( String config_url ) { // // Get File contents.... // try{ String config_contents=""; config_contents = logging.GetConfigFileContents(config_url); if ( config_contents.length() > 0 ){ this.loggingURL = config_url; // apply contents of file to configuration this.setLogConfig( config_contents ); } else { _logger.warn( "URL contents could not be resolved, url: " + config_url ); } } catch( Exception e ){ _logger.warn( "Exception caught during logging configuration using URL, url: "+ config_url ); } } ////////////////////////////////////////////////////////////////////////////// // // LogEventConsumer IDL Support // ////////////////////////////////////////////////////////////////////////////// public CF.LogEvent[] retrieve_records( org.omg.CORBA.IntHolder howMany, int startingPoint ) { howMany=new org.omg.CORBA.IntHolder(0); CF.LogEvent[] seq = new CF.LogEvent[0]; return seq; } public CF.LogEvent[] retrieve_records_by_date( org.omg.CORBA.IntHolder howMany, long to_timeStamp ) { howMany=new org.omg.CORBA.IntHolder(0); CF.LogEvent[] seq = new CF.LogEvent[0]; return seq; } public CF.LogEvent[] retrieve_records_from_date( org.omg.CORBA.IntHolder howMany, long from_timeStamp ) { howMany=new org.omg.CORBA.IntHolder(0); CF.LogEvent[] seq = new CF.LogEvent[0]; return seq; } }