(20160604)開源第三方學習之CocoaLumberjack

来源:http://www.cnblogs.com/wujy/archive/2016/06/30/5629883.html
-Advertisement-
Play Games

CocoaLumberjack是一個很好用的日誌列印工具,它可以幫助我們把工程中的日誌信息列印到終端或者輸出到文件中。 地址:https://github.com/CocoaLumberjack/CocoaLumberjack 類圖: 一:插件的運用 因為網上已經對CocoaLumberjack的運 ...


CocoaLumberjack是一個很好用的日誌列印工具,它可以幫助我們把工程中的日誌信息列印到終端或者輸出到文件中。

地址:https://github.com/CocoaLumberjack/CocoaLumberjack

類圖:

 

 

 

一:插件的運用

因為網上已經對CocoaLumberjack的運用都有很詳細的介紹,有部分內容整理源自於網路結合項目中的運用進行講解;

1.1:DDLog輸出的類型

DDLog:基礎類,必須引入的。
DDASLLogger:支持將調試語句寫入到蘋果的日誌中。一般正對Mac開發。可選。
DDTTYLogger:支持將調試語句寫入xCode控制台。我們即使要用它。可選。
DDFileLogger:支持將調試語句寫入到文件系統。可選。

1.2: DDLog日誌等級種類

DDLogError:定義輸出錯誤文本
DDLogWarn:定義輸出警告文本
DDLogInfo:定義輸出信息文本
DDLogDebug:定義輸出調試文本
DDLogVerbose:定義輸出詳細文本

提供的日誌級別為:
LOG_LEVEL_ERROR:只顯示錯誤日誌。
LOG_LEVEL_WARN:包括:LOG_LEVEL_ERROR
LOG_LEVEL_INFO:包括:LOG_LEVEL_WARN
LOG_LEVEL_DEBUG:包括:LOG_LEVEL_INFO
LOG_LEVEL_VERBOSE:包括:LOG_LEVEL_DEBUG
LOG_LEVEL_OFF:關閉日誌

1.3: 設置不同等級顏色

[[DDTTYLogger sharedInstance] setColorsEnabled:YES];// 啟用顏色區分

[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor grayColor] forFlag:DDLogFlagVerbose]; //設置文字為白色,背景為灰色。
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:[UIColor whiteColor] forFlag:DDLogFlagDebug];
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor cyanColor] backgroundColor:[UIColor blueColor] forFlag:DDLogFlagInfo];
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor lightGrayColor] backgroundColor:[UIColor orangeColor] forFlag:DDLogFlagWarning];
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor redColor] forFlag:DDLogFlagError];

註意:顯示顏色是指針對XCode控制台的輸出顯示,還要結合插件XcodeColors(地址:https://github.com/robbiehanson/XcodeColors);然後要增加如下的setenv代碼,它的位置放在上面,否則將沒有效果;

setenv("XcodeColors", "YES", 0);
[DDLog addLogger:[DDTTYLogger sharedInstance]];

1.4:設置輸出日誌的格式

因為在輸出時我們希望獲得更多的信息,DDLog可以自定義設置一個格式,從而獲得日誌詳細信息;下麵這個類是我們項目中運用:

ZULoggerFormatter* formatter = [[ZULoggerFormatter alloc] init];
[[DDTTYLogger sharedInstance] setLogFormatter:formatter]; //目前是在DDTTYLogger類型上顯示,也可以加到輸入到文件時

格式類:ZULoggerFormatter

@interface ZULoggerFormatter: NSObject<DDLogFormatter>
@end


#import "ZULoggerFormatter.h"
#import "NSDate+Utilities.h"


@implementation ZULoggerFormatter {

}

- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {

  NSString *logLevel = nil;
  switch (logMessage.flag) {
    case DDLogFlagError:
      logLevel = @"[ERROR]";
      break;
    case DDLogFlagWarning:
      logLevel = @"[WARN]";
      break;
    case DDLogFlagInfo:
      logLevel = @"[INFO]";
      break;
    case DDLogFlagDebug:
      logLevel = @"[DEBUG]";
      break;
    default:
      logLevel = @"[VBOSE]";
      break;
  }

  NSString *formatStr
      = [NSString stringWithFormat:@"%@ %@ [%@][line %ld] %@ %@", logLevel, [logMessage.timestamp stringWithFormat:@"yyyy-MM-dd HH:mm:ss.S"], logMessage.fileName, logMessage.line, logMessage.function, logMessage.message];
  return formatStr;
}
@end

1.5 設置巨集取代NSLog

#if Product || Local
#define NSLog(...) DDLogVerbose(__VA_ARGS__)
#define Log(...) DDLogVerbose(__VA_ARGS__)
#else
#define NSLog(...) {}
#define Log(...) {}
#endif

#define LogError(...) DDLogError(__VA_ARGS__)

這樣就可以把項目中那些NSLog也替換成DDLogVerbose級別的錯誤;

1.6 設置不同環境輸出日誌等級

#if Product ||Local
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_ERROR;
#endif

1.7 設置輸出到文件

- (DDFileLogger *)fileLogger
{
    if (!_fileLogger) {
        DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
        fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling
        fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
        
        _fileLogger = fileLogger;
    }
    return _fileLogger;
}

如果沒有設置,它是有提供相應的預設值:

unsigned long long const kDDDefaultLogMaxFileSize      = 1024 * 1024;      // 1 MB  一個文件大小
NSTimeInterval     const kDDDefaultLogRollingFrequency = 60 * 60 * 24;     // 24 Hours  一天
NSUInteger         const kDDDefaultLogMaxNumLogFiles   = 5;                // 5 Files  五個
unsigned long long const kDDDefaultLogFilesDiskQuota   = 20 * 1024 * 1024; // 20 MB  總共

如果有存儲路徑(可以設置paths):

NSString *appName = [[NSProcessInfo processInfo] processName];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? paths[0] : NSTemporaryDirectory();
NSString *logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName];

