Статьи

CocoaLumberjack: вход на стероиды

Ведение журнала является одним из наиболее полезных инструментов для проверки, понимания и отладки приложений iOS и OS X. Вы, вероятно, знакомы с функцией NSLog предоставляемой платформой Foundation, но чувствовали ли вы когда-нибудь необходимость в чем-то более мощном? CocoaLumberjack — это библиотека с открытым исходным кодом, созданная и поддерживаемая Робби Хансоном . CocoaLumberjack поднимает ведение журнала на совершенно новый уровень, и в этом уроке я покажу вам, как настроить и использовать CocoaLumberjack в приложении для iOS.


Запись диагностической информации на консоль, в файл или на удаленный сервер широко используется практически при разработке программного обеспечения любого типа. Это одна из самых простых форм отладки, поэтому, вероятно, она так широко распространена. Это первый инструмент, который я использую, когда отлаживаю или пытаюсь понять сложную часть логики независимо от языка. Это легко, быстро и идет с очень небольшими накладными расходами.

Зачем вам использовать CocoaLumberjack, если все, что он делает, это отправляет фрагменты данных на консоль или в файл? Одна из причин заключается в том, что CocoaLumberjack (в основном) быстрее, чем функция NSLog которую предоставляет нам среда Foundation. Благодаря ряду удобных макросов, предоставляемых CocoaLumberjack, переключиться с NSLog на CocoaLumberjack так же просто, как заменить NSLog операторами DDLog .

Еще одним преимуществом CocoaLumberjack является то, что один оператор журнала может быть отправлен нескольким регистраторам (консоль, файл, удаленная база данных и т. Д.). Вы можете настроить CocoaLumberjack таким образом, чтобы он вел себя по-разному в зависимости от конфигурации сборки (Debug, Release и т. Д.). CocoaLumberjack может сделать для вас гораздо больше, поэтому позвольте мне показать вам, как начать работу с этой изящной библиотекой.


Создайте новый проект в Xcode, выбрав шаблон приложения Single View Application из списка доступных шаблонов (рисунок 1). Назовите свое приложение Журналирование , введите идентификатор компании, установите iPhone для семейства устройств, а затем установите флажок Использовать автоматический подсчет ссылок . Остальные флажки могут быть оставлены непроверенными для этого проекта (рисунок 2). Сообщите Xcode, где вы хотите сохранить проект, и нажмите кнопку « Создать» .

CocoaLumberjack: вход на стероиды: выбор шаблона проекта - рисунок 1
CocoaLumberjack: вход на стероиды: настройка нового проекта - рисунок 2

Добавить библиотеку CocoaLumberjack в свой проект так же просто, как загрузить последнюю версию из GitHub , извлечь архив и перетащить папку с именем Lumberjack в свой проект. Основные файлы: DDLog.h / .m , DDASLLogger.h / .m , DDTTYLogger.h / .m и DDFileLogger.h / .m . Другие файлы в папке являются заглушками для более продвинутого использования CocoaLumberjack, о котором я не буду рассказывать в этом руководстве. Вы можете игнорировать или удалять эти файлы.

Если вы возьмете пик внутри DDLog.h и DDLog.m , вы можете быть удивлены количеством строк кода в этих файлах. Как я уже сказал, CocoaLumberjack имеет много действительно полезных функций. CocoaLumberjack более мощный, чем NSLog потому что он использует преимущества многопоточности, Grand Central Dispatch и мощь среды выполнения Objective-C.

Вы также заметите, что в DDLog.h определено удивительное количество макросов. Мы не будем использовать большинство этих макросов. DDLogError , которые мы будем использовать в этом руководстве, являются DDLogError , DDLogWarn , DDLogInfo и DDLogVerbose . Все они выполняют одну и ту же задачу, но каждый макрос связан с уровнем журнала. Я расскажу больше об уровнях журнала через несколько минут.

