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的文件。 这里是你应该如何使用它:
- 导入
DSLogging.h
标题(两种方式):- 在每个使用CocoaLumberjack的文件中导入它。 就像本地框架文档提出的一样 。
- 导入
.pch
文件一次。 这样做之前考虑这个 。
- 使用
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;
为什么我认为这是一个好方法:
-
这比CocoaLumberjack好一点
- 全球水平(可变)
- 允许您按地域级别“覆盖”全局级别(可以是可变的)
-
它不会削减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