Home | History | Annotate | Download | only in src
      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