Прежде чем мы начнем использовать CocoaLumberjack, рекомендуется добавить оператор импорта в предварительно скомпилированный заголовочный файл проекта. Откройте Logging-Prefix.pch и добавьте оператор импорта для DDLog.h . Это гарантирует, что макросы, определенные в DDLog.h, будут доступны по всему проекту.

01
02
03
04
05
06
07
08
09
10
11
12
#import <Availability.h>
 
#ifndef __IPHONE_4_0
#warning «This project uses features only available in iOS SDK 4.0 and later.»
#endif
 
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
 
    #import «DDLog.h»
#endif

Настроить CocoaLumberjack легко. Однако сначала нам нужно импортировать несколько классов библиотеки CocoaLumberjack. В верхней части MTAppDelegate.m добавьте оператор импорта для DDASLLogger.h , DDTTYLogger.h и DDFileLogger.h (см. Ниже). Первые два класса отвечают за отправку сообщений журнала в консольное приложение (Console.app) и консоль Xcode. Класс DDFileLogger заботится о записи сообщений журнала в файл на диске.

1
2
3
4
5
6
#import «MTAppDelegate.h»
 
#import «DDASLLogger.h»
#import «DDTTYLogger.h»
#import «DDFileLogger.h»
#import «MTViewController.h»

В приложении делегата application:didFinishLaunchingWithOptions: метод мы добавляем два регистратора, как показано ниже. Как DDASLLogger и DDTTYLogger являются синглетонами, как вы могли заметить При такой настройке мы имитируем поведение функции NSLog , то есть сообщения журнала отправляются в консольное приложение (Console.app) и консоль Xcode.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
— (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Configure CocoaLumberjack
    [DDLog addLogger:[DDASLLogger sharedInstance]];
    [DDLog addLogger:[DDTTYLogger sharedInstance]];
 
    // Initialize View Controller
    self.viewController = [[MTViewController alloc] initWithNibName:@»MTViewController» bundle:nil];
 
    // Initialize Window
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
    // Configure Window
    [self.window setRootViewController:self.viewController];
    [self.window makeKeyAndVisible];
 
    return YES;
}

Это все, что нам нужно сделать, чтобы начать работу с CocoaLumberjack. Вы можете проверить это, добавив следующие операторы журнала в метод MTViewController класса MTViewController . Создайте и запустите проект в iOS Simulator, чтобы увидеть, все ли работает как положено.

1
2
3
4
5
6
7
8
— (void)viewDidLoad {
    [super viewDidLoad];
 
    DDLogError(@»This is an error.»);
    DDLogWarn(@»This is a warning.»);
    DDLogInfo(@»This is just a message.»);
    DDLogVerbose(@»This is a verbose message.»);
}

Вы также столкнулись с ошибкой компилятора? Ошибка компилятора читает Использование необъявленного идентификатора ‘ddLogLevel’ . Кажется, нам нужно объявить ddLogLevel прежде чем мы сможем использовать CocoaLumberjack. Это на самом деле особенность CocoaLumberjack. Объявляя и динамически присваивая значение ddLogLevel мы можем настроить CocoaLumberjack таким образом, чтобы операторы журнала выполнялись на основе конфигурации сборки. Чтобы понять, что я имею в виду, измените предварительно скомпилированный заголовочный файл нашего проекта ( Logging-Prefix.pch ), как показано ниже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
#import <Availability.h>
 
#ifndef __IPHONE_4_0
#warning «This project uses features only available in iOS SDK 4.0 and later.»
#endif
 
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
 
    #import «DDLog.h»
#endif
 
#ifdef DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_ERROR;
#endif

По умолчанию CocoaLumberjack определяет четыре уровня журнала: (1) ошибка , (2) предупреждение , (3) информация и (4) подробный . Определение уровней журналов очень распространено в библиотеках журналов (например, log4j и log4php). Назначив уровень журнала для оператора журнала, он может быть классифицирован, что очень полезно, как вы увидите ниже. В предварительно скомпилированном заголовочном файле мы объявляем ddLogLevel и присваиваем ему значение. Значение ddLogLevel определяет, какие операторы журнала выполняются, а какие игнорируются. Другими словами, если конфигурация сборки равна Debug (читай: если определен макрос препроцессора DEBUG ), то ddLogLevel равен LOG_LEVEL_VERBOSE , самому LOG_LEVEL_VERBOSE уровню журнала. Это означает, что каждый оператор журнала будет выполнен. Однако, если конфигурация сборки не равна Debug , то выполняются только операторы журнала с уровнем ошибок журнала. Важно знать, что уровни журналов упорядочены, как вы можете видеть в DDLog.h, где они определены.