1.8 分享項目用到的日誌管理類

#import <Foundation/Foundation.h>
#import <CocoaLumberjack.h>
#import "ZULoggerFormatter.h"

@interface MyFileLogger : NSObject
@property (nonatomic, strong, readwrite) DDFileLogger *fileLogger;

+(MyFileLogger *)sharedManager;

@end



#import "MyFileLogger.h"

@implementation MyFileLogger

#pragma mark - Inititlization
- (instancetype)init
{
    self = [super init];
    
    if (self) {
        [self configureLogging];
    }
    return self;
}

#pragma mark 單例模式

static MyFileLogger *sharedManager=nil;

+(MyFileLogger *)sharedManager
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedManager=[[self alloc]init];
    });
    return sharedManager;
}


#pragma mark - Configuration

- (void)configureLogging
{
    setenv("XcodeColors", "YES", 0);
    [DDLog addLogger:[DDASLLogger sharedInstance]];
    [DDLog addLogger:[DDTTYLogger sharedInstance]];
    [[DDTTYLogger sharedInstance] setColorsEnabled:YES];
    [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor blueColor] backgroundColor:nil forFlag:DDLogFlagInfo];
    [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor purpleColor] backgroundColor:nil forFlag:DDLogFlagDebug];
    [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:nil forFlag:DDLogFlagError];
    [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor greenColor] backgroundColor:nil forFlag:DDLogFlagVerbose];
    ZULoggerFormatter* formatter = [[ZULoggerFormatter alloc] init];
    [[DDTTYLogger sharedInstance] setLogFormatter:formatter];
    [DDLog addLogger:self.fileLogger];
}

#pragma mark - Getters

- (DDFileLogger *)fileLogger
{
    if (!_fileLogger) {
        DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
        fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling
        fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
        
        _fileLogger = fileLogger;
    }
    
    return _fileLogger;
}
@end

 

二:知識點

2.1 關於等級包含的設置,DDLogLevelAll顯示所有,基它則依次降底跟相互包含;可以通過這個代碼瞭解到枚舉的設置;

typedef NS_OPTIONS(NSUInteger, DDLogFlag){
    /**
     *  0...00001 DDLogFlagError
     */
    DDLogFlagError      = (1 << 0),
    
    /**
     *  0...00010 DDLogFlagWarning
     */
    DDLogFlagWarning    = (1 << 1),
    
    /**
     *  0...00100 DDLogFlagInfo
     */
    DDLogFlagInfo       = (1 << 2),
    
    /**
     *  0...01000 DDLogFlagDebug
     */
    DDLogFlagDebug      = (1 << 3),
    
    /**
     *  0...10000 DDLogFlagVerbose
     */
    DDLogFlagVerbose    = (1 << 4)
};

/**
 *  Log levels are used to filter out logs. Used together with flags.
 */
typedef NS_ENUM(NSUInteger, DDLogLevel){
    /**
     *  No logs
     */
    DDLogLevelOff       = 0,
    
    /**
     *  Error logs only
     */
    DDLogLevelError     = (DDLogFlagError),
    
    /**
     *  Error and warning logs
     */
    DDLogLevelWarning   = (DDLogLevelError   | DDLogFlagWarning),
    
    /**
     *  Error, warning and info logs
     */
    DDLogLevelInfo      = (DDLogLevelWarning | DDLogFlagInfo),
    
    /**
     *  Error, warning, info and debug logs
     */
    DDLogLevelDebug     = (DDLogLevelInfo    | DDLogFlagDebug),
    
    /**
     *  Error, warning, info, debug and verbose logs
     */
    DDLogLevelVerbose   = (DDLogLevelDebug   | DDLogFlagVerbose),
    
    /**
     *  All logs (1...11111)
     */
    DDLogLevelAll       = NSUIntegerMax
};

增加相應的巨集進行處理

