Skip to content

Commit

Permalink
Merge branch 'master' of ssh://github.com/emaloney/CleanroomLogger
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Maloney committed Jan 9, 2017
2 parents eeb70f5 + 35347cd commit 38d5dc2
Showing 1 changed file with 50 additions and 38 deletions.
88 changes: 50 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,39 @@ Branch|Build status
[`master`](https://github.com/emaloney/CleanroomLogger)|[![Build status: master branch](https://travis-ci.org/emaloney/CleanroomLogger.svg?branch=master)](https://travis-ci.org/emaloney/CleanroomLogger)


- [Key Benefits of CleanroomLogger](#key-benefits-of-cleanroomlogger)
- [Adding CleanroomLogger to your project](#adding-cleanroomlogger-to-your-project)
- [Using CleanroomLogger](#using-cleanroomlogger)
- [Enabling logging](#enabling-logging)
- [Logging Examples](#logging-examples)
- [CleanroomLogger In Depth](#cleanroomlogger-in-depth)
- [Configuring CleanroomLogger](#configuring-cleanroomlogger)
- [Customized Log Formatting](#customized-log-formatting)
- [API Documentation](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/index.html)
- [Design Philosophy](#design-philosophy)
- [Architectural Overview](#architectural-overview)

### Key Benefits of CleanroomLogger

####  Built for speed
#### ▶︎ Built for speed

You don’t have to choose between smooth scrolling and collecting meaningful log information. CleanroomLogger does *very* little work on the calling thread, so it can get back to business ASAP.

####  A modern logging engine with first-class legacy support
####  A modern logging engine with first-class legacy support

CleanroomLogger takes advantage of Apple’s new [Unified Logging System](https://developer.apple.com/reference/os/2793189-logging) (aka “OSLog” or “os_log”) when running on iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0 or higher.

On systems where OSLog isn’t available, CleanroomLogger gracefully falls back to other standard output mechanisms, automatically.

####  100% documented
####  100% documented

Good documentation is critical to the usefulness of any open-source framework. In addition to the extensive high-level documentation you'll find below, [the CleanroomLogger API](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/index.html) itself is 100% documented.
Good documentation is critical to the usefulness of any open-source framework. In addition to the extensive high-level documentation youll find below, [the CleanroomLogger API](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/index.html) itself is 100% documented.

#### • Prioritize messages by severity
#### ▶ Organize and filter messages by severity

Messages are assigned one of five [_severity levels_](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Enums/LogSeverity.html): the most severe is _error_, followed by _warning_, _info_, _debug_ and _verbose_, the least severe. Knowing a message’s severity lets you perform additional filtering; for example, to minimize the overhead of logging in App Store binaries, you could choose to log only warnings and errors in release builds.

#### • UNIX-friendly

Support for standard UNIX output streams is built-in. Use [`StandardOutputLogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardOutputLogRecorder.html) and [`StandardErrorLogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardErrorLogRecorder.html) to direct output to `stdout` and `stderr`, respectively.

Or, use the [`StandardStreamsLogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardStreamsLogRecorder.html) to direct _verbose_, _debug_ and _info_ messages to `stdout` while _warnings_ and _errors_ go to `stderr`.

#### • Color-coded log messages
#### ▶ Color-coded log messages

Quickly spot problems at runtime in the Xcode console, where log messages are color coded by severity:

Expand All @@ -58,26 +64,19 @@ Quickly spot problems at runtime in the Xcode console, where log messages are co
🛑 Error messages stand out with a red stop sign — hard to miss!
```

#### • Rotating log files
#### ▶ UNIX-friendly

CleanroomLogger provides [simple file-based logging](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/FileLogRecorder.html) support as well as [a self-pruning rotating log directory](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/RotatingLogFileConfiguration.html) implementation.
Support for standard UNIX output streams is built-in. Use [`StandardOutputLogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardOutputLogRecorder.html) and [`StandardErrorLogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardErrorLogRecorder.html) to direct output to `stdout` and `stderr`, respectively.

#### • Super-simple execution tracing
Or, use the [`StandardStreamsLogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardStreamsLogRecorder.html) to send verbose, debug and info messages to `stdout` while warnings and errors go to `stderr`.

Developers often use logging to perform tracing. Rather than writing lots of different log messages to figure out what your program is doing at runtime, just sprinkle your source with `Log.debug?.trace()` and `Log.verbose?.trace()` calls, and you’ll see exactly what lines your code hits, when, and on what thread, as well as the signature of the executing function:
#### ▶ Automatic handling of `OS_ACTIVITY_MODE`

```
2017-01-05 13:46:16.681 -05:00 | 0001AEC4 ◾️ —> StoreDataTransaction.swift:42 - executeTransaction()
2017-01-05 13:46:16.683 -05:00 | 00071095 ◾️ —> LegacyStoresDeepLinking.swift:210 - viewControllerForRouter(_:destination:)
2017-01-05 13:46:16.683 -05:00 | 0001AEC4 ◽️ —> StoreDataTransaction.swift:97 - executeTransaction(completion:)
2017-01-05 13:46:16.684 -05:00 | 00071095 ◾️ —> ContainerViewController.swift:132 - setContentViewController(_:animated:completion:)
2017-01-05 13:46:16.684 -05:00 | 00071095 ◾️ —> DefaultBackstopDeepLinkNavigator.swift:53 - navigate(to:via:using:viewController:displayOptions:completion:)
2017-01-05 13:46:16.687 -05:00 | 00071095 ◽️ —> ViewControllerBase.swift:79 - viewWillAppear
```
When Xcode 8 was introduced, the console pane got a lot more chatty. This was due to the replacement of [the ASL facility](https://github.com/emaloney/CleanroomASL#about-the-apple-system-log) with OSLog. To silence the extra chatter, developers discovered that [setting the `OS_ACTIVITY_MODE` environment variable to “`disable`](http://stackoverflow.com/questions/37800790/hide-strange-unwanted-xcode-8-logs/39461256#39461256) would revert to the old logging behavior. It turns out that this silences OSLog altogether, so no output is sent to the console pane. CleanroomLogger notices when the setting is present, and echoes messages to `stdout` or `stderr` in addition to logging them through the [`os_log()`](https://developer.apple.com/reference/os/2320718-os_log) function.

#### • Quickly identify _where_ your code is logging
#### ▶ See _where_ your code is logging

If you’re just using `print()` or `NSLog()` everywhere, it can sometimes be difficult to figure out what code is responsible for which log messages. CleanroomLogger outputs the file and line responsible for each log message, so you can go straight to the source:
If you’re just using `print()` or `NSLog()` everywhere, it can sometimes be difficult to figure out what code is responsible for which log messages. By default, CleanroomLogger outputs the source file and line responsible for issuing each log message, so you can go straight to the source:

```
🔶 AppleTart.framework didn’t load due to running on iOS 8 (AppleTartShim.swift:19)
Expand All @@ -87,7 +86,24 @@ If you’re just using `print()` or `NSLog()` everywhere, it can sometimes be di
🛑 Unrecognized URL: CountrySelector (GiltOnTheGoDeepLinkRouter.swift:100)
```

#### • Useful built-in formatters
#### ▶ Rotating log files

CleanroomLogger provides [simple file-based logging](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/FileLogRecorder.html) support as well as [a self-pruning rotating log directory](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/RotatingLogFileConfiguration.html) implementation.

#### ▶ Super-simple execution tracing

Developers often use logging to perform tracing. Rather than writing lots of different log messages to figure out what your program is doing at runtime, just sprinkle your source with `Log.debug?.trace()` and `Log.verbose?.trace()` calls, and you’ll see exactly what lines your code hits, when, and on what thread, as well as the signature of the executing function:

```
2017-01-05 13:46:16.681 -05:00 | 0001AEC4 ◾️ —> StoreDataTransaction.swift:42 - executeTransaction()
2017-01-05 13:46:16.683 -05:00 | 00071095 ◾️ —> LegacyStoresDeepLinking.swift:210 - viewControllerForRouter(_:destination:)
2017-01-05 13:46:16.683 -05:00 | 0001AEC4 ◽️ —> StoreDataTransaction.swift:97 - executeTransaction(completion:)
2017-01-05 13:46:16.684 -05:00 | 00071095 ◾️ —> ContainerViewController.swift:132 - setContentViewController(_:animated:completion:)
2017-01-05 13:46:16.684 -05:00 | 00071095 ◾️ —> DefaultBackstopDeepLinkNavigator.swift:53 - navigate(to:via:using:viewController:displayOptions:completion:)
2017-01-05 13:46:16.687 -05:00 | 00071095 ◽️ —> ViewControllerBase.swift:79 - viewWillAppear
```

#### ▶ Useful built-in formatters

CleanroomLogger ships with two general-purpose log formatters: the [`ReadableLogFormatter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ReadableLogFormatter.html) is handy for human consumption, while the [`ParsableLogFormatter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ParsableLogFormatter.html) is useful for machine processing. Both can be customized via the initializer.

Expand All @@ -111,11 +127,11 @@ When the same log messages are handled by a formatter constructed using `Parsabl
1483686422.39651 4 001BEF88 MemoryCache.swift:233 - Caching is temporarily disabled due to a recent memory warning
```

####  Easy mix-and-match formatting
####  Easy mix-and-match formatting

If the built-in options don’t fit the bill, you can use the [`FieldBasedLogFormatter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/FieldBasedLogFormatter.html) to assemble just about any kind of log format possible. (And for all other cases not supported by `FieldBasedLogFormatter`, you can supply your own [`LogFormatter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogFormatter.html) implementation.)
If the built-in formatters don’t fit the bill, you can use the [`FieldBasedLogFormatter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/FieldBasedLogFormatter.html) to assemble just about any kind of log format possible.

Let’s say you wanted a log formatter with the following characteristics: the timestamp in ISO 8601 date format, followed by a tab character, the source file and line number of the call site, followed by the severity as an uppercase string right-justified in a 8-character field, then a colon and a space, and finally the log entry’s payload. You could do this by constructing a `FieldBasedLogFormatter` as follows:
Let’s say you wanted a log formatter with the timestamp in ISO 8601 date format, a tab character, the source file and line number of the call site, followed by the severity as an uppercase string right-justified in a 8-character field, then a colon and a space, and finally the log entry’s payload. You could do this by constructing a `FieldBasedLogFormatter` as follows:

```swift
FieldBasedLogFormatter(fields: [
Expand All @@ -132,19 +148,15 @@ The resulting output would look like:
```
2017-01-08T12:55:17.905-0500 DeepLinkRouterImpl.swift:207 DEBUG: destinationForURL
2017-01-08T12:55:20.716-0500 DefaultDeepLinkRouter.swift:95 INFO: Attempting navigation to storeSale
2017-01-08T12:55:21.995-0500 LegacyUserEnvironment.swift:109 ERROR: Cannot fetch user profile without user guid.
2017-01-08T12:55:25.960-0500 DeepLinkConsoleOutput.swift:104 WARNING: Can't find storeProduct for URL
2017-01-08T12:55:21.995-0500 LegacyUserEnvironment.swift:109 ERROR: Can’t fetch user profile without user guid
2017-01-08T12:55:25.960-0500 DeepLinkConsoleOutput.swift:104 WARNING: Cant find storeProduct for URL
2017-01-08T12:55:33.457-0500 ProductViewController.swift:92 VERBOSE: deinit
```

#### • Automatic handling of `OS_ACTIVITY_MODE`

When Xcode 8 was introduced, the console pane got a lot more chatty. This was due to the replacement of [the ASL facility](https://github.com/emaloney/CleanroomASL#about-the-apple-system-log) with OSLog. To silence the extra chatter, developers discovered that [setting the `OS_ACTIVITY_MODE` environment variable to “`disable`](http://stackoverflow.com/questions/37800790/hide-strange-unwanted-xcode-8-logs/39461256#39461256) would revert to the old logging behavior. It turns out that this silences OSLog altogether, so no output is sent to the console pane. CleanroomLogger notices when the setting is present, and echoes messages to `stdout` or `stderr` in addition to logging them through the [`os_log()`](https://developer.apple.com/reference/os/2320718-os_log) function.

#### • Fully extensible
#### ▶ Fully extensible

CleanroomLogger exposes three primary extension points for implementing your own custom logic:
- [`LogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogRecorder.html)s are used to record formatted log messages. Typically, this involves writing the message to a stream or data store. You can provide your own `LogRecorder` implementations to utilize facilities not natively supported by CleanroomLogger: to store messages in a database table or send them to a remote HTTP endpoint, for example.
- [`LogRecorder`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogRecorder.html)s are used to record formatted log messages. Typically, this involves writing the message to a stream or data store of some kind. You can provide your own `LogRecorder` implementations to utilize facilities not natively supported by CleanroomLogger: to store messages in a database table or send them to a remote HTTP endpoint, for example.
- [`LogFormatter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogFormatter.html)s are used to generate text representations of each [`LogEntry`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogEntry.html) to be recorded.
- [`LogFilter`](https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogFilter.html)s get a chance to inspect—and potentially reject—a `LogEntry` before it is passed to a `LogRecorder`.

Expand Down

0 comments on commit 38d5dc2

Please sign in to comment.