]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTLogging.cxx
- check whether AliLog supports external streams and notification callback
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTLogging.cxx
1 // @(#) $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
8  *          for The ALICE Off-line Project.                               *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTLogging.cxx
20     @author Matthias Richter, Timm Steinbeck
21     @date   
22     @brief  Implementation of HLT logging primitives.
23 */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 #ifndef NOALIROOT_LOGGING
30 #include "AliLog.h"
31 #endif
32 #include "AliHLTStdIncludes.h"
33 #include "AliHLTLogging.h"
34 #include "TString.h"
35 #include "TArrayC.h"
36 #include "Varargs.h"
37 #include <string>
38 #include <sstream>
39 #include <iostream>
40
41 /** target stream for AliRoot logging methods */
42 ostringstream gLogstr;
43
44 #ifndef NOALIROOT_LOGGING
45 /**
46  * Notification callback for AliRoot logging methods
47  */
48 void LogNotification(AliLog::EType_t level, const char* message)
49 {
50   AliHLTLogging hltlog;
51   hltlog.SwitchAliLog(0);
52   hltlog.Logging(kHLTLogInfo, "NotificationHandler", "AliLog", gLogstr.str().c_str());
53   gLogstr.clear();
54   string empty("");
55   gLogstr.str(empty);
56 }
57 #endif
58
59 /**
60  * The global logging buffer.
61  * The buffer is created with an initial size and grown dynamically on
62  * demand.
63  */
64 TArrayC gAliHLTLoggingTarget(200);
65
66 /** the maximum size of the buffer */
67 const int gALIHLTLOGGING_MAXBUFFERSIZE=10000;
68
69 /** ROOT macro for the implementation of ROOT specific class methods */
70 ClassImp(AliHLTLogging)
71
72 AliHLTLogging::AliHLTLogging()
73   :
74   //fLocalLogFilter(kHLTLogDefault),
75   fLocalLogFilter(kHLTLogAll),
76   fpDefaultKeyword(NULL),
77   fpCurrentKeyword(NULL)
78 {
79   // see header file for class documentation
80   // or
81   // refer to README to build package
82   // or
83   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
84 }
85
86 AliHLTLogging::AliHLTLogging(const AliHLTLogging&)
87   :
88   fLocalLogFilter(kHLTLogAll),
89   fpDefaultKeyword(NULL),
90   fpCurrentKeyword(NULL)
91 {
92   // see header file for class documentation
93   HLTFatal("copy constructor untested");
94 }
95
96 AliHLTLogging& AliHLTLogging::operator=(const AliHLTLogging&)
97
98   // see header file for class documentation
99   HLTFatal("assignment operator untested");
100   return *this;
101 }
102
103 AliHLTComponentLogSeverity AliHLTLogging::fGlobalLogFilter=kHLTLogAll;
104 AliHLTfctLogging AliHLTLogging::fLoggingFunc=NULL;
105 int AliHLTLogging::fgUseAliLog=1;
106
107 AliHLTLogging::~AliHLTLogging()
108 {
109   // see header file for class documentation
110 }
111
112 int AliHLTLogging::Init(AliHLTfctLogging pFun) 
113 {
114   // see header file for class documentation
115   if (fLoggingFunc!=NULL && fLoggingFunc!=pFun) {
116     (*fLoggingFunc)(NULL/*fParam*/, kHLTLogWarning, "AliHLTLogging::Init", "no key", "overriding previously initialized logging function");    
117   }
118   fLoggingFunc=pFun;
119   // older versions of AliLog does not support the notification callback and
120   // stringstreams, but they support the logging macros in general
121 #ifndef NOALIROOT_LOGGING
122 #ifndef NO_ALILOG_NOTIFICATION
123   AliLog* log=new AliLog;
124   log->SetLogNotification(LogNotification);
125   log->SetStreamOutput(&gLogstr);
126 #endif // NO_ALILOG_NOTIFICATION
127 #endif // NOALIROOT_LOGGING
128   
129   return 0;
130 }
131
132 int AliHLTLogging::Message(void *param, AliHLTComponentLogSeverity severity,
133                            const char* origin, const char* keyword,
134                            const char* message) 
135 {
136   // see header file for class documentation
137   int iResult=0;
138   if (param==NULL) {
139     // this is currently just to get rid of the warning "unused parameter"
140   }
141
142   const char* strSeverity="";
143   switch (severity) {
144   case kHLTLogBenchmark: 
145     strSeverity="benchmark";
146     break;
147   case kHLTLogDebug:
148     strSeverity="debug";
149     break;
150   case kHLTLogInfo:
151     strSeverity="info";
152     break;
153   case kHLTLogWarning:
154     strSeverity="warning";
155     break;
156   case kHLTLogError:
157     strSeverity="error";
158     break;
159   case kHLTLogFatal:
160     strSeverity="fatal";
161     break;
162   default:
163     break;
164   }
165   TString out="HLT Log ";
166   out+=strSeverity;
167   if (origin) {out+=": "; out+=origin;}
168   out+=" "; out+=message;
169   if (keyword!=NULL && strcmp(keyword, HLT_DEFAULT_LOG_KEYWORD)!=0) {
170     out+=" ("; out+=keyword; out +=")";
171   }
172   cout << out.Data() << endl;
173   return iResult;
174 }
175
176 #ifndef NOALIROOT_LOGGING
177 int AliHLTLogging::AliMessage(AliHLTComponentLogSeverity severity, 
178                               const char* origin_class, const char* origin_func,
179                               const char* file, int line, const char* message) 
180 {
181   // see header file for class documentation
182
183   switch (severity) {
184   case kHLTLogBenchmark: 
185     AliLog::Message(AliLog::kInfo, message, "HLT", origin_class, origin_func, file, line);
186     break;
187   case kHLTLogDebug:
188     AliLog::Message(AliLog::kDebug, message, "HLT", origin_class, origin_func, file, line);
189     break;
190   case kHLTLogInfo:
191     AliLog::Message(AliLog::kInfo, message, "HLT", origin_class, origin_func, file, line);
192     break;
193   case kHLTLogWarning:
194     AliLog::Message(AliLog::kWarning, message, "HLT", origin_class, origin_func, file, line);
195     break;
196   case kHLTLogError:
197     AliLog::Message(AliLog::kError, message, "HLT", origin_class, origin_func, file, line);
198     break;
199   case kHLTLogFatal:
200     AliLog::Message(AliLog::kWarning, message, "HLT", origin_class, origin_func, file, line);
201     break;
202   default:
203     break;
204   }
205   return 0;
206 }
207 #endif
208
209 const char* AliHLTLogging::BuildLogString(const char *format, va_list ap) 
210 {
211   // see header file for class documentation
212
213   int iResult=0;
214   va_list bap;
215   R__VA_COPY(bap, ap);
216
217   // take the first argument from the list as format string if no
218   // format was given
219   const char* fmt = format;
220   if (fmt==NULL) fmt=va_arg(ap, const char*);
221
222   gAliHLTLoggingTarget[0]=0;
223   while (fmt!=NULL) {
224     iResult=vsnprintf(gAliHLTLoggingTarget.GetArray(), gAliHLTLoggingTarget.GetSize(), fmt, ap);
225     if (iResult==-1)
226       // for compatibility with older version of vsnprintf
227       iResult=gAliHLTLoggingTarget.GetSize()*2;
228     else if (iResult<gAliHLTLoggingTarget.GetSize())
229       break;
230
231     // terminate if buffer is already at the limit
232     if (gAliHLTLoggingTarget.GetSize()>=gALIHLTLOGGING_MAXBUFFERSIZE) {
233       gAliHLTLoggingTarget[gAliHLTLoggingTarget.GetSize()-1]=0;
234       break;
235     }
236
237     // check limitation and grow the buffer
238     if (iResult>gALIHLTLOGGING_MAXBUFFERSIZE) iResult=gALIHLTLOGGING_MAXBUFFERSIZE;
239     gAliHLTLoggingTarget.Set(iResult+1);
240
241     // copy the original list and skip the first argument if this was the format string
242     va_end(ap);
243     R__VA_COPY(ap, bap);
244     if (format==NULL) va_arg(ap, const char*);
245   }     
246   va_end(bap);
247
248   return gAliHLTLoggingTarget.GetArray();
249 }
250
251 int AliHLTLogging::Logging(AliHLTComponentLogSeverity severity,
252                            const char* origin, const char* keyword,
253                            const char* format, ... ) 
254 {
255   // see header file for class documentation
256   int iResult=CheckFilter(severity);
257   if (iResult>0) {
258     va_list args;
259     va_start(args, format);
260     if (fLoggingFunc) {
261       iResult = (*fLoggingFunc)(NULL/*fParam*/, severity, origin, keyword, AliHLTLogging::BuildLogString(format, args ));
262     } else {
263 #ifndef NOALIROOT_LOGGING
264       if (fgUseAliLog)
265         iResult=AliMessage(severity, NULL, origin, NULL, 0, AliHLTLogging::BuildLogString(format, args ));
266       else
267 #endif
268         iResult=Message(NULL/*fParam*/, severity, origin, keyword, AliHLTLogging::BuildLogString(format, args ));
269     }
270     va_end(args);
271   }
272   return iResult;
273 }
274
275 int AliHLTLogging::LoggingVarargs(AliHLTComponentLogSeverity severity, 
276                                   const char* origin_class, const char* origin_func,
277                                   const char* file, int line,  ... ) const
278 {
279   // see header file for class documentation
280
281   if (file==NULL && line==0) {
282     // this is currently just to get rid of the warning "unused parameter"
283   }
284   int iResult=CheckFilter(severity);
285   if (iResult>0) {
286     const char* separator="";
287     TString origin;
288     if (origin_class) {
289         origin+=origin_class;
290         separator="::";
291     }
292     if (origin_func) {
293         origin+=separator;
294         origin+=origin_func;
295     }
296     va_list args;
297     va_start(args, line);
298
299     if (fLoggingFunc) {
300       iResult=(*fLoggingFunc)(NULL/*fParam*/, severity, origin.Data(), GetKeyword(), AliHLTLogging::BuildLogString(NULL, args ));
301     } else {
302 #ifndef NOALIROOT_LOGGING
303       if (fgUseAliLog)
304         iResult=AliMessage(severity, origin_class, origin_func, file, line, AliHLTLogging::BuildLogString(NULL, args ));
305       else
306 #endif
307         iResult=Message(NULL/*fParam*/, severity, origin.Data(), GetKeyword(), AliHLTLogging::BuildLogString(NULL, args ));
308     }
309     va_end(args);
310   }
311   return iResult;
312 }
313
314 int AliHLTLogging::CheckFilter(AliHLTComponentLogSeverity severity) const
315 {
316   // see header file for class documentation
317
318   int iResult=severity==kHLTLogNone || (severity&fGlobalLogFilter)>0 && (severity&fLocalLogFilter)>0;
319   return iResult;
320 }
321
322 void AliHLTLogging::SetGlobalLoggingLevel(AliHLTComponentLogSeverity level)
323 {
324   // see header file for class documentation
325
326   fGlobalLogFilter=level;
327 }
328
329 void AliHLTLogging::SetLocalLoggingLevel(AliHLTComponentLogSeverity level)
330 {
331   // see header file for class documentation
332
333   fLocalLogFilter=level;
334 }