CocoaLumberjack: Anmelden von Steroiden
German (Deutsch) translation by Nikol Angelowa (you can also view the original English article)
Die Protokollierung ist eines der nützlichsten Instrumente zum Überprüfen, Verstehen und Debuggen von iOS- und OS X-Anwendungen. Sie sind wahrscheinlich mit der NSLog-Funktion vertraut, die vom Foundation-Framework bereitgestellt wird, aber haben Sie jemals das Bedürfnis nach etwas Stärkerem verspürt? CocoaLumberjack ist eine Open-Source-Bibliothek, die von Robbie Hanson erstellt und verwaltet wird. CocoaLumberjack bringt die Protokollierung auf ein völlig neues Niveau. In diesem Tutorial werde ich Ihnen zeigen, wie Sie CocoaLumberjack in einer iOS-Anwendung einrichten und verwenden.
Protokollierung? Wer braucht Protokollierung?
Das Protokollieren von Diagnoseinformationen auf einer Konsole, einer Datei oder einem Remote-Server wird in fast jeder Art von Softwareentwicklung häufig verwendet. Es ist eine der einfachsten Formen des Debuggens, weshalb es wahrscheinlich so weit verbreitet ist. Es ist das erste Tool, das ich verwende, wenn ich ein komplexes Stück Logik unabhängig von der Sprache debugge oder zu verstehen versuche. Es ist einfach, schnell und mit sehr wenig Aufwand verbunden.
Warum sollten Sie CocoaLumberjack verwenden, wenn nur Daten an die Konsole oder eine Datei gesendet werden? Ein Grund dafür ist, dass CocoaLumberjack (meistens) schneller ist als die NSLog-Funktion, die uns das Foundation-Framework bietet. Dank einer Reihe praktischer Makros von CocoaLumberjack ist der Wechsel von NSLog zu CocoaLumberjack so einfach, wie das Ersetzen Ihres NSLog durch DDLog-Anweisungen.
Ein weiterer Vorteil von CocoaLumberjack besteht darin, dass eine Protokollanweisung an mehrere Protokollierer (Konsole, Datei, entfernte Datenbank usw.) gesendet werden kann. Sie können CocoaLumberjack so konfigurieren, dass es sich je nach Build-Konfiguration (Debug, Release usw.) unterschiedlich verhält. CocoaLumberjack kann noch viel mehr für Sie tun. Lassen Sie mich Ihnen zeigen, wie Sie mit dieser raffinierten Bibliothek beginnen können.
Schritt 1: Einrichten von CocoaLumberjack
Erstellen Sie ein neues Projekt in Xcode, indem Sie die Single View-Anwendungsvorlage aus der Liste der verfügbaren Vorlagen auswählen (Abbildung 1). Benennen Sie Ihre Anwendung Logging, geben Sie eine Firmenkennung ein, legen Sie das iPhone für die Gerätefamilie fest und aktivieren Sie dann Automatische Referenzzählung verwenden. Die restlichen Kontrollkästchen können für dieses Projekt deaktiviert werden (Abbildung 2). Teilen Sie Xcode mit, wo Sie das Projekt speichern möchten, und klicken Sie auf die Schaltfläche Erstellen.




