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