1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "pvlogger.h"
19 #include "pvlogger_registry.h"
20 #include "pvlogger_accessories.h"
21 #include "oscl_dll.h"
22 #include "oscl_stdstring.h"
23
24
25 #ifndef OSCL_COMBINED_DLL
26 OSCL_DLL_ENTRY_POINT_DEFAULT()
27 #endif
28
29 #if(PVLOGGER_ENABLE)
30 const char rootTag[] = "";
31
32 //use the TLS registry, or the singleton registry if no TLS.
33 //Note: singleton registry only works for single-threaded scenarios,
34 //since this implementation assumes a per-thread registry.
35 #include "oscl_base.h"
36 #include "oscl_tls.h"
37 #define PVLOGGER_REGISTRY OsclTLSRegistry
38 #define PVLOGGER_REGISTRY_ID OSCL_TLS_ID_PVLOGGER
39 #define PVLOGGER_REGISTRY_WRAPPER OsclTLS
40
41 #endif //PVLOGGER_ENABLE
42
Init()43 OSCL_EXPORT_REF void PVLogger::Init()
44 {
45 #if(PVLOGGER_ENABLE)
46 alloc_type alloc;
47 OsclAny* ptr = alloc.allocate(sizeof(PVLoggerRegistry));
48 if (ptr)
49 {
50 PVLoggerRegistry *pvlogreg = new(ptr) PVLoggerRegistry();
51 int32 err;
52 PVLOGGER_REGISTRY::registerInstance(pvlogreg, PVLOGGER_REGISTRY_ID, err);
53 }
54 #endif
55 }
56
Cleanup()57 OSCL_EXPORT_REF void PVLogger::Cleanup()
58 {
59 #if(PVLOGGER_ENABLE)
60 int32 err;
61 PVLoggerRegistry *pvlogreg = OSCL_STATIC_CAST(PVLoggerRegistry*, PVLOGGER_REGISTRY::getInstance(PVLOGGER_REGISTRY_ID, err));
62 if (pvlogreg)
63 {
64 pvlogreg->~PVLoggerRegistry();
65 alloc_type alloc;
66 alloc.deallocate(pvlogreg);
67 PVLOGGER_REGISTRY::registerInstance(NULL, PVLOGGER_REGISTRY_ID, err);
68 }
69 #endif
70 }
71
GetLoggerObject(const char * inputTag)72 OSCL_EXPORT_REF PVLogger* PVLogger::GetLoggerObject(const char* inputTag)
73 {
74 #if(PVLOGGER_ENABLE)
75 PVLoggerRegistry* registry = PVLoggerRegistry::GetPVLoggerRegistry();
76 return (registry) ? registry->GetPVLoggerObject(inputTag) : NULL;
77 #else
78 OSCL_UNUSED_ARG(inputTag);
79 return NULL;
80 #endif
81 }
82
SetLogLevelAndPropagate(log_level_type level)83 OSCL_EXPORT_REF void PVLogger::SetLogLevelAndPropagate(log_level_type level)
84 {
85 #if(PVLOGGER_ENABLE)
86 _level = level;
87 PVLoggerRegistry::GetPVLoggerRegistry()->SetNodeLogLevelExplicit(_tag, level);
88 #else
89 OSCL_UNUSED_ARG(level);
90 #endif
91 }
92
IsActive(log_level_type level)93 OSCL_EXPORT_REF bool PVLogger::IsActive(log_level_type level)
94 {
95 #if(PVLOGGER_ENABLE)
96 _lastMsgLevel = level;
97
98 if (_level == PVLOGGER_LEVEL_UNINTIALIZED)
99 {
100 if (_parentLogger != NULL)
101 {
102 return(_parentLogger->IsActive(level));
103 }
104 else
105 {
106 /*
107 * We are the root node, as every node other
108 * than root MUST have a parent. If the root's
109 * log level is uninitialized, then we do not
110 * log anything
111 */
112 return false;
113 }
114 }
115 if (level <= _level)
116 {
117 return true;
118 }
119 #else
120 OSCL_UNUSED_ARG(level);
121 #endif
122 return false;
123 }
124
LogMsgStringV(message_id_type msgID,const char * fmt,va_list arguments)125 OSCL_EXPORT_REF void PVLogger::LogMsgStringV(message_id_type msgID, const char * fmt, va_list arguments)
126 {
127 #if(PVLOGGER_ENABLE)
128 filter_status_type msgStatus = FilterMsg(msgID);
129
130 if (msgStatus == PVLOGGER_FILTER_ACCEPT)
131 {
132 //Log msg to the current node
133 LogMsg(msgID, fmt, arguments);
134 }
135
136 if ((_parentLogger != NULL) && (_oAppenderInheritance))
137 {
138 //Pass the msg to the parent
139 _parentLogger->LogMsgStringV(msgID, fmt, arguments);
140 }
141 #else
142 OSCL_UNUSED_ARG(msgID);
143 OSCL_UNUSED_ARG(fmt);
144 OSCL_UNUSED_ARG(arguments);
145 #endif
146 return;
147 }
148
LogMsgBuffersV(message_id_type msgID,int32 numPairs,va_list arguments)149 OSCL_EXPORT_REF void PVLogger::LogMsgBuffersV(message_id_type msgID, int32 numPairs, va_list arguments)
150 {
151 #if(PVLOGGER_ENABLE)
152 filter_status_type msgStatus = FilterMsg(msgID);
153
154 if (msgStatus == PVLOGGER_FILTER_ACCEPT)
155 {
156 //Log msg to the current node
157 LogMsg(msgID, numPairs, arguments);
158 }
159
160 if ((_parentLogger != NULL) && (_oAppenderInheritance))
161 {
162 //Pass the msg to the parent
163 _parentLogger->LogMsgBuffersV(msgID, numPairs, arguments);
164
165 }
166 #else
167 OSCL_UNUSED_ARG(msgID);
168 OSCL_UNUSED_ARG(numPairs);
169 OSCL_UNUSED_ARG(arguments);
170 #endif
171 return;
172 }
173
LogMsgString(message_id_type msgID,const char * fmt,...)174 OSCL_EXPORT_REF void PVLogger::LogMsgString(message_id_type msgID, const char * fmt, ...)
175 {
176 #if(PVLOGGER_ENABLE)
177 va_list arguments;
178 va_start(arguments, fmt);
179
180 filter_status_type msgStatus = FilterMsg(msgID);
181
182 if (msgStatus == PVLOGGER_FILTER_ACCEPT)
183 {
184 LogMsg(msgID, fmt, arguments);
185 }
186
187 if ((_parentLogger != NULL) && (_oAppenderInheritance))
188 {
189 //Pass the msg to the parent
190 _parentLogger->LogMsgStringV(msgID, fmt, arguments);
191 }
192 #else
193 OSCL_UNUSED_ARG(msgID);
194 OSCL_UNUSED_ARG(fmt);
195 #endif
196 return;
197 }
198
LogMsgBuffers(message_id_type msgID,int32 numPairs,...)199 OSCL_EXPORT_REF void PVLogger::LogMsgBuffers(message_id_type msgID, int32 numPairs, ...)
200 {
201 #if(PVLOGGER_ENABLE)
202 va_list arguments;
203 va_start(arguments, numPairs);
204
205 filter_status_type msgStatus = FilterMsg(msgID);
206
207 if (msgStatus == PVLOGGER_FILTER_ACCEPT)
208 {
209 LogMsg(msgID, numPairs, arguments);
210 }
211
212 if ((_parentLogger != NULL) && (_oAppenderInheritance))
213 {
214 //Pass the msg to the parent
215 _parentLogger->LogMsgBuffersV(msgID, numPairs, arguments);
216 }
217 #else
218 OSCL_UNUSED_ARG(msgID);
219 OSCL_UNUSED_ARG(numPairs);
220 #endif
221 return;
222 }
223
PVLogger(const char * inputTag,log_level_type level,bool oAppenderInheritance)224 OSCL_EXPORT_REF PVLogger::PVLogger(const char* inputTag, log_level_type level, bool oAppenderInheritance)
225 {
226 #if(PVLOGGER_ENABLE)
227 _tag = _tagAllocator.ALLOCATE(oscl_strlen(inputTag) + 1);
228
229 oscl_strncpy(_tag, inputTag, (oscl_strlen(inputTag) + 1));
230
231 _parentLogger = NULL;
232 _oAppenderInheritance = oAppenderInheritance;
233 _level = level;
234 _lastMsgLevel = PVLOGGER_LEVEL_UNINTIALIZED;
235 #else
236 OSCL_UNUSED_ARG(inputTag);
237 OSCL_UNUSED_ARG(level);
238 OSCL_UNUSED_ARG(oAppenderInheritance);
239 #endif
240 return;
241 }
242
243 #if(PVLOGGER_ENABLE)
FilterMsg(message_id_type msgID)244 PVLogger::filter_status_type PVLogger::FilterMsg(message_id_type msgID)
245 {
246 uint32 j;
247
248 if (_pMsgFilterVec.size() > 0)
249 {
250 for (j = 0; j < _pMsgFilterVec.size(); j++)
251 {
252 PVLoggerFilter *msgFilter = _pMsgFilterVec[j];
253
254 filter_status_type msgStatus = msgFilter->FilterString(_tag, msgID, _level);
255
256 if (msgStatus != PVLOGGER_FILTER_NEUTRAL)
257 {
258 return msgStatus;
259 }
260 }
261 }
262 /*
263 * Either All filters returned neutral => Accept msg
264 * or No msg filters => All msgs accepted by default
265 */
266 return(PVLOGGER_FILTER_ACCEPT);
267 }
268
LogMsg(message_id_type msgID,const char * fmt,va_list arguments)269 void PVLogger::LogMsg(message_id_type msgID, const char *fmt, va_list arguments)
270 {
271 uint32 i;
272
273 for (i = 0; i < _pOwnAppenderVec.size(); i++)
274 {
275 PVLoggerAppender *appender = _pOwnAppenderVec[i];
276 appender->AppendString(msgID, fmt, arguments);
277 }
278 return;
279 }
280
LogMsg(message_id_type msgID,int32 numPairs,va_list arguments)281 void PVLogger::LogMsg(message_id_type msgID, int32 numPairs, va_list arguments)
282 {
283 uint32 i;
284
285 for (i = 0; i < _pOwnAppenderVec.size(); i++)
286 {
287 PVLoggerAppender *appender = _pOwnAppenderVec[i];
288 appender->AppendBuffers(msgID, numPairs, arguments);
289 }
290 return;
291 }
292 #endif //PVLOGGER_ENABLE
293
GetPVLoggerRegistry()294 OSCL_EXPORT_REF PVLoggerRegistry* PVLoggerRegistry::GetPVLoggerRegistry()
295 {
296 #if(PVLOGGER_ENABLE)
297 PVLOGGER_REGISTRY_WRAPPER< PVLoggerRegistry, PVLOGGER_REGISTRY_ID > pvLogRegSng;
298 return &(*pvLogRegSng);
299 #else
300 return NULL;
301 #endif
302 }
303
304
PVLoggerRegistry()305 OSCL_EXPORT_REF PVLoggerRegistry::PVLoggerRegistry()
306 {
307 #if(PVLOGGER_ENABLE)
308 /*
309 * Create the root logger node, by default turn off logging
310 * for the root node
311 */
312 OsclAny* ptr = _pvloggerAlloc.allocate(sizeof(PVLogger));
313 if (ptr)
314 {
315 PVLogger *logger = new(ptr) PVLogger(rootTag, PVLOGGER_LEVEL_UNINTIALIZED, true);
316
317 // add logger to the tag tree
318 _loggerTree[OSCL_CONST_CAST(char*, (rootTag))] = logger;
319 }
320 #endif
321 };
322
~PVLoggerRegistry()323 OSCL_EXPORT_REF PVLoggerRegistry::~PVLoggerRegistry()
324 {
325 #if(PVLOGGER_ENABLE)
326 Oscl_TagTree<PVLogger*, alloc_type>::iterator iter;
327
328 for (iter = _loggerTree.begin();
329 iter != _loggerTree.end(); iter++)
330 {
331 PVLogger* logger = iter->value;
332 logger->~PVLogger();
333 _pvloggerAlloc.deallocate(logger);
334 }
335 #endif
336 }
337
GetPVLoggerObject(const char * tagIn)338 OSCL_EXPORT_REF PVLogger *PVLoggerRegistry::GetPVLoggerObject(const char* tagIn)
339 {
340 #if(PVLOGGER_ENABLE)
341 Oscl_TagTree<PVLogger*, alloc_type>::iterator iter =
342 _loggerTree.find(OSCL_CONST_CAST(char*, (tagIn)));
343
344 if (iter != _loggerTree.end())
345 {
346 PVLogger* logger = iter->value;
347 return(logger);
348 }
349 else
350 {
351 /* creates a new logger object */
352 PVLogger *logger = NULL;
353 logger = CreatePVLogger(tagIn, PVLOGGER_LEVEL_UNINTIALIZED, true);
354 return(logger);
355 }
356 #else
357 OSCL_UNUSED_ARG(tagIn);
358 return NULL;
359 #endif
360 }
361
CreatePVLogger(const char * tagIn,log_level_type level,bool oAppenderInheritance)362 OSCL_EXPORT_REF PVLogger *PVLoggerRegistry::CreatePVLogger(const char* tagIn, log_level_type level, bool oAppenderInheritance)
363 {
364 #if(PVLOGGER_ENABLE)
365 Oscl_TagTree<PVLogger*, alloc_type>::iterator iter;
366
367 /* If the input tag already exists in the tagtree, it should have a pointer value of NULL */
368 OSCL_ASSERT((_loggerTree.find(OSCL_CONST_CAST(char* const&, (tagIn))) == _loggerTree.end()) ||
369 (_loggerTree.find(OSCL_CONST_CAST(char* const&, (tagIn))))->value == 0);
370
371 OsclAny* ptr = _pvloggerAlloc.allocate(sizeof(PVLogger));
372 if (!ptr)
373 return NULL;//fail gracefully
374
375 PVLogger *logger = new(ptr) PVLogger(tagIn, level, oAppenderInheritance);
376
377 // add logger to the tag tree
378 _loggerTree[OSCL_CONST_CAST(char*, (tagIn))] = logger;
379
380 // how many levels deep is the node we just inserted?
381 iter = _loggerTree.find(OSCL_CONST_CAST(char*, (tagIn)));
382 uint32 depth = iter->depth();
383
384 // the tag tree will automatically create the parent, grandparent, etc.
385 // make sure each ancestor's stats node is initialized, i.e. initialize each ancestor
386 // until you reach one that is already initialized.
387 Oscl_TagTree<PVLogger*, alloc_type>::node_ptr parent = iter->parent;
388
389 uint32 ii = 0;
390
391 for (ii = 0; ii < depth; ii++)
392 {
393 OSCL_ASSERT(parent != 0);
394
395 // if initialized then we're done
396 PVLogger* tmpPVLoggerNode = parent->value;
397
398 if (tmpPVLoggerNode != NULL)
399 {
400 break;
401 }
402
403 // create new Logger node, for tag use the tag created
404 // by the tag tree, for level use PV_LOG_LEVEL_UNINTIALIZED
405 // for oAppenderInheritance use true
406 OsclAny* ptr = _pvloggerAlloc.allocate(sizeof(PVLogger));
407 if (ptr)
408 {
409 tmpPVLoggerNode = new(ptr) PVLogger(parent->tag.tag, PVLOGGER_LEVEL_UNINTIALIZED, true);
410
411 // Add logger to tag tree
412 parent->value = tmpPVLoggerNode;
413
414 parent = parent->parent;
415 }
416 }
417
418 //Inherit the log level for the newly created node.
419 logger->SetLogLevel(level);
420
421 parent = iter->parent;
422 OSCL_ASSERT(parent != NULL);
423 //Set the parent of the newly created node
424 logger->SetParent(parent->value);
425
426 //Set the parent of the other nodes up the tree
427 for (ii = 0; ii < depth - 1; ii++)
428 {
429
430 PVLogger* tmpPVLoggerNode = parent->value;
431
432 parent = parent->parent;
433 OSCL_ASSERT(parent != NULL);
434
435 //Set the parent for the node
436 tmpPVLoggerNode->SetParent(parent->value);
437
438 }
439
440 return(logger);
441 #else
442 OSCL_UNUSED_ARG(tagIn);
443 OSCL_UNUSED_ARG(level);
444 OSCL_UNUSED_ARG(oAppenderInheritance);
445 return NULL;
446 #endif
447 };
448
SetNodeLogLevelExplicit(char * tagIn,log_level_type level)449 OSCL_EXPORT_REF bool PVLoggerRegistry::SetNodeLogLevelExplicit(char* tagIn,
450 log_level_type level)
451 {
452 #if(PVLOGGER_ENABLE)
453 Oscl_TagTree<PVLogger*, alloc_type>::iterator iter;
454
455 iter = _loggerTree.find(tagIn);
456
457 if (iter != _loggerTree.end())
458 {
459 Oscl_TagTree<PVLogger*, alloc_type>::node_type* currNode = &(*iter);
460
461 SetNodeLogLevelExplicit(currNode, level);
462
463 return true;
464 }
465 #else
466 OSCL_UNUSED_ARG(tagIn);
467 OSCL_UNUSED_ARG(level);
468 #endif
469 return false;
470
471 }
472
SetNodeLogLevelExplicit(Oscl_TagTree<PVLogger *,alloc_type>::node_type * node,log_level_type level)473 OSCL_EXPORT_REF void PVLoggerRegistry::SetNodeLogLevelExplicit(Oscl_TagTree<PVLogger*, alloc_type>::node_type* node,
474 log_level_type level)
475 {
476 #if(PVLOGGER_ENABLE)
477 uint32 num_children = node->children.size();
478
479 for (uint32 i = 0; i < num_children; i++)
480 {
481 Oscl_TagTree<PVLogger*, alloc_type>::node_ptr child = (node->children)[i];
482
483 PVLogger* tmpPVLoggerNode = child->value;
484 tmpPVLoggerNode->SetLogLevel(level);
485 SetNodeLogLevelExplicit(child, level);
486 }
487 #else
488 OSCL_UNUSED_ARG(node);
489 OSCL_UNUSED_ARG(level);
490 #endif
491 };
492