summaryrefslogtreecommitdiff
path: root/doc/book/src/Java-Broker-StatusLogMessages.xml
blob: e905f9ff10912fa59ba3ca026027a41fc9ff6d4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
<?xml version="1.0" encoding="UTF-8"?>
<!--
 
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at
 
   http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 
-->
<?oxygen RNGSchema="http://www.oasis-open.org/docbook/xml/5.0/rng/docbook.rng" type="xml"?>
<book xmlns="http://docbook.org/ns/docbook"
    xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
    <info>
        <title>Operational Logging</title>
        <author>
            <orgname>Apache Software Foundation</orgname>
        </author>        
    </info>
    <chapter>
        <title>Status Log Messages</title>
        <para>This file was derivied from LogMessages used within the Java Broker and originally defined on:
           <tag xlink:href="http://cwiki.apache.org/confluence/display/qpid/Status+Update+Design#StatusUpdateDesign-InitialStatusMessages">Apache Wiki</tag></para>
        <sect1>
            <title>Technical Notes:</title>
            <para>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:</para>
            <para>
                <orderedlist>
                    <listitem>
                        <para>ResourceBundle</para>
                        <para>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 &lt;locale> value in the
                            config.xml. The default locale is en_US.</para>
                    </listitem>
                    <listitem>
                        <para>MessageFormat</para>
                        <para> Each entry is prepared with the Java Core MessageFormat methods.
                            Therefore most functionality you can do via MessageFormat can be done
                            here: </para>
                        <para><tag xlink:href="http://java.sun.com/javase/6/docs/api/java/text/MessageFormat.html">Java API for MessageFormat</tag></para>
                        <para>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.</para>
                    </listitem>
                    <listitem>
                        <para>GenerateLogMessage/Velocity Macro</para>
                        <para>This is the only processing that this file goes through</para>
                        <orderedlist>
                            <listitem>
                                <para>Class Generation:</para>
                                <para>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. </para>
                            </listitem>
                            <listitem>
                                <para>Property Processing</para>
                                <para>During the class generation the message properties ({x}) are
                                    identified and used to create the method signature.</para>
                            </listitem>
                            <listitem>
                                <para>Option Processing</para>
                                <para>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].</para>
                            </listitem>
                        </orderedlist>
                    </listitem>
                </orderedlist>
            </para>
            <para><emphasis role="bold">Format Note:</emphasis></para>
            <para> 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. </para>
            <programlisting><![CDATA[MSG = Text----{0}----]]>
            </programlisting>            
            <para> When given parameter 'Hello' result in text: </para>
            <programlisting><![CDATA[Text----Hello----]]>
            </programlisting>
            <para>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".</para>
            <para>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.</para>
            <para>More details on the SubformatPattern can be found on the API link above. To
                provide fixed log messages as required by the Technical Specification:</para>
            <para><tag xlink:href="http://cwiki.apache.org/confluence/display/qpid/Operational+Logging+-+Status+Update+-+Technical+SpecificationOperationalLogging-StatusUpdate-TechnicalSpecification-Howtoprovidefixedlogmessages">Operational Logging Tech Specification</tag></para>
            <para>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.</para>
            <para>For details of what processing is done see GenerateLogMessages. </para>
            <para>What a localiser or developer need know is the following: </para>
            <para>The Property structure is important as it defines how the class and methods will
                be built.</para>
        </sect1>
        <sect1>
            <title>Class Generation</title>
            <para> Each class of messages will be split in to their own &lt;Class>Messages.java.
                Each logmessage file contains only one class of messages the &lt;Class> name is
                derived from the name of the logmessages file e.g. &lt;Class&gt;_logmessages.properties.                  
            </para>                
        </sect1>
        <sect1>
            <title>Property Format</title>
            <para>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.</para>
            <para>The property file should contain entries in the following format:</para>
            <programlisting><![CDATA[<Log Identifier,developer focused>=<Log Identifier,Operate focus>:<Log Message>]]>
            </programlisting>
             
            <para>eg:</para>
            <programlisting><![CDATA[SHUTTING_DOWN = BRK-1003 : Shutting down : {0} port {1,number,}]]>
            </programlisting>   
            
            <para>Note: the developer focused identifier will become a method name so only a valid
                method name should be used. Currently only '-' are converted to '_'.</para>
            <para>That said properties generate the logging code at build time so any error can be
                easily identified.</para>
            <para>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.</para>
            <para>The current broker contains the following mappings:</para>
            <para>
                <table>
                    <title>Status Messages Mapping</title>
                    <tgroup cols="2">
                        <colspec colname="c1" colnum="1" colwidth="118.29pt"/>
                        <colspec colname="c2" colnum="2" colwidth="135.18pt"/>
                        <thead>
                            <row>
                                <entry>Class</entry>
                                <entry> Type</entry>
                            </row>
                        </thead>
                        <tbody>
                            <row>
                                <entry>Broker</entry>
                                <entry>BRK</entry>
                            </row>
                            <row>
                                <entry>Management Console</entry>
                                <entry>MNG</entry>
                            </row>
                            <row>
                                <entry>VirtualHost</entry>
                                <entry>VHT</entry>
                            </row>
                            <row>
                                <entry>MessageStore</entry>
                                <entry>MST</entry>
                            </row>
                            <row>
                                <entry>ConfigStore</entry>
                                <entry>CFG</entry>
                            </row>
                            <row>
                                <entry>TransactionLog</entry>
                                <entry>TXN</entry>
                            </row>
                            <row>
                                <entry>Connection</entry>
                                <entry>CON</entry>
                            </row>
                            <row>
                                <entry>Channel</entry>
                                <entry>CHN</entry>
                            </row>
                            <row>
                                <entry>Queue</entry>
                                <entry>QUE</entry>
                            </row>
                            <row>
                                <entry>Exchange</entry>
                                <entry>EXH</entry>
                            </row>
                            <row>
                                <entry>Binding</entry>
                                <entry>BND</entry>
                            </row>
                            <row>
                                <entry>Subscription</entry>
                                <entry>SUB</entry>
                            </row>
                        </tbody>
                    </tgroup>
                </table>
            </para>
        </sect1>
        <sect1>
            <title>Property Processing</title>
                <para>
                    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:
               </para>     
            
            <para>Property:</para>
            <programlisting><![CDATA[SHUTTING_DOWN = BRK-1003 : Shuting down : {0} port {1,number,}]]></programlisting>                      
            <para>becomes Method:</para>
            <programlisting><![CDATA[public static LogMessage SHUTTING_DOWN(String param1, Number param2)]]>
            </programlisting>
           
            <para>
                This improves our compile time validation of log message content and
            ensures that change in the message format does not accidentally cause
            erroneous messages.</para>
        </sect1>
        <sect1>
            <title>Option Processing</title>
            <para>
                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:
            </para>
            <programlisting><![CDATA[Msg = Log Message [option1] [option2] ]]></programlisting>                        
            <para>
                Two options will be identified and enabled to select text 'option1' and
                'option2'.
            </para>
            <para>            
                The nesting of a options is not supported and will provide
                unexpected results. e.g. Using Message:
            </para>    
            <programlisting><![CDATA[Msg = Log Message [option1 [sub-option2]] ]]></programlisting>                
            <para>    
                The options will be 'option1 [sub-option2' and 'sub-option2'. The first
                option includes the second option as the nesting is not detected.
            </para>
            <para>            
                The detected options are presented in the method signature as boolean options
                numerically identified by their position in the message. e.g.
                Property:
            </para>                
            <programlisting><![CDATA[ CON-1001 = Open : Client ID {0} [: Protocol Version : {1}] ]]></programlisting>                
            <para>becomes Method:</para>            
            <programlisting><![CDATA[ public static LogMessage CON_1001(String param1, String param2, boolean opt1) ]]></programlisting>                
            <para>            
                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.
            </para>
            <para>            
                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:
            </para>
            <programlisting><![CDATA[ QUE-1001 = Create : Owner: {0} [AutoDelete] [Durable] [Transient] [Priority: {1,number,}] ]]></programlisting>            
            <para>            
                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:
            </para>
            <programlisting><![CDATA[ "Create : Owner: guest    Priority: 1" ]]></programlisting>
            <para>
                Note the spaces here in between gues and Priority are present because only the text between the brackets
                has been removed.
            </para>
            <para>            
                Each option needs to include white space to correctly format the message. So
                the correct definition of QUE-1001 is as follows:
            </para>
            <programlisting><![CDATA[ QUE-1001 = Create : Owner: {0}[ AutoDelete][ Durable][ Transient][ Priority: {1,number,}] ]]></programlisting> 
            <para>            
                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:
            </para>
            <programlisting><![CDATA[ "Create : Owner: guest Priority: 1" ]]></programlisting>             
        </sect1>
    </chapter>    
</book>