CocoaLumberjack的全局日志级别

我正在iPhone项目中使用CocoaLumberjack来logging一些信息。

我按照入门指南 ,一切正常,但有一件事情让我感到困惑:似乎没有一个优雅的方式来定义整个应用程序的日志级别。 为了使它工作,我需要在每个源文件中定义一个常量,如下所示:

static const int ddLogLevel = LOG_LEVEL_VERBOSE; 

那么,有没有办法为应用程序定义全局日志级别?

我发现这篇文章的主题,但我仍然需要在每个文件中添加#import …

您可以在* .pch文件中使用#include语句,以便它自动包含在所有项目的文件中。

我没有find比我在这个问题中提到的文章中解释的更好的办法。

Constant.h

 extern int const ddLogLevel; 

Constant.m

 #import "Constants.h" #import "DDLog.h" int const ddLogLevel = LOG_LEVEL_VERBOSE; 

logging器configuration

 #import "DDLog.h" #import "DDASLLogger.h" #import "DDTTYLogger.h" #import "DDFileLogger.h" ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [DDLog addLogger:[DDASLLogger sharedInstance]]; [DDLog addLogger:[DDTTYLogger sharedInstance]]; DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; [DDLog addLogger:fileLogger]; [fileLogger release]; ... 

导入你的class级

 #import "DDLog.h" #import "Constants.h" ... - (void)someMethod { DDLogVerbose(@"Log this message"); } 

没有更多的前缀头,请。

您不需要现在已弃用的.pch文件,只需在需要的地方包含一个头文件即可。

Logger.h – CocoaLumberjack 1.9.x

 #ifndef Project_Logger_h #define Project_Logger_h #if defined(__OBJC__) #import <CocoaLumberjack/DDLog.h> extern int ddLogLevel; #endif #endif 

Logger.m

 #import "Logger.h" int ddLogLevel = LOG_LEVEL_VERBOSE; 

CocoaLumberjack 2.x的更改

 #import <CocoaLumberjack/CocoaLumberjack.h> int ddLogLevel = DDLogLevelVerbose; 

如果2.0版本的testing版本发生变化,请评论或编辑。

AppDelegate中的示例用法

 #import "AppDelegate.h" #import "Logger.h" #import <CocoaLumberjack/DDFileLogger.h> #import <CocoaLumberjack/DDASLLogger.h> #import <CocoaLumberjack/DDTTYLogger.h> @interface AppDelegate () @property (strong, nonatomic) DDFileLogger *fileLogger; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [DDLog addLogger:[DDASLLogger sharedInstance]]; [DDLog addLogger:[DDTTYLogger sharedInstance]]; DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling fileLogger.logFileManager.maximumNumberOfLogFiles = 7; [DDLog addLogger:fileLogger]; self.fileLogger = fileLogger; DDLogDebug(@"%s", __PRETTY_FUNCTION__); return YES; } - (void)applicationWillResignActive:(UIApplication *)application { DDLogDebug(@"%s", __PRETTY_FUNCTION__); } - (void)applicationDidEnterBackground:(UIApplication *)application { DDLogDebug(@"%s", __PRETTY_FUNCTION__); } - (void)applicationWillEnterForeground:(UIApplication *)application { DDLogDebug(@"%s", __PRETTY_FUNCTION__); } - (void)applicationDidBecomeActive:(UIApplication *)application { DDLogDebug(@"%s", __PRETTY_FUNCTION__); } - (void)applicationWillTerminate:(UIApplication *)application { DDLogDebug(@"%s", __PRETTY_FUNCTION__); } 

您可以在您的* .pch文件中使用它来根据您当前的构buildconfiguration自动获取不同的全局日志级别。[for xcode 4+]

 #ifdef DEBUG static const int ddLogLevel = LOG_LEVEL_VERBOSE; #else static const int ddLogLevel = LOG_LEVEL_WARN; #endif 

或者如果每个logging器都需要不同的日志级别,可以使用DDLog + addLogger:withLogLevel:方法轻松实现。

 [DDLog addLogger:[DDASLLogger sharedInstance] withLogLevel:LOG_LEVEL_INFO]; [DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:LOG_LEVEL_DEBUG]; 

在您提到的每个源文件中定义日志级别都有好处。 您可以使用详细日志logging级别仅用于当前正在处理的部分。 对于rest部分,您可以使用其他级别的信息,警告,错误。

为了dynamic注入日志级别(例如,从configuration文件):

1)用下面的代码创build一个名为DDLogLevel的新类:

 #import "DDLogLevel.h" #import "DDLog.h" @implementation DDLogLevel static int _ddLogLevel = LOG_LEVEL_VERBOSE; + (int)ddLogLevel { return _ddLogLevel; } + (void)ddSetLogLevel:(int)logLevel { _ddLogLevel = logLevel; } @end 

2)在DDLogLevel.h中,find包含以下语句的行:

 #ifndef LOG_LEVEL_DEF #define LOG_LEVEL_DEF ddLogLevel #endif 

并将其replace为:

 #ifndef LOG_LEVEL_DEF #define LOG_LEVEL_DEF [DDLogLevel ddLogLevel] #endif 

