Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

This design will cover the following areas:
Contents

Table of Contents
minLevel3
maxLevel3

Additional Documentation

Logging Configuration

At this stage configuration will be limited to the addtion addition to the main config.xml file of the following option:

...

In the first phase updates only stauts status updates will be provided. Status updates should take the form of general operational logging level, no logging on message delivery path way and No performance impact. The recommendation will be to have these enabled for production use.
e.g. Creation/Destruction events

...

The approach to logging is that each Entitiy a LogActor will be recoreded as a ThreadLocal and will be used to perform logging the log messages as highlighted on Logging Format Design would provide an implementation of MessageStatusLogger. This logger would be obtained from the MessagesStatusLoggerFactory during the constuction of the entity. The LogActor will take two parameters, the LogSubject and the LogMessage. When a Status event occured occurs that should be logged a LogActor is requried to request the loggingthe LogActor can be retrieved from the thread thus avoiding passing the LogActor through as a parameter to all locations were it must be logged. The initial LogActors would will be Connection, Channel AMQPActor and Subscription ManagementActor. Later phases would introduce VirtualHost and ManagementConnection. These Actors will initially only be used to provide their log formated HouseKeepingActor. These LogActors are responsible for checking that the logging should be performed for both themselves and the LogSubject. The LogActor then provids their log formatted name as per the format design. However, later their along with the message to the RootMessageLogger. Initially the configuration will be a simple on/off, however, in a future phase the details can be used to identify if logging should procced proceed for that Actor LogActor and Entity LogSubject combination. At this stage selective configurations is not part of this design.

...

The use of the LogActor allows for situations such as Binding to have a Connection associated with the Binding. This will allow a Binding create event to be logged like this:

No Format

2009-06-29 13:35:10,1234 +0100 MESSAGE [con:1(guest@127.0.0.1/)/ch:2] [ex(amq.direct)/qu(testQueue)/bd(routingKey)] BND-1001 : Binding Created

rather having no details about how the creation occurred:

No Format

2009-06-29 13:35:10,1234 +0100 MESSAGE [ vh(/)/ex(amq.direct)/qu(testQueue)/bd(routingKey) ] BDN-1001 : Create

Interfaces

...

Code Block
java
java
titleMessageStatusLoggerLogActor
/**
 * MessageLogActor Status messages are logged via this interface.
 *
 * Each Entitythe entity that wishes to be logged will implement this to provide their
 * own display representation.
 *
 * The MSLogger will be created by a Factory {@see MessageStatusLoggerFactory}.
 *
 * Currently logging has a global setting however this will later be revised and
 * as such the LogActor will need to be taken in to consideration as well as the
 * status of this Logger.
 *
 * A detailed and published list of messages that will be logged will be
 * provided so that monitoring systems can know what to expect.
 */
public interface MessageStatusLogger
{

    /**
     * This method should be used as a guard against expensive message
     * construction prior to calling message().
     *
     * It should not be called if there is no construction required.
     *
     * This will perform validation that the log message should be performed
     * based on the provided Actor and the Entity this Logger represents.
     * This may be done via delegation to the RootMessageStatusLogger.
     *
     * @param actor The actor that is requesting to perform logging
     *
     * @return if this log message should take place
     */
    public boolean isMessageEnabled(LogActor actor);
is stored as in a ThreadLocal and used to perform logging.
 *
 * The actor is responsible for formatting its display name for the log entry.
 * 
 * The actor performs the requested logging.
 */
public interface LogActor
{
    /**
     * Logs the messagespecified asLogMessage providedabout by String.valueOf(message).the LogSubject
     *
     * The call to message() will first check if #isMessageEnabled() allows
     * the logging to be performed. This means for simple messages it is not
     * necessary to guard this call with isMessageEnabled() as it will be called
     * internally.Currently logging has a global setting however this will later be revised and
     *
     * If any complex construction is requried then it MUST BE guarded so that
     * the log message is not needlessly generated.
     *
     * @param actor   The actor that is requesting the logging
     * @param message The message to log
     */
    public void message(LogActor actor, Object message);

    /**
     * Logs the message as provided by String.valueOf(message).
     *
     * The call to message() will first check if #isMessageEnabled() allows
     * the logging to be performed. This means for simple messages it is notas such the LogActor will need to take into consideration any new configuration 
     * necessary to guard this call with isMessageEnabled() as ita willmeans be called
     * internally.
     *
     * If any complex construction is requried then it MUST BE guarded so that
     * the log message is not needlessly generated.
     *
     * If the provided Throwable is non-null then the stack trace will also be
     * loggedof enabling the logging of LogActors and LogSubjects.
     *
     * @param actor   The actor that is requesting the logging
     * @param message The message to log
     * @param throwable The throwable that should be used to generate a trace.
     */
    public void message(LogActorLogSubject actorsubject, ObjectLogMessage message, Throwable throwable);
}

Code Block
java
java
titleMessageStatusLoggerFactoryLogSubject
/**
 * ThisEach interfaceLogSubject providesthat awishes meansto ofbe creating the Loggers that logged will be required
 * by each of the entities that have a desire implement this to provide status updates.their
 *
 *own For new entities to support status logging this interface must be updateddisplay representation.
 * 
 * AllThe Loggersdisplay deferrepresentation tois theretrieved RootMessageStatusLogger as to wither through the log should
 * take placetoString() method.
 */
public interface MessageStatusLoggerFactoryLogSubject
{
    public ConnectionMessageStatusLogger createConnectionMessageStatusLogger(AMQProtocolSession connection);