Почему это полезно? Это обеспечивает очень простой механизм управления тем, что регистрируется, на основе конфигурации сборки. Вы можете попробовать это, изменив текущую активную схему в XCode. Остановите приложение и щелкните активную схему с именем Logging справа от кнопки остановки (рисунок 3). Выберите Edit Scheme … из меню и нажмите Run Logging слева (рисунок 4). На вкладке Info установите конфигурацию сборки на Release (рисунок 4). С этой опцией вы выбираете конфигурацию сборки, которую XCode должен использовать, когда приложение работает в Симуляторе iOS.

CocoaLumberjack: вход на стероиды: выбор активной схемы в Xcode - рисунок 3
CocoaLumberjack: вход на стероиды: редактирование активной схемы в Xcode - рисунок 4

Если вы сейчас соберете и запустите свой проект в симуляторе iOS, вы должны увидеть только операторы журнала с уровнем журнала ошибок, напечатанным в консоли Xcode. Все операторы журнала с уровнем журнала выше, чем ошибка, игнорируются. Имейте в виду, что макрос препроцессора DEBUG назван CONFIGURATION_DEBUG в Xcode 3. Подробнее об этом можно прочитать в вики CocoaLumberjack .


Регистрация в файл — это кусок пирога с CocoaLumberjack. CocoaLumberjack не только прост в настройке, но и имеет ряд полезных опций, таких как ограничение размера файлов журналов и установка частоты смены кадров. Вы даже можете указать CocoaLumberjack удалить старые файлы журнала при создании новых файлов журнала. Позвольте мне показать вам, как это работает.

Пересмотрите приложение делегата application:didFinishLaunchingWithOptions: метод и обновите его реализацию, как показано ниже. После инициализации экземпляра DDFileLogger мы настраиваем его путем (1) установки максимального размера файла каждого файла журнала (в байтах), (2) установки частоты вращения на 24 часа и (3) установки максимального количества файлов журнала это должно быть сохранено до семи. Не забудьте добавить регистратор файлов, как мы делали ранее.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
— (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Configure CocoaLumberjack
    [DDLog addLogger:[DDASLLogger sharedInstance]];
    [DDLog addLogger:[DDTTYLogger sharedInstance]];
 
    // Initialize File Logger
    DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
 
    // Configure File Logger
    [fileLogger setMaximumFileSize:(1024 * 1024)];
    [fileLogger setRollingFrequency:(3600.0 * 24.0)];
    [[fileLogger logFileManager] setMaximumNumberOfLogFiles:7];
    [DDLog addLogger:fileLogger];
 
    // Initialize View Controller
    self.viewController = [[MTViewController alloc] initWithNibName:@»MTViewController» bundle:nil];
 
    // Initialize Window
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
    // Configure Window
    [self.window setRootViewController:self.viewController];
    [self.window makeKeyAndVisible];
 
    return YES;
}

Прежде чем создавать и запускать проект, откройте Finder и перейдите в следующую папку: ~/Library/Application Support/iPhone Simulator/ /Applications/ /Library/Caches/ ~/Library/Application Support/iPhone Simulator/ /Applications/ /Library/Caches/ ~/Library/Application Support/iPhone Simulator/ /Applications/ /Library/Caches/ , Как видите, путь может немного отличаться в зависимости от используемой версии симулятора iOS. Запустите приложение в симуляторе iOS и проверьте содержимое каталога Caches . Теперь он должен иметь папку с именем Logs, содержащую один текстовый файл с именем log-XXXXXX.txt . Последние шесть символов имени файла являются уникальными, чтобы предотвратить перезапись файлов журнала. Можно указать место, где хранятся файлы журнала. Имейте в виду, что каталог Caches может быть очищен операционной системой в любое время. Если вы хотите хранить файлы журналов своего приложения в более безопасном месте, то я предлагаю сохранить их в каталоге документов приложения.


