505 lines
43 KiB
HTML
505 lines
43 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<title>CleanroomLogger Reference</title>
|
||
<link rel="stylesheet" type="text/css" href="css/jazzy.css" />
|
||
<link rel="stylesheet" type="text/css" href="css/highlight.css" />
|
||
<meta charset='utf-8'>
|
||
<script src="js/jquery.min.js" defer></script>
|
||
<script src="js/jazzy.js" defer></script>
|
||
|
||
</head>
|
||
<body>
|
||
<a title="CleanroomLogger Reference"></a>
|
||
<header>
|
||
<div class="content-wrapper">
|
||
<p><a href="index.html">CleanroomLogger Docs</a> (100% documented)</p>
|
||
<p class="header-right"><a href="https://github.com/emaloney/CleanroomLogger"><img src="img/gh.png"/>View on GitHub</a></p>
|
||
</div>
|
||
</header>
|
||
<div class="content-wrapper">
|
||
<p id="breadcrumbs">
|
||
<a href="index.html">CleanroomLogger Reference</a>
|
||
<img id="carat" src="img/carat.png" />
|
||
CleanroomLogger Reference
|
||
</p>
|
||
</div>
|
||
<div class="content-wrapper">
|
||
<nav class="sidebar">
|
||
<ul class="nav-groups">
|
||
<li class="nav-group-name">
|
||
<a href="Classes.html">Classes</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Classes/BasicLogConfiguration.html">BasicLogConfiguration</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/BufferedLogEntryMessageRecorder.html">BufferedLogEntryMessageRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/BufferedLogEntryRecorder.html">BufferedLogEntryRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/BufferedLogRecorder.html">BufferedLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/BufferedMessageRecorder.html">BufferedMessageRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ConcatenatingLogFormatter.html">ConcatenatingLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ConsoleLogConfiguration.html">ConsoleLogConfiguration</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ConsoleLogConfiguration/StandardStreamsMode.html">– StandardStreamsMode</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/FieldBasedLogFormatter.html">FieldBasedLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/FieldBasedLogFormatter/Field.html">– Field</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/FileLogRecorder.html">FileLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/LogReceptacle.html">LogReceptacle</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/LogRecorderBase.html">LogRecorderBase</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/OutputStreamLogRecorder.html">OutputStreamLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ParsableLogFormatter.html">ParsableLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ReadableLogFormatter.html">ReadableLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RotatingLogFileConfiguration.html">RotatingLogFileConfiguration</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RotatingLogFileRecorder.html">RotatingLogFileRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/StandardErrorLogRecorder.html">StandardErrorLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/StandardLogFormatter.html">StandardLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/StandardOutputLogRecorder.html">StandardOutputLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/StandardStreamsLogRecorder.html">StandardStreamsLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/XcodeLogConfiguration.html">XcodeLogConfiguration</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/XcodeLogFormatter.html">XcodeLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/XcodeTraceLogFormatter.html">XcodeTraceLogFormatter</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Enums.html">Enums</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Enums/CallingThreadStyle.html">CallingThreadStyle</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/DelimiterStyle.html">DelimiterStyle</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/LogSeverity.html">LogSeverity</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/OSLogTypeTranslator.html">OSLogTypeTranslator</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/SeverityStyle.html">SeverityStyle</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/SeverityStyle/TextRepresentation.html">– TextRepresentation</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/TimestampStyle.html">TimestampStyle</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Protocols.html">Protocols</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/LogConfiguration.html">LogConfiguration</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/LogFilter.html">LogFilter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/LogFormatter.html">LogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/LogRecorder.html">LogRecorder</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Structs.html">Structs</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Structs/CallSiteLogFormatter.html">CallSiteLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/CallingThreadLogFormatter.html">CallingThreadLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/DelimiterLogFormatter.html">DelimiterLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/LiteralLogFormatter.html">LiteralLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/Log.html">Log</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/LogChannel.html">LogChannel</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/LogEntry.html">LogEntry</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/LogEntry/Payload.html">– Payload</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/LogSeverityFilter.html">LogSeverityFilter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/OSLogRecorder.html">OSLogRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/PayloadLogFormatter.html">PayloadLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/PayloadMessageLogFormatter.html">PayloadMessageLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/PayloadTraceLogFormatter.html">PayloadTraceLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/PayloadValueLogFormatter.html">PayloadValueLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ProcessIDLogFormatter.html">ProcessIDLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ProcessNameLogFormatter.html">ProcessNameLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/SeverityLogFormatter.html">SeverityLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/StackFrameLogFormatter.html">StackFrameLogFormatter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/TimestampLogFormatter.html">TimestampLogFormatter</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
<article class="main-content">
|
||
<section>
|
||
<section class="section">
|
||
|
||
<h2 id='using-cleanroomlogger' class='heading'>Using CleanroomLogger</h2>
|
||
|
||
<p>The main public API for CleanroomLogger is provided by <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html"><code>Log</code></a>.</p>
|
||
|
||
<p><code>Log</code> maintains five static read-only <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html"><code>LogChannel</code></a> properties that correspond to one of five <em>severity levels</em> indicating the importance of messages sent through that channel. When sending a message, you would select a severity appropriate for that message, and use the corresponding channel:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZvV15CleanroomLogger3Log5errorGSqVS_10LogChannel_"><code>Log.error</code></a> — The highest severity; something has gone wrong and a fatal error may be imminent</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZvV15CleanroomLogger3Log7warningGSqVS_10LogChannel_"><code>Log.warning</code></a> — Something appears amiss and might bear looking into before a larger problem arises</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZvV15CleanroomLogger3Log4infoGSqVS_10LogChannel_"><code>Log.info</code></a> — Something notable happened, but it isn’t anything to worry about</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZvV15CleanroomLogger3Log5debugGSqVS_10LogChannel_"><code>Log.debug</code></a> — Used for debugging and diagnostic information (not intended for use in production code)</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZvV15CleanroomLogger3Log7verboseGSqVS_10LogChannel_"><code>Log.verbose</code></a> - The lowest severity; used for detailed or frequently occurring debugging and diagnostic information (not intended for use in production code)</li>
|
||
</ul>
|
||
|
||
<p>Each of these <code>LogChannel</code>s provide three functions to record log messages:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html#/s:FV15CleanroomLogger10LogChannel5traceFTSS8filePathSS8fileLineSi_T_"><code>trace()</code></a> — This function records a log message with program execution trace information including the source code filename, line number and name of the calling function.</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html#/s:FV15CleanroomLogger10LogChannel7messageFTSS8functionSS8filePathSS8fileLineSi_T_"><code>message(String)</code></a> — This function records the log message passed to it.</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html#/s:FV15CleanroomLogger10LogChannel5valueFTGSqP__8functionSS8filePathSS8fileLineSi_T_"><code>value(Any?)</code></a> — This function attempts to record a log message containing a string representation of the optional <code>Any</code> value passed to it.</li>
|
||
</ul>
|
||
<h3 id='enabling-logging' class='heading'>Enabling logging</h3>
|
||
|
||
<p>By default, logging is disabled, meaning that none of the <code>Log</code>’s channels have been populated. As a result, they have <code>nil</code> values and any attempts to perform logging will silently fail.</p>
|
||
|
||
<p><strong>In order to use CleanroomLogger, <em>you must explicitly enable logging</em></strong>, which is done by calling one of the <code>Log.enable()</code> functions.</p>
|
||
|
||
<p>Ideally, logging is enabled at the first possible point in the application’s launch cycle. Otherwise, critical log messages may be missed during launch because the logger wasn’t yet initialized.</p>
|
||
|
||
<p>The best place to put the call to <code>Log.enable()</code> is at the first line of your app delegate’s <code>init()</code>.</p>
|
||
|
||
<p>If you’d rather not do that for some reason, the next best place to put it is in the <code>application(_:willFinishLaunchingWithOptions:)</code> function of your app delegate. You’ll notice that we’re specifically recommending the <code>will</code> function, not the typical <code>did</code>, because the former is called earlier in the application’s launch cycle.</p>
|
||
|
||
<blockquote>
|
||
<p><strong>Note:</strong> During the running lifetime of an application process, only the <em>first</em> call to <code>Log.enable()</code> function will have any effect. All subsequent calls are ignored silently. You can also prevent CleanroomLogger from being enabled altogether by calling <code>Log.neverEnable()</code>.</p>
|
||
</blockquote>
|
||
<h3 id='logging-examples' class='heading'>Logging examples</h3>
|
||
|
||
<p>To record items in the log, simply select the appropriate channel and call the appropriate function.</p>
|
||
|
||
<p>Here are a few examples:</p>
|
||
<h4 id='logging-an-arbitrary-text-message' class='heading'>Logging an arbitrary text message</h4>
|
||
|
||
<p>Let’s say your application just finished launching. This is a significant event, but it isn’t an error. You also might want to see this information in production app logs. Therefore, you decide the appropriate <code>LogSeverity</code> is <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Enums/LogSeverity.html#/s:FO15CleanroomLogger11LogSeverity4infoFMS0_S0_"><code>.info</code></a> and you select the corresponding <code>LogChannel</code>, which is <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZvV15CleanroomLogger3Log4infoGSqVS_10LogChannel_"><code>Log.info</code></a>. Then, to log a message, just call the channel’s <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html#/s:FV15CleanroomLogger10LogChannel7messageFTSS8functionSS8filePathSS8fileLineSi_T_"><code>message()</code></a> function:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="n">info</span><span class="p">?</span><span class="o">.</span><span class="nf">message</span><span class="p">(</span><span class="s">"The application has finished launching."</span><span class="p">)</span>
|
||
</code></pre>
|
||
<h4 id='logging-a-trace-message' class='heading'>Logging a trace message</h4>
|
||
|
||
<p>If you’re working on some code and you’re curious about the order of execution, you can sprinkle some <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html#/s:FV15CleanroomLogger10LogChannel5traceFTSS8filePathSS8fileLineSi_T_"><code>trace()</code></a> calls around.</p>
|
||
|
||
<p>This function outputs the filename, line number and name of the calling function.</p>
|
||
|
||
<p>For example, if you put the following code on line 364 of a file called ModularTable.swift in a function with the signature <code>tableView(_:cellForRowAt:)</code>:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="n">debug</span><span class="p">?</span><span class="o">.</span><span class="nf">trace</span><span class="p">()</span>
|
||
</code></pre>
|
||
|
||
<p>Assuming logging is enabled for the <code>.debug</code> severity, the following message would be logged when that line gets executed:</p>
|
||
<pre class="highlight plaintext"><code>ModularTable.swift:364 — tableView(_:cellForRowAt:)
|
||
</code></pre>
|
||
<h4 id='logging-an-arbitrary-value' class='heading'>Logging an arbitrary value</h4>
|
||
|
||
<p>The <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogChannel.html#/s:FV15CleanroomLogger10LogChannel5valueFTGSqP__8functionSS8filePathSS8fileLineSi_T_"><code>value()</code></a> function can be used for outputting information about a specific value. The function takes an argument of type <code>Any?</code> and is intended to accept any valid runtime value.</p>
|
||
|
||
<p>For example, you might want to output the <code>IndexPath</code> value passed to your <code>UITableViewDataSource</code>’s <code>tableView(_:cellForRowAt:)</code> function:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="n">verbose</span><span class="p">?</span><span class="o">.</span><span class="nf">value</span><span class="p">(</span><span class="n">indexPath</span><span class="p">)</span>
|
||
</code></pre>
|
||
|
||
<p>This would result in output looking like:</p>
|
||
<pre class="highlight plaintext"><code>= IndexPath: [0, 2]
|
||
</code></pre>
|
||
|
||
<p>The function also handles optionals:</p>
|
||
<pre class="highlight swift"><code><span class="k">var</span> <span class="nv">str</span><span class="p">:</span> <span class="kt">String</span><span class="p">?</span>
|
||
<span class="kt">Log</span><span class="o">.</span><span class="n">verbose</span><span class="p">?</span><span class="o">.</span><span class="nf">value</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
|
||
</code></pre>
|
||
|
||
<p>The output for this would be:</p>
|
||
<pre class="highlight plaintext"><code>= nil
|
||
</code></pre>
|
||
<h3 id='cleanroomlogger-in-depth' class='heading'>CleanroomLogger In Depth</h3>
|
||
|
||
<p>This section delves into the particulars of configuring and customizing CleanroomLogger to suit your needs.</p>
|
||
<h4 id='configuring-cleanroomlogger' class='heading'>Configuring CleanroomLogger</h4>
|
||
|
||
<p>CleanroomLogger is configured when one of the <code>Log.enable()</code> function variants is called. Configuration can occur at most once within the lifetime of the running process. And once set, the configuration can’t be changed; it’s immutable.</p>
|
||
|
||
<p>The <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogConfiguration.html"><code>LogConfiguration</code></a> protocol represents the mechanism by which CleanroomLogger can be configured. <code>LogConfiguration</code>s allow encapsulating related settings and behavior within a single entity, and CleanroomLogger can be configured with multiple <code>LogConfiguration</code> instances to allow combining behaviors.</p>
|
||
|
||
<p>Each <code>LogConfiguration</code> specifies:</p>
|
||
|
||
<ul>
|
||
<li>The <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogConfiguration.html#/s:vP15CleanroomLogger16LogConfiguration15minimumSeverityOS_11LogSeverity"><code>minimumSeverity</code></a>, a <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Enums/LogSeverity.html"><code>LogSeverity</code></a> value that determines which log entries get recorded. Any <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogEntry.html"><code>LogEntry</code></a> with a <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogEntry.html#/s:vV15CleanroomLogger8LogEntry8severityOS_11LogSeverity"><code>severity</code></a> less than the configuration’s <code>mimimumSeverity</code> will not be passed along to any <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogRecorder.html"><code>LogRecorder</code></a>s specified by that configuration.</li>
|
||
<li>An array of <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogFilter.html"><code>LogFilter</code></a>s. Each <code>LogFilter</code> is given a chance to cause a given log entry to be ignored.</li>
|
||
<li>A <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogConfiguration.html#/s:vP15CleanroomLogger16LogConfiguration15synchronousModeSb"><code>synchronousMode</code></a> property, which determines whether synchronous logging should be used when processing log entries for the given configuration. <em>This feature is intended to be used during debugging and is not recommended for production code.</em></li>
|
||
<li>Zero or more contained <code>LogConfiguration</code>s. For organizational purposes, each <code>LogConfiguration</code> can in turn contain additional <code>LogConfiguration</code>s. The hierarchy is not meaningful, however, and is flattened at configuration time.</li>
|
||
<li>An array of <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogRecorder.html"><code>LogRecorder</code></a>s that will be used to write log entries to the underlying logging facility. If a configuration has no <code>LogRecorder</code>s, it is assumed to be a container of other <code>LogConfiguration</code>s only, and is ignored when the configuration hierarchy is flattened.</li>
|
||
</ul>
|
||
|
||
<p>When CleanroomLogger receives a request to log something, zero or more <code>LogConfiguration</code>s are selected to handle the request:</p>
|
||
|
||
<ol>
|
||
<li>The <code>severity</code> of the incoming <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogEntry.html"><code>LogEntry</code></a> is compared against the <code>minimumSeverity</code> of each <code>LogConfiguration</code>. Any <code>LogConfiguration</code> whose <code>minimumSeverity</code> is equal to or less than the <code>severity</code> of the <code>LogEntry</code> is selected for further consideration.</li>
|
||
<li>The <code>LogEntry</code> is then passed sequentially to the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogFilter.html#/s:FP15CleanroomLogger9LogFilter12shouldRecordFT5entryVS_8LogEntry_Sb"><code>shouldRecord(entry:)</code></a> function of each of the <code>LogConfiguration</code>’s <code>filters</code>. If any <code>LogFilter</code> returns <code>false</code>, the associated configuration will <em>not</em> be selected to record that log entry.</li>
|
||
</ol>
|
||
<h5 id='xcodelogconfiguration' class='heading'>XcodeLogConfiguration</h5>
|
||
|
||
<p>Ideally suited for live viewing during development, the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/XcodeLogConfiguration.html"><code>XcodeLogConfiguration</code></a> examines the runtime environment to optimize CleanroomLogger for use within Xcode.</p>
|
||
|
||
<p><code>XcodeLogConfiguration</code> takes into account:</p>
|
||
|
||
<ul>
|
||
<li><p>Whether the new Unified Logging System (also known as “OSLog”) is available; it is only present as of iOS 10.0, macOS 10.12, tvOS 10.0, and watchOS 3.0. By default, logging falls back to <code>stdout</code> and <code>stderr</code> if Unified Logging is unavailable.</p></li>
|
||
<li><p>The value of the <code>OS_ACTIVITY_MODE</code> environment variable; when it is set to “<code>disable</code>”, attempts to log via OSLog are silently ignored. In such cases, log output is echoed to <code>stdout</code> and <code>stderr</code> to ensure that messages are visible in Xcode.</p></li>
|
||
<li><p>The <code>severity</code> of the message. For UNIX-friendly behavior, <code>.verbose</code>, <code>.debug</code> and <code>.info</code> messages are directed to the <code>stdout</code> stream of the running process, while <code>.warning</code> and <code>.error</code> messages are sent to <code>stderr</code>. </p></li>
|
||
</ul>
|
||
|
||
<p>When using the Unified Logging System, messages in the Xcode console appear prefixed with an informational header that looks like:</p>
|
||
<pre class="highlight plaintext"><code>2017-01-04 22:56:47.448224 Gilt[5031:89847] [CleanroomLogger]
|
||
2017-01-04 22:56:47.448718 Gilt[5031:89847] [CleanroomLogger]
|
||
2017-01-04 22:56:47.449487 Gilt[5031:89847] [CleanroomLogger]
|
||
2017-01-04 22:56:47.450127 Gilt[5031:89847] [CleanroomLogger]
|
||
2017-01-04 22:56:47.450722 Gilt[5031:89847] [CleanroomLogger]
|
||
</code></pre>
|
||
|
||
<p>This header is not added by CleanroomLogger; it is added as a result of using OSLog within Xcode. It shows the timestamp of the log entry, followed by the process name, the process ID, the calling thread ID, and the logging system name.</p>
|
||
|
||
<p>To ensure consistent output across platforms, the <code>XcodeLogConfiguration</code> will mimic this header even when logging to <code>stdout</code> and <code>stderr</code>. You can disable this behavior by passing <code>false</code> as the <code>mimicOSLogOutput</code> argument. When disabled, a more concise header is used, showing just the timestamp and the calling thread ID:</p>
|
||
<pre class="highlight plaintext"><code>2017-01-04 23:46:17.225 -05:00 | 00071095
|
||
2017-01-04 23:46:17.227 -05:00 | 00071095
|
||
2017-01-04 23:46:17.227 -05:00 | 000716CA
|
||
2017-01-04 23:46:17.228 -05:00 | 000716CA
|
||
2017-01-04 23:46:17.258 -05:00 | 00071095
|
||
</code></pre>
|
||
|
||
<p>To make it easier to quickly identify important log messages at runtime, the <code>XcodeLogConfiguration</code> makes use of the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/XcodeLogFormatter.html"><code>XcodeLogFormatter</code></a>, which embeds a color-coded representation of each message’s severity:</p>
|
||
<pre class="highlight plaintext"><code>◽️ Verbose messages are tagged with a small gray square — easy to ignore
|
||
◾️ Debug messages have a black square; easier to spot, but still de-emphasized
|
||
🔷 Info messages add a splash of color in the form of a blue diamond
|
||
🔶 Warnings are highlighted with a fire-orange diamond
|
||
❌ Error messages stand out with a big red X — hard to miss!
|
||
</code></pre>
|
||
|
||
<p>The simplest way to enable CleanroomLogger using the <code>XcodeLogConfiguration</code> is by calling:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="nf">enable</span><span class="p">()</span>
|
||
</code></pre>
|
||
|
||
<p>Thanks to the magic of default parameter values, this is equivalent to the following <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/Log.html#/s:ZFV15CleanroomLogger3Log6enableFT15minimumSeverityOS_11LogSeverity9debugModeSb16verboseDebugModeSb14stdStreamsModeOCS_23ConsoleLogConfiguration19StandardStreamsMode16mimicOSLogOutputSb12showCallSiteSb7filtersGSaPS_9LogFilter___T_"><code>Log.enable()</code></a> call:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="nf">enable</span><span class="p">(</span><span class="nv">minimumSeverity</span><span class="p">:</span> <span class="o">.</span><span class="n">info</span><span class="p">,</span>
|
||
<span class="nv">debugMode</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||
<span class="nv">verboseDebugMode</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
|
||
<span class="nv">stdStreamsMode</span><span class="p">:</span> <span class="o">.</span><span class="n">useAsFallback</span><span class="p">,</span>
|
||
<span class="nv">mimicOSLogOutput</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||
<span class="nv">showCallSite</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
|
||
<span class="nv">filters</span><span class="p">:</span> <span class="p">[])</span>
|
||
</code></pre>
|
||
|
||
<p>This configures CleanroomLogger using an <code>XcodeLogConfiguration</code> with <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/XcodeLogConfiguration.html#/s:FC15CleanroomLogger21XcodeLogConfigurationcFT15minimumSeverityOS_11LogSeverity9debugModeSb16verboseDebugModeSb14stdStreamsModeOCS_23ConsoleLogConfiguration19StandardStreamsMode16mimicOSLogOutputSb12showCallSiteSb7filtersGSaPS_9LogFilter___S0_">default settings</a>.</p>
|
||
|
||
<blockquote>
|
||
<p><strong>Note:</strong> If either <code>debugMode</code> or <code>verboseDebugMode</code> is <code>true</code>, the <code>XcodeLogConfiguration</code> will be used in <code>synchronousMode</code>, which is not recommended for production code.</p>
|
||
</blockquote>
|
||
|
||
<p>The call above is also equivalent to:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="nf">enable</span><span class="p">(</span><span class="nv">configuration</span><span class="p">:</span> <span class="kt">XcodeLogConfiguration</span><span class="p">())</span>
|
||
</code></pre>
|
||
<h5 id='rotatinglogfileconfiguration' class='heading'>RotatingLogFileConfiguration</h5>
|
||
|
||
<p>The <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/RotatingLogFileConfiguration.html"><code>RotatingLogFileConfiguration</code></a> can be used to maintain a directory of log files that are rotated daily.</p>
|
||
|
||
<blockquote>
|
||
<p><strong>Warning:</strong> The <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/RotatingLogFileRecorder.html"><code>RotatingLogFileRecorder</code></a> created by the <code>RotatingLogFileConfiguration</code> assumes full control over the log directory. Any file not recognized as an active log file will be deleted during the automatic pruning process, which may occur at any time. <em>This means if you’re not careful about the <code>directoryPath</code> you pass, you may lose valuable data!</em></p>
|
||
</blockquote>
|
||
|
||
<p>At a minimum, the <code>RotatingLogFileConfiguration</code> requires you to specify the <code>minimumSeverity</code> for logging, the number of days to keep log files, and a directory in which to store those files:</p>
|
||
<pre class="highlight swift"><code><span class="c1">// logDir is a String holding the filesystem path to the log directory</span>
|
||
<span class="k">let</span> <span class="nv">rotatingConf</span> <span class="o">=</span> <span class="kt">RotatingLogFileConfiguration</span><span class="p">(</span><span class="nv">minimumSeverity</span><span class="p">:</span> <span class="o">.</span><span class="n">info</span><span class="p">,</span>
|
||
<span class="nv">daysToKeep</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span>
|
||
<span class="nv">directoryPath</span><span class="p">:</span> <span class="n">logDir</span><span class="p">)</span>
|
||
|
||
<span class="kt">Log</span><span class="o">.</span><span class="nf">enable</span><span class="p">(</span><span class="nv">configuration</span><span class="p">:</span> <span class="n">rotatingConf</span><span class="p">)</span>
|
||
</code></pre>
|
||
|
||
<p>The code above would record any log entry with a severity of <code>.info</code> or higher in a file that would be kept for at least 7 days before being pruned. This particular configuration uses the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ReadableLogFormatter.html"><code>ReadableLogFormatter</code></a> to format log entries.</p>
|
||
|
||
<p>The <code>RotatingLogFileConfiguration</code> can also be used to specify <code>synchronousMode</code>, a set of <code>LogFilter</code>s to apply, and one or more custom <code>LogFormatter</code>s.</p>
|
||
<h5 id='multiple-configurations' class='heading'>Multiple Configurations</h5>
|
||
|
||
<p>CleanroomLogger also supports multiple configurations, allowing different logging behaviors to be in use simultaneously.</p>
|
||
|
||
<p>Whenever a message is logged, every <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogConfiguration.html"><code>LogConfiguration</code></a> is consulted separately and given a chance to process the message. By supplying a <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogConfiguration.html#/s:vP15CleanroomLogger16LogConfiguration15minimumSeverityOS_11LogSeverity"><code>minimumSeverity</code></a> and unique set of <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogConfiguration.html#/s:vP15CleanroomLogger16LogConfiguration7filtersGSaPS_9LogFilter__"><code>LogFilter</code></a>s, each configuration can specify its own logic for screening out unwanted messages. Surviving messages are then passed to the configuration’s <code>LogFormatter</code>s, each in turn, until one returns a non-<code>nil</code> string. That string—the formatted log message—is ultimately passed to one or more <code>LogRecorder</code>s for writing to some underlying logging facility.</p>
|
||
|
||
<blockquote>
|
||
<p>Note that each configuration is a self-contained, stand-alone entity. None of the settings, behaviors or actions of a given <code>LogConfiguration</code> will affect any other.</p>
|
||
</blockquote>
|
||
|
||
<p>For an example of how this works, imagine adding a debug mode <code>XcodeLogConfiguration</code> to the <code>rotatingConf</code> declared above. You could do this by writing:</p>
|
||
<pre class="highlight swift"><code><span class="kt">Log</span><span class="o">.</span><span class="nf">enable</span><span class="p">(</span><span class="nv">configuration</span><span class="p">:</span> <span class="p">[</span><span class="kt">XcodeLogConfiguration</span><span class="p">(</span><span class="nv">debugMode</span><span class="p">:</span> <span class="kc">true</span><span class="p">),</span> <span class="n">rotatingConf</span><span class="p">])</span>
|
||
</code></pre>
|
||
|
||
<p>In this example, both the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/XcodeLogConfiguration.html"><code>XcodeLogConfiguration</code></a> and the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/RotatingLogFileConfiguration.html"><code>RotatingLogFileConfiguration</code></a> will be consulted as each logging call occurs. Because the <code>XcodeLogConfiguration</code> is declared with <code>debugMode: true</code>, it will operate in <code>synchronousMode</code> while <code>rotatingConf</code> will operate asynchronously.</p>
|
||
|
||
<p>Further, the <code>XcodeLogConfiguration</code> will result in messages being logged via the Unified Logging System (if available) and/or the running process’s <code>stdout</code> and <code>stderr</code> streams. The <code>RotatingLogFileConfiguration</code>, on the other hand, results in messages being written to a file.</p>
|
||
|
||
<p>Finally, each configuration results in a different message format being used.</p>
|
||
<h5 id='implementing-your-own-configuration' class='heading'>Implementing Your Own Configuration</h5>
|
||
|
||
<p>Although you can provide your own implementation of the <code>LogConfiguration</code> protocol, it may be simpler to create a <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/BasicLogConfiguration.html"><code>BasicLogConfiguration</code></a> instance and pass the relevant parameters to <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/BasicLogConfiguration.html#/s:FC15CleanroomLogger21BasicLogConfigurationcFT15minimumSeverityOS_11LogSeverity7filtersGSaPS_9LogFilter__9recordersGSaPS_11LogRecorder__15synchronousModeSb14configurationsGSqGSaPS_16LogConfiguration____S0_">the initializer</a>.</p>
|
||
|
||
<p>You can also subclass <code>BasicLogConfiguration</code> if you’d like to encapsulate your configuration further.</p>
|
||
<h5 id='a-complicated-example' class='heading'>A Complicated Example</h5>
|
||
|
||
<p>Let’s say you want configure CleanroomLogger to:</p>
|
||
|
||
<ol>
|
||
<li>Print <code>.verbose</code>, <code>.debug</code> and <code>.info</code> messages to <code>stdout</code> while directing <code>.warning</code> and <code>.error</code> messages to <code>stderr</code></li>
|
||
<li>Mirror all messages to OSLog, if it is available on the runtime platform</li>
|
||
<li>Create a rotating log file directory at the path <code>/tmp/CleanroomLogger</code> to store <code>.info</code>, <code>.warning</code> and <code>.error</code> messages for up to 15 days</li>
|
||
</ol>
|
||
|
||
<p>Further, you want the log entries for each to be formatted differently:</p>
|
||
|
||
<ol>
|
||
<li>An <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/XcodeLogFormatter.html"><code>XcodeLogFormatter</code></a> for <code>stdout</code> and <code>stderr</code></li>
|
||
<li>A <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ReadableLogFormatter.html"><code>ReadableLogFormatter</code></a> for OSLog</li>
|
||
<li>A <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ParsableLogFormatter.html"><code>ParsableLogFormatter</code></a> for the log files</li>
|
||
</ol>
|
||
|
||
<p>To configure CleanroomLogger to do all this, you could write:</p>
|
||
<pre class="highlight swift"><code><span class="k">var</span> <span class="nv">configs</span> <span class="o">=</span> <span class="p">[</span><span class="kt">LogConfiguration</span><span class="p">]()</span>
|
||
|
||
<span class="c1">// create a recorder for logging to stdout & stderr</span>
|
||
<span class="c1">// and add a configuration that references it</span>
|
||
<span class="k">let</span> <span class="nv">stderr</span> <span class="o">=</span> <span class="kt">StandardStreamsLogRecorder</span><span class="p">(</span><span class="nv">formatters</span><span class="p">:</span> <span class="p">[</span><span class="kt">XcodeLogFormatter</span><span class="p">()])</span>
|
||
<span class="n">configs</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="kt">BasicLogConfiguration</span><span class="p">(</span><span class="nv">recorders</span><span class="p">:</span> <span class="p">[</span><span class="n">stderr</span><span class="p">]))</span>
|
||
|
||
<span class="c1">// create a recorder for logging via OSLog (if possible)</span>
|
||
<span class="c1">// and add a configuration that references it</span>
|
||
<span class="k">if</span> <span class="k">let</span> <span class="nv">osLog</span> <span class="o">=</span> <span class="kt">OSLogRecorder</span><span class="p">(</span><span class="nv">formatters</span><span class="p">:</span> <span class="p">[</span><span class="kt">ReadableLogFormatter</span><span class="p">()])</span> <span class="p">{</span>
|
||
<span class="c1">// the OSLogRecorder initializer will fail if running on </span>
|
||
<span class="c1">// a platform that doesn’t support the os_log() function</span>
|
||
<span class="n">configs</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="kt">BasicLogConfiguration</span><span class="p">(</span><span class="nv">recorders</span><span class="p">:</span> <span class="p">[</span><span class="n">osLog</span><span class="p">]))</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="c1">// create a configuration for a 15-day rotating log directory</span>
|
||
<span class="k">let</span> <span class="nv">fileCfg</span> <span class="o">=</span> <span class="kt">RotatingLogFileConfiguration</span><span class="p">(</span><span class="nv">minimumSeverity</span><span class="p">:</span> <span class="o">.</span><span class="n">info</span><span class="p">,</span>
|
||
<span class="nv">daysToKeep</span><span class="p">:</span> <span class="mi">15</span><span class="p">,</span>
|
||
<span class="nv">directoryPath</span><span class="p">:</span> <span class="s">"/tmp/CleanroomLogger"</span><span class="p">,</span>
|
||
<span class="nv">formatters</span><span class="p">:</span> <span class="p">[</span><span class="kt">ParsableLogFormatter</span><span class="p">()])</span>
|
||
|
||
<span class="c1">// crash if the log directory doesn’t exist yet & can’t be created</span>
|
||
<span class="k">try!</span> <span class="n">fileCfg</span><span class="o">.</span><span class="nf">createLogDirectory</span><span class="p">()</span>
|
||
|
||
<span class="n">configs</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">fileCfg</span><span class="p">)</span>
|
||
|
||
<span class="c1">// enable logging using the LogRecorders created above</span>
|
||
<span class="kt">Log</span><span class="o">.</span><span class="nf">enable</span><span class="p">(</span><span class="nv">configuration</span><span class="p">:</span> <span class="n">configs</span><span class="p">)</span>
|
||
</code></pre>
|
||
<h4 id='customized-log-formatting' class='heading'>Customized Log Formatting</h4>
|
||
|
||
<p>The <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Protocols/LogFormatter.html"><code>LogFormatter</code></a> protocol is consulted when attempting to convert a <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Structs/LogEntry.html"><code>LogEntry</code></a> into a string.</p>
|
||
|
||
<p>CleanroomLogger ships with several high-level <code>LogFormatter</code> implementations for specific purposes:</p>
|
||
|
||
<ul>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/XcodeLogFormatter.html"><code>XcodeLogFormatter</code></a> — Optimized for live viewing of a log stream in Xcode. Used by the <code>XcodeLogConfiguration</code> by default.</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ParsableLogFormatter.html"><code>ParsableLogFormatter</code></a> — Ideal for logs intended to be ingested for parsing by other processes.</li>
|
||
<li><a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/ReadableLogFormatter.html"><code>ReadableLogFormatter</code></a> — Ideal for logs intended to be read by humans.</li>
|
||
</ul>
|
||
|
||
<p>The latter two <code>LogFormatter</code>s are both subclasses of <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/StandardLogFormatter.html"><code>StandardLogFormatter</code></a>, which provides a basic mechanism for customizing the behavior of formatting.</p>
|
||
|
||
<p>You can also assemble an entirely custom formatter quite easily using the <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/FieldBasedLogFormatter.html"><code>FieldBasedLogFormatter</code></a>, which lets you mix and match <a href="https://rawgit.com/emaloney/CleanroomLogger/master/Documentation/API/Classes/FieldBasedLogFormatter/Field.html"><code>Field</code></a>s to roll your own formatter.</p>
|
||
|
||
</section>
|
||
</section>
|
||
<section id="footer">
|
||
<p>© 2015-2017 <a class="link" href="http://tech.gilt.com/" target="_blank" rel="external">Gilt Groupe</a></p>
|
||
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.8.3</a>, a <a class="link" href="http://realm.io" target="_blank" rel="external">Realm</a> project.</p>
|
||
</section>
|
||
</article>
|
||
</div>
|
||
</body>
|
||
</div>
|
||
</html>
|