Files
flexiber/delog/index.html
2021-03-06 12:00:40 +00:00

121 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `delog` crate."><meta name="keywords" content="rust, rustlang, rust-lang, delog"><title>delog - Rust</title><link rel="stylesheet" type="text/css" href="../normalize.css"><link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../delog/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><p class="location">Crate delog</p><div class="block version"><p>Version 0.1.0</p></div><div class="sidebar-elems"><a id="all-types" href="all.html"><p>See all delog's items</p></a><div class="block items"><ul><li><a href="#reexports">Re-exports</a></li><li><a href="#modules">Modules</a></li><li><a href="#macros">Macros</a></li><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li><li><a href="#traits">Traits</a></li><li><a href="#functions">Functions</a></li></ul></div><p class="location"></p><script>window.sidebarCurrent = {name: "delog", ty: "mod", relpath: "../"};</script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<a id="settings-menu" href="../settings.html"><img src="../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><h1 class="fqn"><span class="out-of-band"><span id="render-detail"><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span><a class="srclink" href="../src/delog/lib.rs.html#1-183" title="goto source code">[src]</a></span><span class="in-band">Crate <a class="mod" href="">delog</a></span></h1><div class="docblock"><h1 id="compile-time-configurable-deferred-logging-for-printf-debugging-aka-tracing" class="section-header"><a href="#compile-time-configurable-deferred-logging-for-printf-debugging-aka-tracing">Compile-time configurable deferred logging (for <code>printf()</code>-debugging <em>aka</em> tracing)</a></h1>
<p>This is an implementation of the <code>log::Log</code> trait, suitable for use
in both embedded and desktop environments.</p>
<p>It has two main goals:</p>
<ul>
<li>logs are stored in a circular static memory buffer, so that logging is &quot;zero-cost in the inner
loop&quot; (apart from the formatting), with deferred actual I/O later via flushing.</li>
<li>compile-time log level settings for applications with multiple library components;
inactive log levels of libraries are completely compiled out.</li>
</ul>
<p>Moreover, setting the kill switch feature flag <code>knock-it-off</code>, any and all traces of logging
are removed from the final binary.</p>
<h2 id="usage-and-defaults" class="section-header"><a href="#usage-and-defaults">Usage and defaults</a></h2>
<blockquote>
<p><em>&quot;Global settings subtractive (default all), local settings additive (default none) but with kill-switch.&quot;</em></p>
</blockquote>
<p>From <code>log</code>, we inherit:</p>
<ul>
<li>static global filters, default <code>LevelFilter::Trace</code> (i.e., everything), set via <code>delog</code> or
<code>log</code> feature flags (multiple settings result in the most restrictive filter)</li>
<li>dynamic global filter, initialized in the &quot;init&quot;/&quot;init_default&quot; constructors of the
macro-generated structs implementing our <code>Delogger</code> trait. This can be changed by calls to
the global <code>set_max_level</code> function in <code>log</code>.</li>
</ul>
<p>Libraries that use the logging macros from <code>log</code> are governed by the more restrictive of these two settings.</p>
<p>On the other hand, a library that uses the <code>delog::generate_macros!()</code> macro gains macros <code>info!</code>, <code>warn!</code>, etc.,
which, by default, do nothing, and are completely optimized out.</p>
<p>If such a libray itself defines a feature <code>log-all</code> that is active, then logging calls with these macros are passed through
and goverend by the global filters. Such a library can also define a feature such as
<code>log-info</code>, which activates <em>exactly</em> the info-level logs; it is up to the library to define
logic such as &quot;log-info implies log-warn&quot;. There is a kill-switch: if the library defines a
feature <code>log-none</code>, and some intermediate library activates one of the additive <code>log-*</code>
features, setting <code>log-none</code> completely turns off logging for this library.</p>
<h2 id="background" class="section-header"><a href="#background">Background</a></h2>
<p>Compared to existing approaches such as <code>ufmt</code>, <code>cortex-m-funnel</code> and <code>defmt</code>,
we pursue different values and requirements, namely:</p>
<ul>
<li><strong>compatibility with the standard <code>core::fmt</code> traits and the standard <code>log</code> library API</strong>.
This means that, while libraries may &quot;upgrade&quot; their logging capabilities by using <code>delog</code>
as drop-in replacement for their logging calls (see below), any existing library that already
uses <code>log</code> is compatible. This, for our use cases, is a huge win, as opposed to using up &quot;weirdness
budget&quot; and requiring custom tooling for something that is often trivial, throw-away, simple logging.</li>
<li>it follows that one can easily drop a <code>trace!(&quot;{:?}&quot;, &amp;suspicious_object)</code> call at any time for
any object that has a (possibly automatically derived) <code>Debug</code> trait implementation without
passing around structures and keeping on top of lifetimes.</li>
<li>deferred logging: This is a typical &quot;shared memory&quot; logger, calls to <code>info!</code> etc.
are not directly sent to their final output, but instead are stored in a circular buffer
that is &quot;drained&quot; by calling <code>flush</code> on the logger at a convenient moment, for instance
in an idle loop.</li>
<li>immediate mode logging: Sometimes one wants to bypass the deferred flushing of logs,
this is possible using either the little-known <code>target</code> argument to <code>info!</code> and friends
with &quot;!&quot; as parameter, or using the additional <code>immediate_info!</code> and friends macros.</li>
<li>ability to set log levels <em>per library, at compile-time</em>. This can be easily retro-fitted
on existing <code>log</code>-based libraries, by adding the requisite features in <code>Cargo.toml</code> and
replacing <code>log</code> with <code>delog</code> (see <code>gate-tests</code> for examples of this).</li>
<li>the outcome is that one can leave useful logging calls in the library code, only to activate
them in targeted ways at build time, exactly as needed.</li>
<li>helper macros to easily output binary byte arrays and slices in hexadecimal representations,
which wrap the data in newtypes with custom <code>fmt::UpperHex</code> etc. implementations.</li>
</ul>
<p><strong>Non-goals</strong>:</p>
<ul>
<li>ultimate speed or code size: Our intention are &quot;normal&quot; logs, not the use of logging/tracing to
for stream binary data to the host. While admittedly the <code>core::fmt</code>-ing facilities are not as
efficient as one might hope, in our use cases we have sufficient flash and RAM to use these (and
some hope that, someday, eventually, maybe, the formatting machinery will be revisited and
improved at the root level, namely the language itself.)</li>
</ul>
<p>That said, we believe there is opportunity to extend <code>delog</code> in the <code>defmt</code> direction by
using, e.g., the <code>fmt::Binary</code> trait, newtypes and sentinel values to embed raw binary
representations of data in time-critical situations without formatting, deferring
the extraction and actual formatting to some host-side mechanism.</p>
<h2 id="features" class="section-header"><a href="#features">Features</a></h2>
<p>The <code>flushers</code> and <code>semihosting</code> features mostly exist to share code within the examples,
including the <code>example</code> feature. Without them, dependencies are quite minimal, and compilation fast.</p>
<p>The <code>fallible</code> and <code>immediate</code> features (default on) activate the <code>try_*!</code> and <code>*_now!</code> macros, respectively.</p>
<h2 id="warning" class="section-header"><a href="#warning">Warning</a></h2>
<p>The current circular buffer implementation (v0.1.0) is definitely unsound on desktop.
For embedded use, atomics are required (so no Cortex-M0/M1, and no plans to support non-atomic
platforms, which are likely to also be too resource-constrained to support the bloat inherent
in <code>core::fmt</code>). While we think the implemented circular buffer algorithm works for the &quot;nested interrupt&quot;
setup of NVICs, it has not been tested much.
The hope is that the worst case scenario is some slightly messed up log outputs.</p>
<h2 id="outlook" class="section-header"><a href="#outlook">Outlook</a></h2>
<p>We plan to iterate towards a v0.2.0 soon, making use of a separate &quot;flusher&quot; for the
&quot;immediate&quot; logging path. For instance, when logging via serial-over-USB, one might want immediate
logs to pend a separate RTIC interrupt handler that blocks until the logs are pushed and read
(allowing one to debug the boot process of a firmware), or one might want to just write to RTT
(or even semihosting xD) for these, during development.</p>
</div><h2 id="reexports" class="section-header"><a href="#reexports">Re-exports</a></h2>
<table><tr><td><code>pub use <a class="mod" href="../log/index.html" title="mod log">log</a>;</code></td></tr></table><h2 id="modules" class="section-header"><a href="#modules">Modules</a></h2>
<table><tr class="module-item"><td><a class="mod" href="hex/index.html" title="delog::hex mod">hex</a></td><td class="docblock-short"><p>Convenient <code>Display</code> and other traits for binary data.</p>
</td></tr><tr class="module-item"><td><a class="mod" href="render/index.html" title="delog::render mod">render</a></td><td class="docblock-short"><p>The default, minimal renderer, and some helper functions.</p>
</td></tr></table><h2 id="macros" class="section-header"><a href="#macros">Macros</a></h2>
<table><tr class="module-item"><td><a class="macro" href="macro.delog.html" title="delog::delog macro">delog</a></td><td class="docblock-short"><p>Generate a deferred logger with specified capacity and flushing mechanism.</p>
</td></tr><tr class="module-item"><td><a class="macro" href="macro.generate_macros.html" title="delog::generate_macros macro">generate_macros</a></td><td class="docblock-short"><p>Generate logging macros that can be gated by library.</p>
</td></tr><tr class="module-item"><td><a class="macro" href="macro.hex_str.html" title="delog::hex_str macro">hex_str</a></td><td class="docblock-short"><p>Compactly format byte arrays and slices as hexadecimals.</p>
</td></tr><tr class="module-item"><td><a class="macro" href="macro.hexstr.html" title="delog::hexstr macro">hexstr</a></td><td class="docblock-short"><p>More compactly format byte arrays and slices as hexadecimals.</p>
</td></tr><tr class="module-item"><td><a class="macro" href="macro.try_log.html" title="delog::try_log macro">try_log</a></td><td class="docblock-short"><p>Fallible (ungated) version of <code>log!</code>.</p>
</td></tr></table><h2 id="structs" class="section-header"><a href="#structs">Structs</a></h2>
<table><tr class="module-item"><td><a class="struct" href="struct.Record.html" title="delog::Record struct">Record</a></td><td class="docblock-short"><p>The &quot;payload&quot; of a log message.</p>
</td></tr><tr class="module-item"><td><a class="struct" href="struct.Statistics.html" title="delog::Statistics struct">Statistics</a></td><td class="docblock-short"><p>Statistics on logger usage.</p>
</td></tr></table><h2 id="enums" class="section-header"><a href="#enums">Enums</a></h2>
<table><tr class="module-item"><td><a class="enum" href="enum.Level.html" title="delog::Level enum">Level</a></td><td class="docblock-short"><p>An enum representing the available verbosity levels of the logger.</p>
</td></tr><tr class="module-item"><td><a class="enum" href="enum.LevelFilter.html" title="delog::LevelFilter enum">LevelFilter</a></td><td class="docblock-short"><p>An enum representing the available verbosity level filters of the logger.</p>
</td></tr></table><h2 id="traits" class="section-header"><a href="#traits">Traits</a></h2>
<table><tr class="module-item"><td><a class="trait" href="trait.Delogger.html" title="delog::Delogger trait">Delogger</a></td><td class="docblock-short"><p>Semi-abstract characterization of the deferred loggers that the <code>delog!</code> macro produces.</p>
</td></tr><tr class="module-item"><td><a class="trait" href="trait.Flusher.html" title="delog::Flusher trait">Flusher</a></td><td class="docblock-short"><p>A way to pass on logs, user supplied.</p>
</td></tr><tr class="module-item"><td><a class="trait" href="trait.Renderer.html" title="delog::Renderer trait">Renderer</a></td><td class="docblock-short"><p>A way to format logs, user supplied.</p>
</td></tr><tr class="module-item"><td><a class="trait" href="trait.State.html" title="delog::State trait">State</a></td><td class="docblock-short"><p>Trait for either state or statistics of loggers.</p>
</td></tr><tr class="module-item"><td><a class="trait" href="trait.TryLog.html" title="delog::TryLog trait">TryLog</a></td><td class="docblock-short"><p>Fallible, panic-free version of the <code>log::Log</code> trait.</p>
</td></tr><tr class="module-item"><td><a class="trait" href="trait.TryLogWithStatistics.html" title="delog::TryLogWithStatistics trait">TryLogWithStatistics</a></td><td class="docblock-short"><p>TryLog with some usage statistics on top.</p>
</td></tr></table><h2 id="functions" class="section-header"><a href="#functions">Functions</a></h2>
<table><tr class="module-item"><td><a class="fn" href="fn.dequeue.html" title="delog::dequeue fn">dequeue</a><a title="unsafe function" href="#"><sup></sup></a></td><td class="docblock-short"><p>The core &quot;read from circular buffer&quot; method. Marked unsafe to discourage use!</p>
</td></tr><tr class="module-item"><td><a class="fn" href="fn.enqueue.html" title="delog::enqueue fn">enqueue</a><a title="unsafe function" href="#"><sup></sup></a></td><td class="docblock-short"><p>The core &quot;write to circular buffer&quot; method. Marked unsafe to discourage use!</p>
</td></tr><tr class="module-item"><td><a class="fn" href="fn.logger.html" title="delog::logger fn">logger</a></td><td class="docblock-short"><p>Returns a reference to the logger (as <code>TryLogWithStatistics</code> implementation)</p>
</td></tr><tr class="module-item"><td><a class="fn" href="fn.try_enqueue.html" title="delog::try_enqueue fn">try_enqueue</a><a title="unsafe function" href="#"><sup></sup></a></td><td class="docblock-short"><p>The fallible &quot;write to circular buffer&quot; method. Marked unsafe to discourage use!</p>
</td></tr></table></section><section id="search" class="content hidden"></section><section class="footer"></section><script>window.rootPath = "../";window.currentCrate = "delog";</script><script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>