Несмотря на то, что цвета кажутся ничем иным, как приятным глазом, каждый разработчик знает, насколько важны цвета при работе в редакторе кода. С CocoaLumberjack вы можете добавить цвет в консоль Xcode. Робби Хэнсон, создатель CocoaLumberjack, также внес свой вклад в плагин Xcode под названием Xcode Colors . CocoaLumberjack очень хорошо работает с Xcode Colors. Загрузите последнюю версию Xcode Colors , распакуйте архив и поместите его содержимое в папку плагинов Xcode (находится в ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ ) и перезапустите Xcode. Обратите внимание, что может быть необходимо вручную создать папку плагинов, если она отсутствует.

Чтобы включить цвета в консоли Xcode, вернитесь к application:didFinishLaunchingWithOptions: метод и скажите общему экземпляру класса TTYLogger включить цвета (см. Ниже). CocoaLumberjack использует цвета по умолчанию, если вы не указываете цвет для определенного уровня журнала. Переопределить настройки цвета по умолчанию легко, как показано ниже. Запустите приложение в iOS Simulator и осмотрите окно консоли Xcode, чтобы увидеть результат (рисунок 5).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
— (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Configure CocoaLumberjack
    [DDLog addLogger:[DDASLLogger sharedInstance]];
    [DDLog addLogger:[DDTTYLogger sharedInstance]];
 
    // Enable Colors
    [[DDTTYLogger sharedInstance] setColorsEnabled:YES];
    [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor greenColor] backgroundColor:nil forFlag:LOG_FLAG_INFO];
 
    // Initialize File Logger
    DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
 
    // Configure File Logger
    [fileLogger setMaximumFileSize:(1024 * 1024)];
    [fileLogger setRollingFrequency:(3600.0 * 24.0)];
    [[fileLogger logFileManager] setMaximumNumberOfLogFiles:7];
    [DDLog addLogger:fileLogger];
 
    // Initialize View Controller
    self.viewController = [[MTViewController alloc] initWithNibName:@»MTViewController» bundle:nil];
 
    // Initialize Window
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
    // Configure Window
    [self.window setRootViewController:self.viewController];
    [self.window makeKeyAndVisible];
 
    return YES;
}
CocoaLumberjack: вход на стероиды: добавление цвета в консоль Xcode - рисунок 5

Я уже упоминал, что CocoaLumberjack определяет четыре уровня журнала по умолчанию. Однако можно определить пользовательские уровни журнала. Я не буду обсуждать пользовательские уровни журналов в этом руководстве, но если вы хотите узнать больше об этой функции, то я предлагаю вам прочитать статью о пользовательских уровнях журналов в вики CocoaLumberjack.

Сочетание цветов с настраиваемыми уровнями журналов дает очень мощный инструмент для сбора данных и отладки приложения. Имейте в виду, что CocoaLumberjack может предложить гораздо больше, чем то, что я показал в этом коротком руководстве. С CocoaLumberjack вы можете создавать собственные регистраторы, а также настраиваемые средства форматирования. Пользовательские регистраторы особенно полезны, если вы хотите войти в базу данных или отправить файлы журнала на удаленный сервер через регулярные промежутки времени. CocoaLumberjack действительно мощная библиотека, которая стала незаменимым инструментом в моем наборе инструментов.


Регистрация данных приложения и диагностической информации на консоли или в файле может быть очень полезна при устранении проблем как во время разработки, так и в процессе производства. Поэтому необходимо иметь надежное решение для каротажа. Вместе со многими другими разработчиками я создал собственные решения для ведения журналов для многих проектов, но CocoaLumberjack является идеальной заменой и может предложить гораздо больше.