FileDocCategorySizeDatePackage
LoggingEvent.javaAPI DocApache log4j 1.2.1518447Sat Aug 25 00:09:40 BST 2007org.apache.log4j.spi

LoggingEvent

public class LoggingEvent extends Object implements Serializable
The internal representation of logging events. When an affirmative decision is made to log then a LoggingEvent instance is created. This instance is passed around to the different log4j components.

This class is of concern to those wishing to extend log4j.

author
Ceki Gülcü
author
James P. Cakalic
since
0.8.2

Fields Summary
private static long
startTime
public final transient String
fqnOfCategoryClass
Fully qualified name of the calling category class.
private transient Category
logger
The category of the logging event. This field is not serialized for performance reasons.

It is set by the LoggingEvent constructor or set by a remote entity after deserialization.

public final String
categoryName

The category (logger) name.

public transient Priority
level
Level of logging event. Level cannot be serializable because it is a flyweight. Due to its special seralization it cannot be declared final either.

This field should not be accessed directly. You shoud use the {@link #getLevel} method instead.

private String
ndc
The nested diagnostic context (NDC) of logging event.
private Hashtable
mdcCopy
The mapped diagnostic context (MDC) of logging event.
private boolean
ndcLookupRequired
Have we tried to do an NDC lookup? If we did, there is no need to do it again. Note that its value is always false when serialized. Thus, a receiving SocketNode will never use it's own (incorrect) NDC. See also writeObject method.
private boolean
mdcCopyLookupRequired
Have we tried to do an MDC lookup? If we did, there is no need to do it again. Note that its value is always false when serialized. See also the getMDC and getMDCCopy methods.
private transient Object
message
The application supplied message of logging event.
private String
renderedMessage
The application supplied message rendered through the log4j objet rendering mechanism.
private String
threadName
The name of thread in which this logging event was generated.
private ThrowableInformation
throwableInfo
This variable contains information about this event's throwable
public final long
timeStamp
The number of milliseconds elapsed from 1/1/1970 until logging event was created.
private LocationInfo
locationInfo
Location information for the caller.
static final long
serialVersionUID
static final Integer[]
PARAM_ARRAY
static final String
TO_LEVEL
static final Class[]
TO_LEVEL_PARAMS
static final Hashtable
methodCache
Constructors Summary
public LoggingEvent(String fqnOfCategoryClass, Category logger, Priority level, Object message, Throwable throwable)
Instantiate a LoggingEvent from the supplied parameters.

Except {@link #timeStamp} all the other fields of LoggingEvent are filled when actually needed.

param
logger The logger generating this event.
param
level The level of this event.
param
message The message of this event.
param
throwable The throwable of this event.

 // use a tiny table

                                                                                       
      
		            
    this.fqnOfCategoryClass = fqnOfCategoryClass;
    this.logger = logger;
    this.categoryName = logger.getName();
    this.level = level;
    this.message = message;
    if(throwable != null) {
      this.throwableInfo = new ThrowableInformation(throwable);
    }
    timeStamp = System.currentTimeMillis();
  
public LoggingEvent(String fqnOfCategoryClass, Category logger, long timeStamp, Priority level, Object message, Throwable throwable)
Instantiate a LoggingEvent from the supplied parameters.

Except {@link #timeStamp} all the other fields of LoggingEvent are filled when actually needed.

param
logger The logger generating this event.
param
timeStamp the timestamp of this logging event
param
level The level of this event.
param
message The message of this event.
param
throwable The throwable of this event.

    this.fqnOfCategoryClass = fqnOfCategoryClass;
    this.logger = logger;
    this.categoryName = logger.getName();
    this.level = level;
    this.message = message;
    if(throwable != null) {
      this.throwableInfo = new ThrowableInformation(throwable);
    }

    this.timeStamp = timeStamp;
  
public LoggingEvent(String fqnOfCategoryClass, Category logger, long timeStamp, Level level, Object message, String threadName, ThrowableInformation throwable, String ndc, LocationInfo info, Map properties)
Create new instance.

since
1.2.15
param
fqnOfCategoryClass Fully qualified class name of Logger implementation.
param
logger The logger generating this event.
param
timeStamp the timestamp of this logging event
param
level The level of this event.
param
message The message of this event.
param
threadName thread name
param
throwable The throwable of this event.
param
ndc Nested diagnostic context
param
info Location info
param
properties MDC properties

      super();
      this.fqnOfCategoryClass = fqnOfCategoryClass;
      this.logger = logger;
      if (logger != null) {
          categoryName = logger.getName();
      } else {
          categoryName = null;
      }
      this.level = level;
      this.message = message;
      if(throwable != null) {
        this.throwableInfo = throwable;
      }

      this.timeStamp = timeStamp;
      this.threadName = threadName;
      ndcLookupRequired = false;
      this.ndc = ndc;
      this.locationInfo = info;
      mdcCopyLookupRequired = false;
      if (properties != null) {
        mdcCopy = new java.util.Hashtable(properties);
      }
    
Methods Summary
public java.lang.StringgetFQNOfLoggerClass()
Get the fully qualified name of the calling logger sub-class/wrapper. Provided for compatibility with log4j 1.3

return
fully qualified class name, may be null.
since
1.2.15

      return fqnOfCategoryClass;
    
public org.apache.log4j.LevelgetLevel()
Return the level of this event. Use this form instead of directly accessing the level field.

    return (Level) level;
  
public org.apache.log4j.spi.LocationInfogetLocationInformation()
Set the location information for this logging event. The collected information is cached for future use.

    if(locationInfo == null) {
      locationInfo = new LocationInfo(new Throwable(), fqnOfCategoryClass);
    }
    return locationInfo;
  
public org.apache.log4j.CategorygetLogger()
Gets the logger of the event. Use should be restricted to cloning events.

since
1.2.15

      return logger;
    
public java.lang.StringgetLoggerName()
Return the name of the logger. Use this form instead of directly accessing the categoryName field.

    return categoryName;
  
public java.lang.ObjectgetMDC(java.lang.String key)
Returns the the context corresponding to the key parameter. If there is a local MDC copy, possibly because we are in a logging server or running inside AsyncAppender, then we search for the key in MDC copy, if a value is found it is returned. Otherwise, if the search in MDC copy returns a null result, then the current thread's MDC is used.

Note that both the local MDC copy and the current thread's MDC are searched.

    Object r;
    // Note the mdcCopy is used if it exists. Otherwise we use the MDC
    // that is associated with the thread.
    if(mdcCopy != null) {
      r = mdcCopy.get(key);
      if(r != null) {
        return r;
      }
    }
    return MDC.get(key);
  
public voidgetMDCCopy()
Obtain a copy of this thread's MDC prior to serialization or asynchronous logging.

    if(mdcCopyLookupRequired) {
      mdcCopyLookupRequired = false;
      // the clone call is required for asynchronous logging.
      // See also bug #5932.
      Hashtable t = (Hashtable) MDC.getContext();
      if(t != null) {
	mdcCopy = (Hashtable) t.clone();
      }
    }
  
public java.lang.ObjectgetMessage()
Return the message for this logging event.

Before serialization, the returned object is the message passed by the user to generate the logging event. After serialization, the returned value equals the String form of the message possibly after object rendering.

since
1.1

    if(message != null) {
      return message;
    } else {
      return getRenderedMessage();
    }
  
public java.lang.StringgetNDC()
This method returns the NDC for this event. It will return the correct content even if the event was generated in a different thread or even on a different machine. The {@link NDC#get} method should never be called directly.

    if(ndcLookupRequired) {
      ndcLookupRequired = false;
      ndc = NDC.get();
    }
    return ndc;
  
public java.util.MapgetProperties()
Returns the set of properties for the event. The returned set is unmodifiable by the caller. Provided for compatibility with log4j 1.3

return
Set an unmodifiable map of the properties.
since
1.2.15

      getMDCCopy();
      Map properties;
      if (mdcCopy == null) {
         properties = new HashMap();
      } else {
         properties = mdcCopy;
      }
      return Collections.unmodifiableMap(properties);
    
public final java.lang.StringgetProperty(java.lang.String key)
Return a property for this event. The return value can be null. Equivalent to getMDC(String) in log4j 1.2. Provided for compatibility with log4j 1.3.

param
key property name
return
property value or null if property not set
since
1.2.15

        Object value = getMDC(key);
        String retval = null;
        if (value != null) {
            retval = value.toString();
        }
        return retval;
    
public java.util.SetgetPropertyKeySet()
Returns the set of the key values in the properties for the event. The returned set is unmodifiable by the caller. Provided for compatibility with log4j 1.3

return
Set an unmodifiable set of the property keys.
since
1.2.15

      return getProperties().keySet();
    
public java.lang.StringgetRenderedMessage()

     if(renderedMessage == null && message != null) {
       if(message instanceof String)
	 renderedMessage = (String) message;
       else {
	 LoggerRepository repository = logger.getLoggerRepository();

	 if(repository instanceof RendererSupport) {
	   RendererSupport rs = (RendererSupport) repository;
	   renderedMessage= rs.getRendererMap().findAndRender(message);
	 } else {
	   renderedMessage = message.toString();
	 }
       }
     }
     return renderedMessage;
  
public static longgetStartTime()
Returns the time when the application started, in milliseconds elapsed since 01.01.1970.

    return startTime;
  
public java.lang.StringgetThreadName()

    if(threadName == null)
      threadName = (Thread.currentThread()).getName();
    return threadName;
  
public org.apache.log4j.spi.ThrowableInformationgetThrowableInformation()
Returns the throwable information contained within this event. May be null if there is no such information.

Note that the {@link Throwable} object contained within a {@link ThrowableInformation} does not survive serialization.

since
1.1

    return throwableInfo;
  
public java.lang.String[]getThrowableStrRep()
Return this event's throwable's string[] representaion.


    if(throwableInfo ==  null)
      return null;
    else
      return throwableInfo.getThrowableStrRep();
  
public final longgetTimeStamp()
Getter for the event's time stamp. The time stamp is calculated starting from 1970-01-01 GMT.

return
timestamp
since
1.2.15

      return timeStamp;
    
public final booleanlocationInformationExists()
Check for the existence of location information without creating it (a byproduct of calling getLocationInformation).

return
true if location information has been extracted.
since
1.2.15

      return (locationInfo != null);
    
private voidreadLevel(java.io.ObjectInputStream ois)


    int p = ois.readInt();
    try {
      String className = (String) ois.readObject();
      if(className == null) {
	level = Level.toLevel(p);
      } else {
	Method m = (Method) methodCache.get(className);
	if(m == null) {
	  Class clazz = Loader.loadClass(className);
	  // Note that we use Class.getDeclaredMethod instead of
	  // Class.getMethod. This assumes that the Level subclass
	  // implements the toLevel(int) method which is a
	  // requirement. Actually, it does not make sense for Level
	  // subclasses NOT to implement this method. Also note that
	  // only Level can be subclassed and not Priority.
	  m = clazz.getDeclaredMethod(TO_LEVEL, TO_LEVEL_PARAMS);
	  methodCache.put(className, m);
	}
	PARAM_ARRAY[0] = new Integer(p);
	level = (Level) m.invoke(null,  PARAM_ARRAY);
      }
    } catch(Exception e) {
	LogLog.warn("Level deserialization failed, reverting to default.", e);
	level = Level.toLevel(p);
    }
  
private voidreadObject(java.io.ObjectInputStream ois)

    ois.defaultReadObject();
    readLevel(ois);

    // Make sure that no location info is available to Layouts
    if(locationInfo == null)
      locationInfo = new LocationInfo(null, null);
  
public final voidsetProperty(java.lang.String propName, java.lang.String propValue)
Set value for MDC property. This adds the specified MDC property to the event. Access to the MDC is not synchronized, so this method should only be called when it is known that no other threads are accessing the MDC.

since
1.2.15
param
propName
param
propValue

        if (mdcCopy == null) {
            getMDCCopy();
        }
        if (mdcCopy == null) {
            mdcCopy = new Hashtable();
        }
        mdcCopy.put(propName, propValue);      
  
private voidwriteLevel(java.io.ObjectOutputStream oos)


    oos.writeInt(level.toInt());

    Class clazz = level.getClass();
    if(clazz == Level.class) {
      oos.writeObject(null);
    } else {
      // writing directly the Class object would be nicer, except that
      // serialized a Class object can not be read back by JDK
      // 1.1.x. We have to resort to this hack instead.
      oos.writeObject(clazz.getName());
    }
  
private voidwriteObject(java.io.ObjectOutputStream oos)

    // Aside from returning the current thread name the wgetThreadName
    // method sets the threadName variable.
    this.getThreadName();

    // This sets the renders the message in case it wasn't up to now.
    this.getRenderedMessage();

    // This call has a side effect of setting this.ndc and
    // setting ndcLookupRequired to false if not already false.
    this.getNDC();

    // This call has a side effect of setting this.mdcCopy and
    // setting mdcLookupRequired to false if not already false.
    this.getMDCCopy();

    // This sets the throwable sting representation of the event throwable.
    this.getThrowableStrRep();

    oos.defaultWriteObject();

    // serialize this event's level
    writeLevel(oos);