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 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 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 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 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 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 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 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 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 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 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) 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 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 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 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 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 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 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 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 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 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