Вот как я это делаю. Внутренний класс инкапсулирует экземпляр синглтона регистратора и его метод трассировки (хе-хе - я знаю - синглтон внутри синглтона). Внешний класс использует его, только если специальный класс может быть загружен, в противном случае мы продолжаем без него. Надеюсь, вы можете изменить это в соответствии с вашими потребностями. И любые предложения по улучшению кода всегда приветствуются! :-) HTH
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Provides centralized access to standardized output formatting. Output is sent to System.out and,
* if the classpath allows it, to the Cisco CTIOS LogManager. (This is NOT a dependency, however.)
*
*/
public class LogWriter
{
protected static LogWriter me = null;
private SimpleDateFormat dateFormat = null;
private StringBuffer line = null;
CLogger ciscoLogger = null;
/*
* The following 2 methods constitute the thread-safe singleton pattern.
*/
private static class LogWriterHolder
{
public static LogWriter me = new LogWriter();
}
/**
* Returns singleton instance of the class. Thread-safe. The only way to get one is to use this.
*
* @return an instance of LogWriter
*/
public static LogWriter sharedInstance()
{
return LogWriterHolder.me;
}
@SuppressWarnings("unchecked")
LogWriter()
{
dateFormat = new SimpleDateFormat("yyyyMMddHHmmss ");
line = new StringBuffer();
try {
Class x = Class.forName("com.cisco.cti.ctios.util.LogManager");
if( x != null ) {
java.lang.reflect.Method m = x.getMethod("Instance", new Class[0]);
java.lang.reflect.Method n = x.getMethod("Trace", int.class, String.class );
if( m != null ) {
Object y = m.invoke( x , new Object[0] );
if( n != null ) {
ciscoLogger = new CLogger();
ciscoLogger.target = y;
ciscoLogger.traceImpl = n ;
}
}
}
} catch(Throwable e )
{
System.err.println( e.getMessage() ) ;
e.printStackTrace();
}
}
/**
* Formats a line and sends to System.out. The collection and formatting of the text is
* thread safe.
*
* @param message The human message you want to display in the log (required).
* @param hostAddress Host address of server (optional)
* @param hostPort Port on hostAddresss (optional) - also used for className in object-specific logs.
*/
public void log( String message, String hostAddress, String hostPort )
{
if ( message == null || message.length() < 3 ) return;
synchronized( this )
{
try {
line.delete(0, line.length());
line.append(dateFormat.format(new Date()));
line.append(hostAddress);
line.append(":");
line.append(hostPort);
line.append(" ");
while (line.length() < 28)
line.append(" ");
line.append(message);
this.write( line.toString() );
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void write(String line )
{
System.out.println( line ) ;
}
/**
* Write a simple log message to output delegates (default is System.out).
* <p>
* Will prepend each line with date in yyyyMMddHHmmss format. there will be a big space
* after the date, in the spot where host and port are normally written, when {@link LogWriter#log(String, String, String) log(String,String,String)}
* is used.
*
* @param message What you want to record in the log.
*/
public void log( String message )
{
if( ciscoLogger != null ) ciscoLogger.trace(0x01, message );
this.log( message, "", "");
}
class CLogger
{
Object target;
Method traceImpl;
@SuppressWarnings("boxing")
public void trace( int x, String y )
{
try {
traceImpl.invoke( target, x, y) ;
} catch( Throwable e ) {
// nothing to say about this
}
}
}
}