xref: /AOO41X/main/sal/inc/rtl/logfile.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir #ifndef _RTL_LOGFILE_HXX_
28*cdf0e10cSrcweir #define _RTL_LOGFILE_HXX_
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <rtl/logfile.h>
31*cdf0e10cSrcweir #include <rtl/string.hxx>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir namespace rtl
34*cdf0e10cSrcweir {
35*cdf0e10cSrcweir /**
36*cdf0e10cSrcweir @descr	The intended use for class Logfile is to write time stamp information
37*cdf0e10cSrcweir 		for profiling purposes.
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir 		Profiling output should only be generated for a special product version of OpenOffice
40*cdf0e10cSrcweir 		which is compiled with a defined preprocessor symbol 'TIMELOG'.
41*cdf0e10cSrcweir 		Therefore we have provided a set of macros that uses the class Logfile only if
42*cdf0e10cSrcweir 		this symbol is defined.  If the macros are not sufficient, i.e. you need more
43*cdf0e10cSrcweir 		then three arguments for a printf style message, then you have to insert an
44*cdf0e10cSrcweir 		#ifdef TIMELOG/#endif brace yourself.
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir 		Additionally the environment variable RTL_LOGFILE has to be defined in order to generate
47*cdf0e10cSrcweir 		logging information. If the variable is not empty, it creates a file with the name
48*cdf0e10cSrcweir 		$(RTL_LOGFILE)_$(PID).log, where $(PID) is the process id of the running process.
49*cdf0e10cSrcweir 		It can be used as a run time switch for enabling or disabling the logging.
50*cdf0e10cSrcweir 		Note that this variable is evaluated only once at the first attempt to write a message.
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir 		The class LogFile collects runtime data within its constructor and destructor. It can be
53*cdf0e10cSrcweir 		used for timing whole functions.
54*cdf0e10cSrcweir 		If you want to write timing data without context you can use the RTL_LOGFILE_TRACE-macros
55*cdf0e10cSrcweir 		which are defined inside <rtl/logfile.h>.
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir 		The class LogFile should not be used directly, instead use the RTL_LOGFILE_CONTEXT/
58*cdf0e10cSrcweir 		RTL_LOGFILE_TRACE-macros.
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 		Macro usage:
61*cdf0e10cSrcweir 		------------
62*cdf0e10cSrcweir 		RTL_LOGFILE_CONTEXT( instance, name );
63*cdf0e10cSrcweir 		This macro creates an instance of class LogFile with the name "instance" and writes the current time,
64*cdf0e10cSrcweir 		thread id and "name" to the log file.
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir 		Example: RTL_LOGFILE_CONTEXT( aLog, "Timing for foo-method" );
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 		RTL_LOGFILE_CONTEXT_TRACE( instance, mesage );
69*cdf0e10cSrcweir 		RTL_LOGFILE_CONTEXT_TRACEn( instance, frmt, arg1, .., arg3 );
70*cdf0e10cSrcweir 		These macros can be used to log information in a "instance" context. The "instance" object
71*cdf0e10cSrcweir 		is used to log message informations. All macros with "frmt" uses printf notation to log timing infos.
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir 		Example: RTL_LOGFILE_CONTEXT_TRACE( aLog, "Now we call an expensive function" );
74*cdf0e10cSrcweir 				 RTL_LOGFIlE_CONTEXT_TRACE1( aLog, "Config entries read: %u", (unsigned short)i );
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir 		RTL_LOGFILE_TRACE( string );
77*cdf0e10cSrcweir 		RTL_LOGFILE_TRACEn( frmt, arg1, .., arg3 );
78*cdf0e10cSrcweir 		These macros can be used to log information outside a context. The macro directly calls
79*cdf0e10cSrcweir 		rtl_logfile_trace to write the info to the log file. All macros with "frmt" uses printf
80*cdf0e10cSrcweir 		notation to log timing infos.
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 		Example: RTL_LOGFILE_TRACE( "Timing for loading a file" );
83*cdf0e10cSrcweir 				 RTL_LOGFILE_TRACE1( aLog, "Timing for loading file: %s", aFileName );
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 		The lines written to the log file consist of the following space separated elements:
86*cdf0e10cSrcweir 		1.	The time relative to the start of the global timer in milliseconds.  The times is
87*cdf0e10cSrcweir 			started typically for the first logged line.
88*cdf0e10cSrcweir 		2.	Thread id.  It's absolut value is probably of less interest than providing a way to
89*cdf0e10cSrcweir 			distinguish different threads.
90*cdf0e10cSrcweir 		3.	a.	An opening or closing curly brace indicating the start or end of a scope.
91*cdf0e10cSrcweir 				4a. Function name or general scope identifier.
92*cdf0e10cSrcweir 			b.	A vertical line indicating an arbitrary message.
93*cdf0e10cSrcweir 				4b optional function name or general scope identifier.
94*cdf0e10cSrcweir 				5b A colon followed by a space and a free form message terminated by a newline.
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 		There is a second version of creating a context. RTL_LOGFILE_CONTEXT_AUTHOR takes
97*cdf0e10cSrcweir 		two more arguments, the name of the project and the author's sign who is responsible
98*cdf0e10cSrcweir 		for the code in which the macro is used.
99*cdf0e10cSrcweir */
100*cdf0e10cSrcweir 	class Logfile
101*cdf0e10cSrcweir 	{
102*cdf0e10cSrcweir 	public:
103*cdf0e10cSrcweir 		inline Logfile( const sal_Char *name );
104*cdf0e10cSrcweir 		/**	@descr	Create a log file context where the message field consists of a project
105*cdf0e10cSrcweir 				name, the author's shortcut, and the actual message.  These three strings
106*cdf0e10cSrcweir 				are written in a format that is understood by script that later parses the
107*cdf0e10cSrcweir 				log file and that so can extract the three strings.
108*cdf0e10cSrcweir 			@param	project	Short name of the project, like sw for writer or sc for calc.
109*cdf0e10cSrcweir 			@param	author	The sign of the person responsible for the code.
110*cdf0e10cSrcweir 			@param	name	The actual message, typically a method name.
111*cdf0e10cSrcweir 		*/
112*cdf0e10cSrcweir 		inline Logfile( const sal_Char *project, const sal_Char *author, const sal_Char *name );
113*cdf0e10cSrcweir 		inline ~Logfile();
114*cdf0e10cSrcweir 		inline const sal_Char *getName();
115*cdf0e10cSrcweir 	private:
116*cdf0e10cSrcweir 		::rtl::OString m_sName;
117*cdf0e10cSrcweir 	};
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir 	inline Logfile::Logfile( const sal_Char *name )
120*cdf0e10cSrcweir 		: m_sName( name )
121*cdf0e10cSrcweir 	{
122*cdf0e10cSrcweir 		rtl_logfile_longTrace( "{ %s\n", name );
123*cdf0e10cSrcweir 	}
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir 	inline Logfile::Logfile( const sal_Char *project, const sal_Char *author, const sal_Char *name )
126*cdf0e10cSrcweir 		: m_sName( project)
127*cdf0e10cSrcweir 	{
128*cdf0e10cSrcweir 		m_sName += " (";
129*cdf0e10cSrcweir 		m_sName += author;
130*cdf0e10cSrcweir 		m_sName += ") ";
131*cdf0e10cSrcweir 		m_sName += name;
132*cdf0e10cSrcweir 		rtl_logfile_longTrace( "{ %s\n", m_sName.pData->buffer );
133*cdf0e10cSrcweir 	}
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 	inline Logfile::~Logfile()
136*cdf0e10cSrcweir 	{
137*cdf0e10cSrcweir 		rtl_logfile_longTrace( "} %s\n", m_sName.pData->buffer );
138*cdf0e10cSrcweir 	}
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir 	inline const sal_Char * Logfile::getName()
141*cdf0e10cSrcweir 	{
142*cdf0e10cSrcweir 		return m_sName.getStr();
143*cdf0e10cSrcweir 	}
144*cdf0e10cSrcweir }
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir #ifdef TIMELOG
147*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT( instance, name ) ::rtl::Logfile instance( name )
148*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_AUTHOR( instance, project, author, name ) ::rtl::Logfile instance(project, author, name )
149*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE( instance, message ) \
150*cdf0e10cSrcweir 		rtl_logfile_longTrace( "| %s : %s\n", \
151*cdf0e10cSrcweir 						   instance.getName(), \
152*cdf0e10cSrcweir 						   message )
153*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE1( instance , frmt, arg1 ) \
154*cdf0e10cSrcweir 		rtl_logfile_longTrace( "| %s : ", \
155*cdf0e10cSrcweir 						   instance.getName() ); \
156*cdf0e10cSrcweir         rtl_logfile_trace( frmt , arg1 ); \
157*cdf0e10cSrcweir         rtl_logfile_trace( "\n" )
158*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE2( instance , frmt, arg1 , arg2 ) \
159*cdf0e10cSrcweir 		rtl_logfile_longTrace( "| %s : ", \
160*cdf0e10cSrcweir 						   instance.getName() ); \
161*cdf0e10cSrcweir         rtl_logfile_trace( frmt , arg1 , arg2 ); \
162*cdf0e10cSrcweir         rtl_logfile_trace( "\n" )
163*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE3( instance , frmt, arg1 , arg2 , arg3 ) \
164*cdf0e10cSrcweir 		rtl_logfile_longTrace( "| %s : ", \
165*cdf0e10cSrcweir 						   instance.getName() ); \
166*cdf0e10cSrcweir         rtl_logfile_trace( frmt , arg1 , arg2 , arg3 ); \
167*cdf0e10cSrcweir         rtl_logfile_trace( "\n" )
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir #else
170*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT( instance, name )  ((void)0)
171*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_AUTHOR( instance, project, author, name )  ((void)0)
172*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE( instance, message )  ((void)0)
173*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE1( instance, frmt, arg1 ) ((void)0)
174*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE2( instance, frmt, arg1, arg2 ) ((void)0)
175*cdf0e10cSrcweir #define RTL_LOGFILE_CONTEXT_TRACE3( instance, frmt, arg1, arg2 , arg3 ) ((void)0)
176*cdf0e10cSrcweir #endif
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir // Normal RTL_LOGFILE_* entries will not make it into release versions,
179*cdf0e10cSrcweir // TIMELOG is disabled a few versions prior relase build.
180*cdf0e10cSrcweir //
181*cdf0e10cSrcweir // We need some logs also in these builds, eg. for making performance regression tests.
182*cdf0e10cSrcweir //
183*cdf0e10cSrcweir // POLICY: Don't use RTL_LOGFILE_PRODUCT_* for your personal logging information.
184*cdf0e10cSrcweir //         Be aware that these logs make it into the product shipped to customers.
185*cdf0e10cSrcweir //         If you have good reasons for doing this, please contact product management.
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir #define RTL_LOGFILE_PRODUCT_TRACE( string )  \
188*cdf0e10cSrcweir             rtl_logfile_longTrace( "| : %s\n", string )
189*cdf0e10cSrcweir #define RTL_LOGFILE_PRODUCT_TRACE1( frmt, arg1 ) \
190*cdf0e10cSrcweir              rtl_logfile_longTrace( "| : " ); \
191*cdf0e10cSrcweir              rtl_logfile_trace( frmt, arg1 ); \
192*cdf0e10cSrcweir              rtl_logfile_trace( "\n" )
193*cdf0e10cSrcweir #define RTL_LOGFILE_PRODUCT_CONTEXT( instance, name ) \
194*cdf0e10cSrcweir             ::rtl::Logfile instance( name )
195*cdf0e10cSrcweir #define RTL_LOGFILE_PRODUCT_CONTEXT_TRACE1( instance, frmt, arg1 ) \
196*cdf0e10cSrcweir 		rtl_logfile_longTrace( "| %s : ", \
197*cdf0e10cSrcweir 						   instance.getName() ); \
198*cdf0e10cSrcweir              rtl_logfile_trace( frmt, arg1 ); \
199*cdf0e10cSrcweir              rtl_logfile_trace( "\n" )
200*cdf0e10cSrcweir #define RTL_LOGFILE_HASLOGFILE() \
201*cdf0e10cSrcweir 			 rtl_logfile_hasLogFile()
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir #endif
205*cdf0e10cSrcweir 
206