3)最后,从您的初始化过程(也许从appDelegate)调用具有所需级别的ddSetLogLevel。

global log level和可选的local log level共享我的CocoaLumberjack 2.0.0的configuration与保留的DynamicLogLevelsfunction 。

我的解决scheme包括简单的头文件DSLogging.h (和它的副本),导入CocoaLumberjack.h并定义便利macros来设置使用CocoaLumberjack日志macros的文件。 这里是你应该如何使用它:

  1. 导入DSLogging.h标题(两种方式):
    • 在每个使用CocoaLumberjack的文件中导入它。 就像本地框架文档提出的一样 。
    • 导入.pch文件一次。 这样做之前考虑这个 。
  2. 使用DSLogLevelSetup...macros设置文件的日志级别。 注意:每个使用日志的源文件中都应该有macros。

查看里面的文档了解更多细节。 下载要点 。

DSLogging.h标题:

 // // Created by DanSkeel on 23.04.15. #import "CocoaLumberjack.h" #define DS_LogScopeGlobal extern #define DS_LogScopeLocal static #define DS_LogMutableYes #define DS_LogMutableNo const #define DS_LogValueGlobal ; #define DS_LogValueLocal(lvl) = lvl #define DS_Setup_Log(scope, mutablility, value) scope mutablility DDLogLevel ddLogLevel value /** To setup loggin enviroment for particular file use one of these macros * * @note Use CocoaLumberjack as usual (https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/GettingStarted.md): * * 1. just import DSLoggin.h in source file instead of CocoaLumberjack.h * * 2. Use one of these macros to setup loggin enviroment for the file. * Note: there should one of these macros in EACH file that uses CocoaLumberjack macroses. * @example To enable logging for file with globally defined level you can make convinient snippet: * @code * #import "DSLogging.h" * DSLogLevelSetupGlobal * @endcode * * Use @b SetupGlobal to setup files that will use global level from @p DSLogging.m file * * Use @b SetupMutableGlobal to be able to change global level at runtime (assign new level to ddLogLevel variable) * * Use @b Setup(DDLogLevel) to set local log level * * Use @b SetupMutable(DDLogLevel) to be able to modify local level at runtime ((assign new level to ddLogLevel variable)) * * This approach preserves a lot of CocoaLumberjack advantages. See SO https://stackoverflow.com/a/29837945/991816 * * @remarks details: these macros just help you define/reference ddLogLevel value. So if you * see warning about <i> undeclared identifier </i> it should remind you to use one of these macros in this file. */ extern char optionClickMeToSeePrettyDoc; #define DSLogLevelSetupMutableGlobal DS_Setup_Log(DS_LogScopeGlobal, DS_LogMutableYes, DS_LogValueGlobal) #define DSLogLevelSetupGlobal DS_Setup_Log(DS_LogScopeGlobal, DS_LogMutableNo, DS_LogValueGlobal) #define DSLogLevelSetupMutable(lvl) DS_Setup_Log(DS_LogScopeLocal, DS_LogMutableYes, DS_LogValueLocal(lvl)) #define DSLogLevelSetup(lvl) DS_Setup_Log(DS_LogScopeLocal, DS_LogMutableNo, DS_LogValueLocal(lvl)) 

DSLogging.m来源:

 // // Created by DanSkeel on 23.04.15. #import "DSLogging.h" DDLogLevel ddLogLevel = DDLogLevelVerbose; 

为什么我认为这是一个好方法:

  1. 这比CocoaLumberjack好一点

    • 全球水平(可变)
    • 允许您按地域级别“覆盖”全局级别(可以是可变的)
  2. 它不会削减CocoaLumberjackfunction

    • 使用variables来设置级别,所以它可以用于CocoaLumberjack的高级function。

我是CocoaLumberjack的新手,对于我的方法我可以太乐观,如果我在某个时候说谎,听到你的批评者会很高兴。