Das Hinzufügen der CocoaLumberjack-Bibliothek zu Ihrem Projekt ist so einfach wie das Herunterladen der neuesten Version von GitHub, das Extrahieren des Archivs und das Ziehen des Ordners mit dem Namen Lumberjack in Ihr Projekt. Die Kerndateien sind DDLog.h/.m, DDASLLogger.h/.m, DDTTYLogger.h/.m und DDFileLogger.h/.m. Die anderen Dateien im Ordner sind Stubs für fortgeschrittenere Anwendungen von CocoaLumberjack, auf die ich in diesem Tutorial nicht eingehen werde. Sie können diese Dateien ignorieren oder löschen.
Wenn Sie einen Peak in DDLog.h und DDLog.m erstellen, werden Sie möglicherweise von der Anzahl der Codezeilen in diesen Dateien überrascht sein. Wie gesagt, CocoaLumberjack hat viele wirklich nützliche Funktionen. CocoaLumberjack ist leistungsfähiger als NSLog, da es Multithreading, Grand Central Dispatch und die Leistung der Objective-C-Laufzeit nutzt.
Sie werden auch feststellen, dass in DDLog.h überraschend viele Makros definiert sind. Wir werden die meisten dieser Makros nicht verwenden. Die Makros, die wir in diesem Tutorial verwenden, sind DDLogError, DDLogWarn, DDLogInfo und DDLogVerbose. Sie führen alle dieselbe Aufgabe aus, aber jedes Makro ist einer Protokollebene zugeordnet. Ich werde in wenigen Augenblicken mehr über Protokollstufen sprechen.
Bevor wir CocoaLumberjack verwenden, sollten Sie der vorkompilierten Header-Datei des Projekts eine Import-Anweisung hinzufügen. Öffnen Sie Logging-Prefix.pch und fügen Sie eine Importanweisung für DDLog.h hinzu. Dadurch wird sichergestellt, dass die in DDLog.h definierten Makros im gesamten Projekt verfügbar sind.
1 |
#import <Availability.h>
|
2 |
|
3 |
#ifndef __IPHONE_4_0
|
4 |
#warning "This project uses features only available in iOS SDK 4.0 and later."
|
5 |
#endif
|
6 |
|
7 |
#ifdef __OBJC__
|
8 |
#import <UIKit/UIKit.h>
|
9 |
#import <Foundation/Foundation.h>
|
10 |
|
11 |
#import "DDLog.h"
|
12 |
#endif
|
Schritt 2: Hinzufügen eines Loggers
Das Konfigurieren von CocoaLumberjack ist einfach. Zunächst müssen wir jedoch mehrere Klassen der CocoaLumberjack-Bibliothek importieren. Fügen Sie oben in MTAppDelegate.m eine Importanweisung für DDASLLogger.h, DDTTYLogger.h und DDFileLogger.h hinzu (siehe unten). Die ersten beiden Klassen sind für das Senden von Protokollnachrichten an die Konsolenanwendung(Console.app) und die Konsole von Xcode zuständig. Die DDFileLogger-Klasse übernimmt das Schreiben von Protokollnachrichten in eine Datei auf der Festplatte.
1 |
#import "MTAppDelegate.h"
|
2 |
|
3 |
#import "DDASLLogger.h"
|
4 |
#import "DDTTYLogger.h"
|
5 |
#import "DDFileLogger.h"
|
6 |
#import "MTViewController.h"
|
Bei der Benutzung in der Anwendung application:didFinishLaunchingWithOptions: fügen wir zwei Logger hinzu, wie unten gezeigt. Wie Sie vielleicht bemerkt haben, sind sowohl DDASLLogger als auch DDTTYLogger Singletons. Mit diesem Setup ahmen wir das Verhalten der NSLog-Funktion nach, dh Protokollnachrichten werden an die Konsolenanwendung (Console.app) und die Xcode-Konsole gesendet.
1 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
2 |
// Configure CocoaLumberjack
|
3 |
[DDLog addLogger:[DDASLLogger sharedInstance]]; |
4 |
[DDLog addLogger:[DDTTYLogger sharedInstance]]; |
5 |
|
6 |
// Initialize View Controller
|
7 |
self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewController" bundle:nil]; |
8 |
|
9 |
// Initialize Window
|
10 |
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; |
11 |
|
12 |
// Configure Window
|
13 |
[self.window setRootViewController:self.viewController]; |
14 |
[self.window makeKeyAndVisible]; |
15 |
|
16 |
return YES; |
17 |
}
|
Dies ist alles, was wir tun müssen, um mit CocoaLumberjack zu beginnen. Sie können dies testen, indem Sie der viewDidLoad-Methode der MTViewController-Klasse die folgenden Protokollanweisungen hinzufügen. Erstellen Sie das Projekt und führen Sie es im iOS-Simulator aus, um festzustellen, ob alles wie erwartet funktioniert.
1 |
- (void)viewDidLoad { |
2 |
[super viewDidLoad]; |
3 |
|
4 |
DDLogError(@"This is an error."); |
5 |
DDLogWarn(@"This is a warning."); |
6 |
DDLogInfo(@"This is just a message."); |
7 |
DDLogVerbose(@"This is a verbose message."); |
8 |
}
|
Sind Sie auch auf einen Compilerfehler gestoßen? Der Compilerfehler lautet Verwendung des nicht deklarierten Bezeichners 'ddLogLevel'. Es scheint, dass wir ddLogLevel deklarieren müssen, bevor wir CocoaLumberjack verwenden können. Dies ist eigentlich eine Funktion von CocoaLumberjack. Durch Deklarieren und dynamisches Zuweisen eines Werts zu ddLogLevel können wir CocoaLumberjack so konfigurieren, dass Protokollanweisungen basierend auf der Build-Konfiguration ausgeführt werden. Um zu verstehen, was ich meine, ändern Sie die vorkompilierte Header-Datei unseres Projekts (Logging-Prefix.pch) wie unten gezeigt.
1 |
#import <Availability.h>
|
2 |
|
3 |
#ifndef __IPHONE_4_0
|
4 |
#warning "This project uses features only available in iOS SDK 4.0 and later."
|
5 |
#endif
|
6 |
|
7 |
#ifdef __OBJC__
|
8 |
#import <UIKit/UIKit.h>
|
9 |
#import <Foundation/Foundation.h>
|
10 |
|
11 |
#import "DDLog.h"
|
12 |
#endif
|
13 |
|
14 |
#ifdef DEBUG
|
15 |
static const int ddLogLevel = LOG_LEVEL_VERBOSE; |
16 |
#else
|
17 |
static const int ddLogLevel = LOG_LEVEL_ERROR; |
18 |
#endif
|
Standardmäßig definiert CocoaLumberjack vier Protokollebenen: (1) error, (2) warning, (3) info und (4) verbose. Das Definieren von Protokollebenen ist in Protokollierungsbibliotheken (z. B. log4j und log4php) sehr verbreitet. Durch Zuweisen einer Protokollebene zu einer Protokollanweisung kann diese kategorisiert werden. Dies ist sehr nützlich, wie Sie gleich sehen werden. In der vorkompilierten Header-Datei deklarieren wir ddLogLevel und weisen ihr einen Wert zu. Der Wert von ddLogLevel bestimmt, welche Protokollanweisungen ausgeführt und welche ignoriert werden. Mit anderen Worten, wenn die Build-Konfiguration gleich Debug ist (lesen Sie: Wenn das Präprozessor-Makro DEBUG definiert ist), ist ddLogLevel gleich LOG_LEVEL_VERBOSE, der höchsten Protokollstufe. Dies bedeutet, dass jede Protokollanweisung ausgeführt wird. Wenn die Build-Konfiguration jedoch nicht Debug entspricht, werden nur Protokollanweisungen mit einer Protokoll error stufe ausgeführt. Es ist wichtig zu wissen, dass die Protokollebenen geordnet sind, wie Sie in DDLog.h sehen können, wo sie definiert sind.
Warum ist das nützlich? Dies bietet einen sehr einfachen Mechanismus, um zu steuern, was basierend auf der Build-Konfiguration protokolliert wird. Sie können dies ausprobieren, indem Sie das aktuell aktive Schema in Xcode ändern. Stoppen Sie die Anwendung und klicken Sie auf das aktive Schema mit dem Namen Protokollierung rechts neben der Schaltfläche Stopp (Abbildung 3). Wählen Sie im Menü die Option Schema bearbeiten... und klicken Sie links auf Protokollierung ausführen (Abbildung 4). Setzen Sie auf der Registerkarte Info die Build-Konfiguration auf Release (Abbildung 4). Mit dieser Option wählen Sie die Build-Konfiguration aus, die Xcode verwenden soll, wenn die Anwendung im iOS-Simulator ausgeführt wird.