    public ChannelMessageStatusLogger createChannelMessageStatusLogger(AMQChannel channel);

/**
     * Logs the message as provided by String.valueOf(message).
    public QueueMessageStatusLogger createQueueMessageStatusLogger(AMQQueue queue);

 *
    public ExchangeMessageStatusLogger* createExchangeMessageStatusLogger(Exchange exchange);

    public BindingMessageStatusLogger createBindingMessageStatusLogger(ExchangeBinding binding);

    public SubscriptionMessageStatusLogger createSubscriptionMessageStatusLogger(Subscription subscription);

@returns String the display representation of this LogSubject
     */
    public MessageStoreMessageStatusLoggerString createMessageStoreMessageStatusLoggertoString(MessageStore store);
}

Code Block
java
java
titleRootMessageStatusLoggerRootMessageLogger
/**
 * The RootMessageStatusLoggerRootMessageLogger is used by the MessageStatusLoggersLogActors to query if
 * logging is enabled for the requested message and to provide the actual
 * message that should be logged.
 */
public interface RootMessageStatusLoggerRootMessageLogger
{
    /**
     * DeterminDetermine if the MessageStatusLoggerLogSubject and the LogActor should be
     * generating log messages.
     *
     * @param messageStatusLoggerlogSubject The subject loggerof performingthis thelog loggingrequest
     * @param actor        logActor       The actor requesting the logging
     * @return boolean true if the message should be logged.
     */
    boolean isMessageEnabled(MessageStatusLoggerLogActor messageStatusLoggeractor,
                             LogActor actorLogSubject subject);

    /**
     * Log the raw message to the configured logger.
     *
     * @param message   The message to log
     * @param throwable Optional Throwable that should provide stact trace
     */
    void rawMessage(String message, Throwable throwable);

    /**
     * Accessor to get the MSLFactory that can then be used to perform logging 
     * @return MessageStatusLoggerFactory 
     */
    MessageStatusLoggerFactory getMessageStatusLoggerFactory();
}

Code Block
java
java
titleRawMessageLogger
/**
 * A RawMessage Logger takes the given String and any Throwable and writes the
 * data to its resouceresource.
 */
public interface RawMessageLogger
{
    /**
     * Log the message and formatted stack trace for any Throwable.
     *
     * @param message   String to log.
     * @param throwable Throwable for which to provide stack trace.
     */
    public void rawMessage(String message, Throwable throwable);
}

The addition of the ability to set a creator allows for situations such as Binding to have a Connection associated with the Binding. This will allow a Binding create event to be logged like this:

No Format

2009-06-29 13:35:10,1234 +0100 INFO [ con:1(guest@127.0.0.1/)/ch:2/ex(amq.direct)/qu(testQueue)/bd(routingKey) ] Created Binding

rather having no details about how the creation occured:

No Format

2009-06-29 13:35:10,1234 +0100 INFO [ vh(/)/ex(amq.direct)/qu(testQueue)/bd(routingKey) ] Created Binding

Logging Usage

Code Block
java
java
titleLogging by of a LogEntityChannel Creation
pubic class SubscriptionConnection
...
   LogActor amqpActor = // retrieved iffrom (_statusLogger.isInfoEnabled(this))ThreadLocal.
    {
        _statusLogger.info(this, "Subscription Event occured.");
    }//_channelSubject is an instance LogSubject that knows how to represent this Connection
   amqpActor.logMessage(_connectionSubject, LogMessages.CHANNEL_CREATE(this));

...

Would result in the following based on the Logging Format Design.

No Format
2009-06-29 13:35:10,1234 +0100 INFOMESSAGE [ con:1(guest@127.0.0.1/)/] [ch:2/sub:1:qu(myqueue) ] Subscription Event occcured.] ChM-1001 : Channel Created
Code Block
java
java
titleLogging of a newly created LogEntity via connectionnew consumer creation
...
    binding = new ExchangeBinding(...);
    ((LogEntity)binding).setCreator(connection);
... 
// Verify binding can be performed/created
...
    if (_statusLogger.isInfoEnabled(binding))
    {
        _statusLogger.info(binding, "Created");
    }amqpActor.logMessage(_subsriptionSubject, LogMessages.SUBSCRIPTION_CREATE(this));
...

Would result in the following:

No Format
2009-06-29 13:35:10,1234 +0100 INFOMESSAGE [ con:1(guest@127.0.0.1/)/ch:2/pl(ACL, Consume, qu(myQueue)) ] Plugin Event occured for this. ] [sub:1:qu(myqueue)] Sub-1001 : Subscription Created

Initial Status Messages

Broker

...