1

I've started using CocoaLumberjack and was interested in using their custom log levels feature. They have a handy config available at https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomLogLevels to get you started. I don't know exactly what I want right now, so I left it as is.

Next I set my debug level in my code using this...

static const int ddLogLevel = LOG_LEVEL_DEBUG;

However with this set up it appears only messages of GREATER severity than LOG_LEVEL_DEBUG get presented. Meaning calls to DDLogInfo() and above show up, but not DDLogDebug(). This is also true as I slide upwards. So...

static const int ddLogLevel = LOG_LEVEL_INFO;

...ignores DDLogInfo() and DDLogDebug(), but shows for DDLogNotice() and higher. Surely the expected behavior is to be inclusive of that warning level.

Here's the code deep inside CocoaLumberjack that makes the decision...

for (DDLoggerNode *loggerNode in loggers) {
    // skip the loggers that shouldn't write this message based on the logLevel

    if (!(logMessage->logFlag & loggerNode.logLevel)) {
        continue;
    }

    dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool {

        [loggerNode->logger logMessage:logMessage];

    }});
}

In my first example, my log level is 111111 (63) and message flag (using DDLogDebug()) is 100000 (32). 63 & 32 is YES, so this fails (with the NOT). So I would think the message would get logged. Moving the log method up to DDLogInfo() which has a message flag of 010000 (16). This is still YES and therefore fails with the NOT, so we get logged. But I see it in this case. Anyone have any experience with this?

oguz ismail
  • 1
  • 16
  • 47
  • 69
rob5408
  • 2,972
  • 2
  • 40
  • 53
  • I've just tested this in my own project using Lumberjack, and I can confirm that it works as you *expect* it should. If I set the level to e.g. `LOG_LEVEL_WARN`, then I see all warnings and above. If I set it to `LOG_LEVEL_INFO`, I see all info and above. Have you added any extra code to customize / alter the log levels yourself? – James Frost Jan 23 '14 at 07:57
  • @JamesFrost, the only modification was using CL's "MYLog.h" which is available at that link above. I switched back to their normal handling and it indeed works fine. It must be a problem with how they create the bitmasks for their "custom" levels. – rob5408 Jan 23 '14 at 13:48

2 Answers2

1

I think I've worked it out. In CocoaLumberjack itself, in DDLog.h, the log level flags are defined like so:

#define LOG_FLAG_ERROR    (1 << 0)  // 0...00001
#define LOG_FLAG_WARN     (1 << 1)  // 0...00010
#define LOG_FLAG_INFO     (1 << 2)  // 0...00100
#define LOG_FLAG_DEBUG    (1 << 3)  // 0...01000
#define LOG_FLAG_VERBOSE  (1 << 4)  // 0...10000

However, the CustomLogLevels MyLog.h file defines them like so:

#define LOG_FLAG_FATAL   (1 << 0)  // 0...000001
#define LOG_FLAG_ERROR   (1 << 1)  // 0...000010
#define LOG_FLAG_WARN    (1 << 2)  // 0...000100
#define LOG_FLAG_NOTICE  (1 << 3)  // 0...001000
#define LOG_FLAG_INFO    (1 << 4)  // 0...010000
#define LOG_FLAG_DEBUG   (1 << 5)  // 0...100000

Note that it adds an extra FATAL flag, which has the effect of shifting all of the other flags down a place. This is the cause of the issue you were seeing.

James Frost
  • 6,960
  • 1
  • 33
  • 42
  • Hi James, also in MyLog.h everything first gets #undef'd so I don't think that's it. I think it actually has to do with the way that MyLog.h builds each level. They OR the previous LEVEL with the current FLAG and keep doing that for each FLAG. In DDLog.h they OR every FLAG together for each LEVEL. While hand executing this doesn't come up with any difference, it's the only thing different between the two approaches. I could probably confirm this by just changing MyLog.h to the same technique, but I've moved on. :/ Thanks for the help! – rob5408 Jan 28 '14 at 16:09
  • Yep, they #undef the existing definitions of the log levels, and then (as in my answer above) they redefine them - but by adding in `LOG_FLAG_FATAL`, they shift all of the other flags down one place. – James Frost Jan 28 '14 at 16:10
  • DDLogDebug, etc are also redefined though. I'd imagine if LOG_FLAG_DEBUG is redefined and DDLogDebug is set to look for that value and then my app sets its log level to LOG_LEVEL_DEBUG, then it would all match up. I guess I'm not following. – rob5408 Jan 28 '14 at 16:43
0

if you have custom levels higher than the inbuilt, try initialising with:

[DDLog addLogger: [DDASLLogger sharedInstance] withLogLevel: LOG_LEVEL_CUSTOM];
[DDLog addLogger: [DDTTYLogger sharedInstance] withLogLevel: LOG_LEVEL_CUSTOM];

where LOG_LEVEL_CUSTOM is defined in your MyLog.h as:

#define LOG_LEVEL_CUSTOM (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_CUSTOM)
DDP
  • 2,463
  • 1
  • 26
  • 28