Wenn Sie Ihr Projekt jetzt im iOS-Simulator erstellen und ausführen, sollten nur Protokollanweisungen mit einer Protokoll error-Stufe auf der Xcode-Konsole angezeigt werden. Alle Protokollanweisungen mit einer höheren Protokollstufe als error werden ignoriert. Beachten Sie, dass das DEBUG-Präprozessor-Makro in Xcode 3 CONFIGURATION_DEBUG heißt. Weitere Informationen hierzu finden Sie im Wiki von CocoaLumberjack.
Schritt 3: Anmelden an einer Datei
Das Protokollieren in einer Datei ist mit CocoaLumberjack ein Kinderspiel. Es ist nicht nur einfach es einzurichten, CocoaLumberjack bietet einige nützliche Optionen, z. B. die Begrenzung der Dateigröße von Protokolldateien und die Festlegung einer fortlaufenden Häufigkeit. Sie können CocoaLumberjack sogar anweisen, alte Protokolldateien zu entfernen, wenn neue Protokolldateien erstellt werden. Lassen Sie mich Ihnen zeigen, wie das funktioniert.
Überprüfen Sie die Anwendung des application:didFinishLaunchingWithOptions: method und aktualisieren Sie die Implementierung wie unten gezeigt. Nach dem Initialisieren einer Instanz von DDFileLogger konfigurieren wir sie, indem wir (1) die maximale Dateigröße jeder Protokolldatei (in Byte) festlegen,(2) die Rollfrequenz auf 24 Stunden festlegen und (3) die maximale Anzahl von Protokolldateien festlegen das sollte auf sieben gehalten werden. Vergessen Sie nicht, den Dateilogger wie zuvor hinzuzufügen.
1 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
2 |
// Configure CocoaLumberjack
|
3 |
[DDLog addLogger:[DDASLLogger sharedInstance]]; |
4 |
[DDLog addLogger:[DDTTYLogger sharedInstance]]; |
5 |
|
6 |
// Initialize File Logger
|
7 |
DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; |
8 |
|
9 |
// Configure File Logger
|
10 |
[fileLogger setMaximumFileSize:(1024 * 1024)]; |
11 |
[fileLogger setRollingFrequency:(3600.0 * 24.0)]; |
12 |
[[fileLogger logFileManager] setMaximumNumberOfLogFiles:7]; |
13 |
[DDLog addLogger:fileLogger]; |
14 |
|
15 |
// Initialize View Controller
|
16 |
self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewController" bundle:nil]; |
17 |
|
18 |
// Initialize Window
|
19 |
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; |
20 |
|
21 |
// Configure Window
|
22 |
[self.window setRootViewController:self.viewController]; |
23 |
[self.window makeKeyAndVisible]; |
24 |
|
25 |
return YES; |
26 |
}
|
Öffnen Sie vor dem Erstellen und Ausführen des Projekts den Finder und navigieren Sie zum folgenden Speicherort: ~/Library/Application Support/iPhone Simulator//Applications//Library/Caches/Wie Sie sehen, kann der Pfad je nach verwendeter Version des iOS-Simulators geringfügig abweichen. Führen Sie die Anwendung im iOS-Simulator aus und überprüfen Sie den Inhalt des Caches-Verzeichnisses. Es sollte jetzt einen Ordner mit dem Namen Logs haben, der eine Textdatei mit dem Namen log-XXXXXX.txt enthält. Die letzten sechs Zeichen des Dateinamens sind eindeutig, um zu verhindern, dass Protokolldateien überschrieben werden. Es ist möglich, den Speicherort anzugeben, an dem die Protokolldateien gespeichert sind. Beachten Sie, dass das Caches-Verzeichnis jederzeit vom Betriebssystem geleert werden kann. Wenn Sie die Protokolldateien Ihrer Anwendung an einem sichereren Ort speichern möchten, empfehle ich, sie im Verzeichnis Dokumente der Anwendung zu speichern.
Bonus: Farben
Obwohl Farben nichts anderes als eine Augenweide zu sein scheinen, weiß jeder Entwickler, wie wichtig Farben bei der Arbeit in einem Code-Editor sind. Mit CocoaLumberjack können Sie der Xcode-Konsole Farbe hinzufügen. Robbie Hanson, der Schöpfer von CocoaLumberjack, hat auch zu einem Xcode-Plugin namens Xcode Colors beigetragen. CocoaLumberjack funktioniert sehr gut mit Xcode Colors. Laden Sie die neueste Version von Xcode Colors herunter, extrahieren Sie das Archiv und legen Sie den Inhalt in den Plug-In-Ordner von Xcode (unter ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/) und starten Sie Xcode neu. Beachten Sie, dass der Plug-In-Ordner möglicherweise manuell erstellt werden muss, wenn er nicht vorhanden ist.
Um Farben in der Xcode-Konsole zu aktivieren, kehren Sie zur folgenden zurück application:didFinishLaunchingWithOptions: method und weisen Sie die gemeinsam genutzte Instanz der TTYLogger-Klasse an, Farben zu aktivieren (siehe unten). CocoaLumberjack verwendet Standardfarben, wenn Sie keine Farbe für eine bestimmte Protokollstufe angeben. Das Überschreiben der Standardfarbeinstellungen ist wie unten gezeigt einfach. Führen Sie die Anwendung im iOS-Simulator aus und überprüfen Sie das Konsolenfenster von Xcode, um das Ergebnis anzuzeigen (Abbildung 5).
1 |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
2 |
// Configure CocoaLumberjack
|
3 |
[DDLog addLogger:[DDASLLogger sharedInstance]]; |
4 |
[DDLog addLogger:[DDTTYLogger sharedInstance]]; |
5 |
|
6 |
// Enable Colors
|
7 |
[[DDTTYLogger sharedInstance] setColorsEnabled:YES]; |
8 |
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor greenColor] backgroundColor:nil forFlag:LOG_FLAG_INFO]; |
9 |
|
10 |
// Initialize File Logger
|
11 |
DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; |
12 |
|
13 |
// Configure File Logger
|
14 |
[fileLogger setMaximumFileSize:(1024 * 1024)]; |
15 |
[fileLogger setRollingFrequency:(3600.0 * 24.0)]; |
16 |
[[fileLogger logFileManager] setMaximumNumberOfLogFiles:7]; |
17 |
[DDLog addLogger:fileLogger]; |
18 |
|
19 |
// Initialize View Controller
|
20 |
self.viewController = [[MTViewController alloc] initWithNibName:@"MTViewController" bundle:nil]; |
21 |
|
22 |
// Initialize Window
|
23 |
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; |
24 |
|
25 |
// Configure Window
|
26 |
[self.window setRootViewController:self.viewController]; |
27 |
[self.window makeKeyAndVisible]; |
28 |
|
29 |
return YES; |
30 |
}
|


