xref: /AOO41X/main/sal/rtl/source/logfile.cxx (revision 87d2adbc9cadf14644c3679b041b9226f7630199)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sal.hxx"
26 #include <cstdarg>
27 #include <cstdio>
28 #include <stdio.h>
29 #include <stdarg.h>
30 
31 #include <rtl/logfile.h>
32 #include <osl/process.h>
33 #ifndef _OSL_FILE_H_
34 #include <osl/time.h>
35 #endif
36 #include <osl/time.h>
37 #include <osl/mutex.hxx>
38 #include <rtl/bootstrap.h>
39 #include <rtl/ustring.hxx>
40 #ifndef _RTL_STRBUF_HXX_
41 #include <rtl/ustrbuf.hxx>
42 #endif
43 #include <rtl/alloc.h>
44 #include "osl/thread.h"
45 
46 #include <algorithm>
47 
48 #ifdef _MSC_VER
49 #define vsnprintf _vsnprintf
50 #endif
51 
52 using namespace rtl;
53 using namespace osl;
54 using namespace std;
55 
56 namespace {
57 
58 static oslFileHandle g_aFile = 0;
59 static sal_Bool g_bHasBeenCalled = sal_False;
60 static const sal_Int32 g_BUFFERSIZE = 4096;
61 static sal_Char *g_buffer = 0;
62 
63 class   LoggerGuard
64 {
65 public:
66     ~LoggerGuard();
67 };
68 
~LoggerGuard()69 LoggerGuard::~LoggerGuard()
70 {
71     if( g_buffer )
72     {
73         sal_Int64 nWritten, nConverted =
74             sprintf( g_buffer, "closing log file at %06" SAL_PRIuUINT32, osl_getGlobalTimer() );
75         if( nConverted > 0 )
76             osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64 *)&nWritten );
77         osl_closeFile( g_aFile );
78         g_aFile = 0;
79 
80         rtl_freeMemory( g_buffer );
81         g_buffer = 0;
82         g_bHasBeenCalled = sal_False;
83     }
84 }
85 
86 // The destructor of this static LoggerGuard is "activated" by the assignment to
87 // g_buffer in init():
88 LoggerGuard loggerGuard;
89 
getLogMutex()90 Mutex & getLogMutex()
91 {
92     static Mutex *pMutex = 0;
93     if( !pMutex )
94     {
95         MutexGuard guard( Mutex::getGlobalMutex() );
96         if( ! pMutex )
97         {
98             static Mutex mutex;
99             pMutex = &mutex;
100         }
101     }
102     return *pMutex;
103 }
104 
getFileUrl(const OUString & name)105 OUString getFileUrl( const OUString &name )
106 {
107     OUString aRet;
108     if ( osl_getFileURLFromSystemPath( name.pData, &aRet.pData )
109          != osl_File_E_None )
110     {
111         OSL_ASSERT( false );
112     }
113 
114     OUString aWorkingDirectory;
115     osl_getProcessWorkingDir( &(aWorkingDirectory.pData) );
116     osl_getAbsoluteFileURL( aWorkingDirectory.pData, aRet.pData, &(aRet.pData) );
117 
118     return aRet;
119 }
120 
init()121 void init() {
122     if( !g_bHasBeenCalled )
123     {
124         MutexGuard guard( getLogMutex() );
125         if( ! g_bHasBeenCalled )
126         {
127             OUString name( RTL_CONSTASCII_USTRINGPARAM( "RTL_LOGFILE" ) );
128             OUString value;
129             if( rtl_bootstrap_get( name.pData, &value.pData, 0 ) )
130             {
131                 //  Obtain process id.
132                 oslProcessIdentifier aProcessId = 0;
133                 oslProcessInfo info;
134                 info.Size = sizeof (oslProcessInfo);
135                 if (osl_getProcessInfo (0, osl_Process_IDENTIFIER, &info) == osl_Process_E_None)
136                     aProcessId = info.Ident;
137 
138                 //  Construct name of log file and open the file.
139                 OUStringBuffer buf( 128 );
140                 buf.append( value );
141 
142                 // if the filename ends with .nopid, the incoming filename is not modified
143                 if( value.getLength() < 6 /* ".nopid" */ ||
144                     rtl_ustr_ascii_compare_WithLength(
145                         value.getStr() + (value.getLength()-6) , 6 , ".nopid" ) )
146                 {
147                     buf.appendAscii( "_" );
148                     buf.append( (sal_Int32) aProcessId );
149                     buf.appendAscii( ".log" );
150                 }
151 
152                 OUString o = getFileUrl( buf.makeStringAndClear() );
153                 oslFileError e = osl_openFile(
154                     o.pData, &g_aFile, osl_File_OpenFlag_Write|osl_File_OpenFlag_Create);
155 
156                 if( osl_File_E_None == e )
157                 {
158                     TimeValue aCurrentTime;
159                     g_buffer = ( sal_Char * ) rtl_allocateMemory( g_BUFFERSIZE );
160                     sal_Int64 nConverted = 0;
161                     if (osl_getSystemTime (&aCurrentTime))
162                     {
163                         nConverted = (sal_Int64 ) sprintf (
164                                 g_buffer,
165                                 "opening log file %f seconds past January 1st 1970\n"
166                                 "corresponding to %" SAL_PRIuUINT32 " ms after timer start\n",
167                                 aCurrentTime.Seconds + 1e-9 * aCurrentTime.Nanosec,
168                                 osl_getGlobalTimer());
169 
170                         if( nConverted > 0 )
171                         {
172                             sal_Int64 nWritten;
173                             osl_writeFile( g_aFile, g_buffer, nConverted , (sal_uInt64 *)&nWritten );
174                         }
175                     }
176 
177                     nConverted = sprintf (g_buffer, "Process id is %" SAL_PRIuUINT32 "\n", aProcessId);
178                     if( nConverted )
179                     {
180                         sal_Int64 nWritten;
181                         osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64 *)&nWritten );
182                     }
183                 }
184                 else
185                 {
186                     OSL_TRACE( "Couldn't open logfile %s(%d)" , o.getStr(), e );
187                 }
188             }
189             g_bHasBeenCalled = sal_True;
190         }
191     }
192 }
193 
194 }
195 
rtl_logfile_trace(const char * pszFormat,...)196 extern "C" void SAL_CALL rtl_logfile_trace  ( const char *pszFormat, ... )
197 {
198     init();
199     if( g_buffer )
200     {
201         va_list args;
202         va_start(args, pszFormat);
203         {
204             sal_Int64 nConverted, nWritten;
205             MutexGuard guard( getLogMutex() );
206             nConverted = vsnprintf( g_buffer , g_BUFFERSIZE, pszFormat, args );
207             nConverted = (nConverted > g_BUFFERSIZE ? g_BUFFERSIZE : nConverted );
208             if( nConverted > 0 )
209                 osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64*)&nWritten );
210         }
211         va_end(args);
212     }
213 }
214 
rtl_logfile_longTrace(char const * format,...)215 extern "C" void SAL_CALL rtl_logfile_longTrace(char const * format, ...) {
216     init();
217     if (g_buffer != 0) {
218         sal_uInt32 time = osl_getGlobalTimer();
219         oslThreadIdentifier threadId = osl_getThreadIdentifier(0);
220         va_list args;
221         va_start(args, format);
222         {
223             MutexGuard g(getLogMutex());
224             int n1 = snprintf(
225                 g_buffer, g_BUFFERSIZE, "%06" SAL_PRIuUINT32 " %" SAL_PRIuUINT32 " ", time, threadId);
226             if (n1 >= 0) {
227                 sal_uInt64 n2;
228                 osl_writeFile(
229                     g_aFile, g_buffer,
230                     static_cast< sal_uInt64 >(
231                         std::min(n1, static_cast< int >(g_BUFFERSIZE))),
232                     &n2);
233                 n1 = vsnprintf(g_buffer, g_BUFFERSIZE, format, args);
234                 if (n1 > 0) {
235                     osl_writeFile(
236                         g_aFile, g_buffer,
237                         static_cast< sal_uInt64 >(
238                             std::min(n1, static_cast< int >(g_BUFFERSIZE))),
239                         &n2);
240                 }
241             }
242         }
243         va_end(args);
244     }
245 }
246 
rtl_logfile_hasLogFile(void)247 extern "C" sal_Bool SAL_CALL rtl_logfile_hasLogFile( void ) {
248     init();
249     return g_buffer != 0;
250 }
251