# Operational Logging

Apache Software Foundation

## Status Log Messages

This file was derivied from LogMessages used within the Java Broker and originally defined on: Apache Wiki

### Technical Notes:

The status log messages file is a standard Java Properties file so white space is respected at the end of the lines. This file could be processed in a number of ways:

1. ResourceBundle

   This file is loaded as a ResourceBundle. The en_US addition to the file is the localisation. Additional localisations can be provided and will automatically be selected based on the <locale> value in the config.xml. The default locale is en_US.

2. MessageFormat

   Each entry is prepared with the Java Core MessageFormat methods. Therefore most functionality you can do via MessageFormat can be done here:

   Java API for MessageFormat

   The caveat here is that only default String and number FormatTypes can be used. This is due to the processing described in 3 below. If support for date, time or choice is required then the GenerateLogMessages class should be updated to provide support.

3. GenerateLogMessage/Velocity Macro

   This is the only processing that this file goes through

   1. Class Generation:

      The GenerateLogMessage processes this file and uses the velocity Macro to create classes with static methods to perform the logging and give us compile time validation.

   2. Property Processing

      During the class generation the message properties ({x}) are identified and used to create the method signature.

   3. Option Processing

      The Classes perform final formatting of the messages at runtime based on optional parameters that are defined within the message. Optional parameters are enclosed in square brackets e.g. [optional].

Format Note:

As mentioned earlier white space in this file is very important. One thing in particular to note is the way MessageFormat performs its replacements. The replacement text will totally replace the {xxx} section so there will be no addition of white space or removal e.g.

    MSG = Text----{0}----

When given parameter 'Hello' result in text:

    Text----Hello----

For simple arguments this is expected however when using Style formats then it can be a little unexpected. In particular a common pattern is used for number replacements : {0,number,}. This is used in the Broker to display an Integer simply as the Integer with no formatting. e.g new Integer(1234567) becomes the String "1234567" which is can be contrasted with the pattern without a style format field : {0,number} which becomes string "1,234,567".

What you may not expect is that {0,number, } would produce the String " 1234567" note that the space after the ',' here has resulted in a space in front of the number in the output.

More details on the SubformatPattern can be found on the API link above. To provide fixed log messages as required by the Technical Specification:

Operational Logging Tech Specification

This file is processed by Velocity to create a number of classes that contain static methods that provide LogMessages in the code to provide compile time validation.

For details of what processing is done see GenerateLogMessages.

What a localiser or developer need know is the following:

The Property structure is important as it defines how the class and methods will be built.

### Class Generation

Each class of messages will be split in to their own <Class>Messages.java. Each logmessage file contains only one class of messages the <Class> name is derived from the name of the logmessages file e.g. <Class>_logmessages.properties.

### Property Format

The property format MUST adhere to the follow format to make it easier to use the logging API as a developer but also so that operations staff can easily locate log messages in the output.

The property file should contain entries in the following format:

    <Log Identifier,developer focused>=<Log Identifier,Operate focus>:<Log Message>

eg:

    SHUTTING_DOWN = BRK-1003 : Shutting down : {0} port {1,number,}

Note: the developer focused identifier will become a method name so only a valid method name should be used. Currently only '-' are converted to '_'.

That said properties generate the logging code at build time so any error can be easily identified.

The three character identifier show above in BRK-1003 should ideally be unique. This is the only requirement, limiting to 3 characters is not required.

The current broker contains the following mappings:

Status Messages Mapping

Class | Type
--- | ---
Broker | BRK
Management Console | MNG
VirtualHost | VHT
MessageStore | MST
ConfigStore | CFG
TransactionLog | TXN
Connection | CON
Channel | CHN
Queue | QUE
Exchange | EXH
Binding | BND
Subscription | SUB

### Property Processing

Each property is then processed by the GenerateLogMessages class to identify the number and type of parameters, {x} entries. Parameters are defaulted to String types but the use of FormatType number (e.g.{0,number}) will result in a Number type being used. These parameters are then used to build the method parameter list. e.g:

Property:

    SHUTTING_DOWN = BRK-1003 : Shutting down : {0} port {1,number,}

becomes Method:

    public static LogMessage SHUTTING_DOWN(String param1, Number param2)

This improves our compile time validation of log message content and ensures that change in the message format does not accidentally cause erroneous messages.

### Option Processing

Options are identified in the log message as being surrounded by square brackets ([ ]). These optional values can themselves contain parameters however nesting of options is not permitted. Identification is performed on first matching so given the message:

    Msg = Log Message [option1] [option2]

Two options will be identified and enabled to select text 'option1' and 'option2'.

The nesting of a options is not supported and will provide unexpected results. e.g. Using Message:

    Msg = Log Message [option1 [sub-option2]]

The options will be 'option1 [sub-option2' and 'sub-option2'. The first option includes the second option as the nesting is not detected.

The detected options are presented in the method signature as boolean options numerically identified by their position in the message. e.g. Property:

     CON-1001 = Open : Client ID {0} [: Protocol Version : {1}]

becomes Method:

     public static LogMessage CON_1001(String param1, String param2, boolean opt1)

The value of 'opt1' will show/hide the option in the message. Note that 'param2' is still required however a null value can be used if the optional section is not desired.

Again here the importance of white space needs to be highlighted. Looking at the QUE-1001 message as an example. The first thought on how this would look would be as follows:

     QUE-1001 = Create : Owner: {0} [AutoDelete] [Durable] [Transient] [Priority: {1,number,}]

Each option is correctly defined so the text that is defined will appear when selected. e.g. 'AutoDelete'. However, what may not be immediately apparent is the white space. Using the above definition of QUE-1001 if we were to print the message with only the Priority option displayed it would appear as this:

     "Create : Owner: guest    Priority: 1"

Note the spaces here in between gues and Priority are present because only the text between the brackets has been removed.

Each option needs to include white space to correctly format the message. So the correct definition of QUE-1001 is as follows:

     QUE-1001 = Create : Owner: {0}[ AutoDelete][ Durable][ Transient][ Priority: {1,number,}]

Note that white space is included with each option and there is no extra white space between the options. As a result the output with just Priority enabled is as follows:

     "Create : Owner: guest Priority: 1"