#define NSLogError(frmt, ...)    do{ if(DD_NSLOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0)
#define NSLogWarn(frmt, ...)     do{ if(DD_NSLOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0)
#define NSLogInfo(frmt, ...)     do{ if(DD_NSLOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0)
#define NSLogDebug(frmt, ...)    do{ if(DD_NSLOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0)
#define NSLogVerbose(frmt, ...)  do{ if(DD_NSLOG_LEVEL >= 5) NSLog((frmt), ##__VA_ARGS__); } while(0)

2.2:進程類NSProcessInfo方法

+(NSProcessInfo*)processInfo  //返回當前進程的信息
-(NSArray*)arguments  //以NSString對象數組的形式返回當前進程的參數
-(NSDictionary *)environment  //返回變數/值對詞典,以描述當前的環境變數(比如PATH和HOME)及其值
-(int)processIdentifier  //返回進程標識符,它是操作系統賦予進程的唯一數字,用於識別每個正在運行的進程
-(NSString*)processName  //返回當前正在執行的進程名稱
-(NSString *)globallyUniqueString  //每次調用這個方法時,都返回不同的單值字元串,可以用這個字元串生成單值臨時文件名
-(NSString *)hostname  //返回主機系統的名稱(在筆者的Mac OS x系統中,返回的是mac-mato-ipad.local)
-(NSUInteger)operatingSystem  //返回表示操作系統的數字(在筆者的Mac OS x系統中,返回的是5)
-(NSString *)operatingSystemName  //返回操作系統的名稱(筆者的Mac OS x系統中返回NSMACHOperatingSystem,可能返回的值定義在NSProgressInfo.h文件中)
-(NSString *)operatingSystemVersionString  //返回操作系統的當前版本(筆者的Mac OS x系統中返回Version 10.7.5 (Build 11G56))
-(void)setProcessName:(NSString *)name  //將當前進程名稱設置為name。應該謹慎地使用這個方法,應為關於進程名稱存在一些假設(比如用戶預設的設置)
例如:

NSString *appName = [[NSProcessInfo processInfo] processName];

2.3: lengthOfBytesUsingEncoding:NSUTF8StringEncoding

用於計算含有中英文的字元串長度,包含一個中文字用上面的方法時會轉化成三個位元組,其它一個位元組;

int len = [textField.text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 交叉編譯 在一個平臺上去編譯另一個平臺上可以執行的本地代碼 cpu平臺 arm x86 mips 操作系統平臺 windows linux mac os 原理 模擬不同平臺的特性去編譯代碼 jni開發工具: ndk native develop kit NDK目錄 docs--幫助文檔 platfo ...
  • 1.編碼不對 a.對某文件或某工程更改編碼: 滑鼠移到工程名或文件名,右鍵->Properties->Resource->Text file enCoding ->更改編碼(GBK、UTF-8等)->Apply->OK退出 b.修改整個命名空間的編碼 eclipse菜單欄->Window->Pref ...
  • 看這篇博客時 "最快讓你上手ReactiveCocoa之基礎篇" 看到作者介紹鏈式編程那一塊,發現自己的鑽研精神不足。想想自己使用鏈式編程也有段時間了,對,就是 Masonry 庫。自己一直享受點語法帶來的效率提升,卻沒想過自己去照著實現一下,真是慚愧。 好吧,本著發現問題就要立即解決問題的一貫原則 ...
  • 工程在經過多人後,往往會出現較多的垃圾,導致打包出來的ipa文件偏大,有時候我們會通過清理代碼來給程式瘦身,而瘦身ipa效果明顯的,主要通過清理程式里的無用圖片。 推薦一個清理圖片的應用 https://github.com/tinymind/LSUnusedResources 直接打開運行,點擊B ...
  • JNI簡介 JNI (Java Native Interface),Java的本地介面 JNI是Java眾多開發技術中的一門,意在利用本地代碼,為Java程式提供 更高效,更靈活的拓展。應用場景包括:對運行效率敏感的演算法實現、跨平臺應用移植、調用系統的底層驅動、調用硬體等。儘管Java一貫以其良好的 ...
  • 本文為原創文章,轉載請註明出處。 文章最後附帶DEMO,請需要的朋友下載。 從API 17開始,Android提供了Presentation類,為多屏異顯開發提供了官方支持,當然最終需求的實現也需要底層硬體及驅動的支持。 基本需求:控制輔屏全屏顯示與主顯不同的內容,且當主顯全屏顯示的內容變化後對輔屏 ...
  • PS:註意事項 一些坑在此聲明: 1、安裝Eclipse後,記得設置各項編碼格式為utf-8 請移步:http://www.blogjava.net/xiaomage234/archive/2014/05/13/413626.html(我也是網上查閱的~~) 2、下載Android SDK時需要翻牆 ...
  • 一、背景 很久之前就想寫一篇文章來記錄Cordova的使用了,上次用到它是在一年前,這次用到它是在這個月。下次用到它還不知道是什麼時候了,為了供以後翻閱,在此做個記錄。現在很多資料都是在硬碟里、網路收藏夾里。這次就一次性彙總到這裡吧。 二、簡介 Cordova提供了一組設備相關的API,通過這組AP ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...