Ich habe bereits erwähnt, dass CocoaLumberjack standardmäßig vier Protokollebenen definiert. Es ist jedoch möglich, benutzerdefinierte Protokollebenen zu definieren. Ich werde in diesem Tutorial nicht auf benutzerdefinierte Protokollebenen eingehen. Wenn Sie jedoch mehr über diese Funktion erfahren möchten, empfehlen wir Ihnen, den Artikel über benutzerdefinierte Protokollebenen im CocoaLumberjack-Wiki zu lesen.
Das Kombinieren von Farben mit benutzerdefinierten Protokollebenen führt zu einem sehr leistungsstarken Tool zum Sammeln von Daten und Debuggen einer Anwendung. Denken Sie daran, dass CocoaLumberjack viel mehr zu bieten hat als das, was ich in diesem kurzen Tutorial gezeigt habe. Mit CocoaLumberjack können Sie sowohl benutzerdefinierte Logger als auch benutzerdefinierte Formatierer erstellen. Benutzerdefinierte Protokollierer sind besonders nützlich, wenn Sie sich in regelmäßigen Zeitabständen bei einer Datenbank anmelden oder Protokolldateien an einen Remoteserver senden möchten. CocoaLumberjack ist wirklich eine leistungsstarke Bibliothek, die zu einem unverzichtbaren Werkzeug in meiner Toolbox geworden ist.
Abschluss
Das Protokollieren von Anwendungsdaten und Diagnoseinformationen in der Konsole oder einer Datei kann beim Debuggen von Problemen sowohl während der Entwicklung als auch während der Produktion sehr nützlich sein. Eine solide Protokollierungslösung ist daher unerlässlich. Zusammen mit vielen anderen Entwicklern habe ich für viele Projekte benutzerdefinierte Protokollierungslösungen erstellt, aber CocoaLumberjack ist ein idealer Ersatz und hat noch viel mehr zu bieten.