我这样做的方式是从这个答案的启发..但是,这是我做了不同的方式,所以我可以有一个全球级日志级别, 能够覆盖每个文件中的全局日志级别,如果我这样select:

  • 而不是调用文件Constants.h我称之为GlobalDebugLevel.h 。 这是因为在这个文件中包含任何其他的全局常量是没有意义的,除非你真的总是使用全局debugging级别,并且没有用于文件特定的日志级别。
  • 在我想拥有它自己的日志级别的文件..我只是注释掉`#import“GlobalLogLevel.h”,然后包括这样的东西:

static const int ddLogLevel = LOG_LEVEL_VERBOSE;

大家都开心:)

PS这是一个.pch免费的解决scheme.. .pch我试过,但然后编译器会抱怨, ddLogLevel已经定义,只要我想在文件级别覆盖它

有一个更简单的方法来解决这个问题,你可以设置logging器实例的日志级别:

 #ifdef DEBUG [DDLog addLogger:[DDTTYLogger sharedInstance] withLevel:DDLogLevelDebug]; #else [DDLog addLogger:[DDTTYLogger sharedInstance] withLevel:DDLogLevelError]; #endif 

所以不需要额外的导入或.pch文件。

这是一个dynamic的日志logging示例,它使用DanSkeels DSLogging代码,如下所示:

GFDPerson.h

 #import <Foundation/Foundation.h> @interface GFDPerson : NSObject{ @protected NSArray *pLogLevelNames; NSArray *pLogLevelKeys; NSDictionary *pLogLevels; } -(void)logPerson; -(void)setLogLevel:(NSUInteger)logLevel; @end 

GFDPerson.m

 #import "GFDPerson.h" #import "DSLogging.h" DSLogLevelSetupMutable(DDLogLevelWarning); @implementation GFDPerson -(id)init{ if (self = [super init]) { pLogLevelNames = [[NSArray alloc] initWithObjects: @"no logging", @"only errors", @"errors and warnings", @"errors, warnings and infos", @"verbose", nil]; pLogLevelKeys = [[NSArray alloc] initWithObjects: [[NSNumber numberWithInteger:DDLogLevelOff]stringValue], [[NSNumber numberWithInteger:DDLogLevelError]stringValue], [[NSNumber numberWithInteger:DDLogLevelWarning]stringValue], [[NSNumber numberWithInteger:DDLogLevelInfo]stringValue], [[NSNumber numberWithInteger:DDLogLevelVerbose]stringValue], nil]; pLogLevels = [[NSDictionary alloc]initWithObjects:pLogLevelNames forKeys:pLogLevelKeys]; return self; } return nil; } -(void)setLogLevel:(NSUInteger)logLevel{ ddLogLevel = logLevel; } -(void)logPerson{ NSLog(@"Person is logging with Loglevel: %@",[pLogLevels valueForKey: [[NSNumber numberWithInteger:ddLogLevel]stringValue]]); DDLogVerbose(@"Person log verbose"); DDLogInfo(@"Person log info"); DDLogWarn(@"Person log warning"); DDLogError(@"Person log error"); DDLogDebug(@"Person log debug"); } @end 

的main.m

 #import <Foundation/Foundation.h> #import "DSLogging.h" #import "GFDPerson.h" DSLogLevelSetupMutable(DDLogLevelError); int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... [DDLog addLogger:[DDASLLogger sharedInstance]]; [DDLog addLogger:[DDTTYLogger sharedInstance]]; ddLogLevel = DDLogLevelWarning; NSLog(@"Warning:"); DDLogWarn(@"WARNING LOG!"); DDLogError(@"ERROR LOG!"); DDLogVerbose(@"VERBOSE LOG!"); ddLogLevel = DDLogLevelError; NSLog(@"Error:"); DDLogWarn(@"WARNING LOG!"); DDLogError(@"ERROR LOG!"); DDLogVerbose(@"VERBOSE LOG!"); ddLogLevel = DDLogLevelOff; NSLog(@"Off:"); DDLogWarn(@"WARNING LOG!"); DDLogError(@"ERROR LOG!"); DDLogVerbose(@"VERBOSE LOG!"); ddLogLevel = DDLogLevelVerbose; NSLog(@"Verbose:"); DDLogWarn(@"WARNING LOG!"); DDLogError(@"ERROR LOG!"); DDLogVerbose(@"VERBOSE LOG!"); ddLogLevel = DDLogLevelOff; GFDPerson *personA = [[GFDPerson alloc] init]; [personA logPerson]; [personA setLogLevel:DDLogLevelVerbose]; [personA logPerson]; [personA setLogLevel:DDLogLevelError]; [personA logPerson]; } return 0; } 

这个代码的输出:

 Warning: WARNING LOG! ERROR LOG! Error: ERROR LOG! Off: Verbose: WARNING LOG! ERROR LOG! VERBOSE LOG! Person is logging with Loglevel: errors and warnings Person log warning Person log error Person is logging with Loglevel: verbose Person log verbose Person log info Person log warning Person log error Person log debug Person is logging with Loglevel: only errors Person log error 

请评论,如果我误解或误用了一些东西…

CocoaLumberjack中包含一个示例应用程序,显示如何设置全局日志级别,您可以在这里findhttps://github.com/robbiehanson/CocoaLumberjack/tree/master/Xcode/GlobalLogLevel

如FreeAsInBeer回答,你可以在.pch文件中定义这个常量。 您可以在.pch文件中这样做。

 // include Lumberjack header file #import <Lumberjack/Lumberjack.h> // define ddLogLevel constant static const int ddLogLevel = LOG_LEVEL_VERBOSE; 

我的工具,我创build一个新的头文件(例如mylog.h)自定义伐木工人设置。 通过这种方式,我在我的.pch文件中使用#import语句来包含mylog.h。 这个自定义头文件可能会这样。

 // include Lumberjack header file #import "Lumberjack.h" #undef ZEKit_LOG_LEVEL #if defined (DEBUG) && (DEBUG == 1) #define ZEKit_LOG_LEVEL LOG_LEVEL_VERBOSE #else #define ZEKit_LOG_LEVEL LOG_LEVEL_WARN #endif static const int ddLogLevel = ZEKit_LOG_LEVEL; // ... Other custom settings 
Interesting Posts