blob: ba460928011894dac66642e78f78d7200a44aade [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../../img/favicon.ico">
<title>toc - Apache Mynewt</title>
<link href="../../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../../css/highlight.css">
<link href="../../../../css/base.css" rel="stylesheet">
<link href="../../../../css/custom.css" rel="stylesheet">
<link href="../../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="toc">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li
class=""
>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li
class="important"
>
<a href="/quick-start/">Quick Start</a>
</li>
<li
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_12_0/" >
Version: 1.12.0
</option>
<option value="/v1_11_0/" >
Version: 1.11.0
</option>
<option value="/v1_10_0/" >
Version: 1.10.0
</option>
<option value="/v1_9_0/" >
Version: 1.9.0
</option>
<option value="/v1_8_0/" >
Version: 1.8.0
</option>
<option value="/v1_7_0/" >
Version: 1.7.0
</option>
<option value="/v1_6_0/" >
Version: 1.6.0
</option>
<option value="/v1_5_0/" >
Version: 1.5.0
</option>
<option value="/v1_4_0/" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" selected="selected" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select></li>
<li ><a href="../../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../../../tutorials/tutorials/">Tutorials</a>
</li>
<li ><a href="../../../os_user_guide/">OS User Guide</a>
<ul>
<li ><a href="../../../core_os/mynewt_os/">OS Core</a>
</li>
<li ><a href="../../../core_os/porting/port_os/">Porting to your Platform</a>
</li>
<li ><a href="../../console/console/">Console</a>
</li>
<li ><a href="../../shell/shell/">Shell</a>
</li>
<li ><a href="../../split/split/">Split Images</a>
</li>
<li ><a href="../../bootloader/bootloader/">Bootloader</a>
</li>
<li><a href="
../../fs/fs/fs/
">File System</a>
</li>
<li ><a href="../../hal/hal/">Hardware Abstraction Layer</a>
</li>
<li ><a href="../../drivers/driver/">Drivers</a>
</li>
<li ><a href="../../testutil/testutil/">Test Utilities</a>
</li>
<li ><a href="../../devmgmt/newtmgr/">Device Management with Newt Manager</a>
</li>
<li ><a href="../../imgmgr/imgmgr/">Image Manager</a>
</li>
<li >
<a href="../../baselibc/">Baselibc library</a>
</li>
<li ><a href="../../json/json/">JSON</a>
</li>
<li ><a href="../../fcb/fcb/">Flash Circular Buffer</a>
</li>
<li ><a href="../../stats/stats/">Stats</a>
</li>
<li class="active"><a href="./">Logs</a>
<ul>
</ul>
</li>
<li ><a href="../../sysinitconfig/sysinitconfig/">System Configuration And Initialization</a>
</li>
</ul>
</li>
<li><a href="
../../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../../faq/go_env/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; Logs</li>
<li>&raquo; <a href="os/os_user_guide/">OS User Guide</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.0.0 is not the most recent version of the Apache Mynewt
documentation. Click <a href="/latest">here</a> to read the latest
version.
</p>
</div>
<h2 id="logging">Logging</h2>
<p>Mynewt log package supports logging of information within a Mynewt application. It allows packages to define their own log streams with separate names. It also allows an application to control the output destination of logs.
<br></p>
<h3 id="description">Description</h3>
<p>In the Mynewt OS, the log package comes in two versions:</p>
<ul>
<li>
<p>The <code>sys/log/full</code> package implements the complete log functionality and API.</p>
</li>
<li>
<p>The <code>sys/log/stub</code> package implements stubs for the API.</p>
</li>
</ul>
<p>Both packages export the <code>log</code> API, and any package that uses the log API must list <code>log</code> as a requirement in its <code>pkg.yml</code> file as follows: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.req_apis:
- log
</code></pre></div>
<p><br>
The application's <code>pkg.yml</code> file specifies the version of the log package to use.
A project that requires the full logging capability must list the <code>sys/log/full</code> package as a dependency in its <code>pkg.yml</code> file:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.deps:
- sys/log/full
</code></pre></div>
<p><br>
You can use the <code>sys/log/stub</code> package if you want to build your application without logging to reduce code size.</p>
<p><br></p>
<h4 id="compile-time-settings">Compile Time Settings</h4>
<p>To save space at compile time, there is a compile time log level that
includes/excludes certain logs at compile time, saving image space. For
example, during debug, you can have significant logs present, but disable
these at compile time to ensure the code size limits are met.</p>
<p>A compiler flag <code>LOG_LEVEL</code> can be set in your <code>target.cflags</code> or within
your app <code>pkg.cflags</code> files to set the compile time log level. The
log level are defined in <code>/sys/log/full/include/log/log.h</code>
but must be added by number to your <code>yml</code> file.</p>
<p>For example:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> pkg.cflags -DLOG_LEVEL=3
</code></pre></div>
<p>or </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> newt target set my_target cflags=-DLOG_LEVEL=3
</code></pre></div>
<p>would both set the compile-time log level to <code>LOG_LEVEL_ERROR</code>. All logs
of less than <code>LOG_LEVEL_ERROR</code> severity would be disabled at compile
time and take no space within the Mynewt application image.</p>
<p>These compile time settings are applicable to all logs registered with the
system.</p>
<p><br></p>
<h3 id="log">Log</h3>
<p>Each log stream requires a <code>log</code> structure to define its logging properties.
<br></p>
<h3 id="log-handler">Log Handler</h3>
<p>To use logs, a log handler that handles the I/O from the log is required. The log package comes with three pre-built log handlers:</p>
<ul>
<li>console -- streams log events directly to the console port. Does
not support walking and reading.</li>
<li>cbmem -- writes/reads log events to a circular buffer. Supports walking
and reading for access by newtmgr and shell commands.</li>
<li>fcb -- writes/reads log events to a <a href="/os/modules/fcb/fcb.md">flash circular buffer</a>. Supports walking and reading for access by newtmgr and shell commands.</li>
</ul>
<p>In addition, it is possible to create custom log handlers for other methods.
Examples may include</p>
<ul>
<li>Flash file system</li>
<li>Flat flash buffer</li>
<li>Streamed over some other interface</li>
</ul>
<p>To use logging, you typically do not need to create your own log handler. You can use one of the pre-built ones.</p>
<p>A package or an application must define a variable of type <code>struct log</code> and register a log handler for it with the log package. It must call the <code>log_register()</code> function to specify the log handler to use:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #000000">log_register</span>(<span style="color: #A90D91">char</span> <span style="color: #000000">*name</span>, <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">log</span> <span style="color: #000000">*log</span>, <span style="color: #A90D91">const</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">log_handler</span> <span style="color: #000000">*lh</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>, <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">level</span>)
</code></pre></div>
<p>The parameters are:</p>
<ul>
<li><code>name</code>- Name of the log stream.</li>
<li><code>log</code> - Log instance to register,</li>
<li><code>lh</code> - Pointer to the log handler. You can specify one of the pre-built ones: <ul>
<li><code>&amp;log_console_handler</code> for console</li>
<li><code>&amp;log_cbm_handler</code> for circular buffer </li>
<li><code>&amp;log_fcb_handler</code> for flash circular buffer</li>
</ul>
</li>
<li><code>arg</code> - Opaque argument that the specified log handler uses. The value of this argument depends on the log handler you specify:<ul>
<li>NULL for the <code>log_console_handler</code>.</li>
<li>Pointer to an initialized <code>cbmem</code> structure (see <code>util/cbmem</code> package) for the <code>log_cbm_handler</code>.</li>
<li>Pointer to an initialized <code>fcb_log</code> structure (see <code>fs/fcb</code> package) for the <code>log_fcb_handler</code>. </li>
</ul>
</li>
</ul>
<p>Typically, a package that uses logging defines a global variable, such as <code>my_package_log</code>, of type <code>struct log</code>. The package can call the <code>log_register()</code> function with default values, but usually an application will override the logging properties and where to log to. There are two ways a package can allow an application to override the values:</p>
<ul>
<li>Define system configuration settings that an application can set and the package can then call the <code>log_register()</code> function with the configuration values.</li>
<li>Make the <code>my_package_log</code> variable external and let the application call the <code>log_register()</code> function to specify a log handler for its specific purpose. </li>
</ul>
<h3 id="configuring-logging-for-packages-that-an-application-uses">Configuring Logging for Packages that an Application Uses</h3>
<p>Here is an example of how an application can set the log handlers for the logs of the packages that the application includes. </p>
<p>In this example, the <code>package1</code> package defines the variable <code>package1_log</code> of type <code>struct log</code> and externs the variable. Similarly, the <code>package2</code> package defines the variable <code>package2_log</code> and externs the variable. The application sets logs for <code>package1</code> to use console and sets logs for <code>package2</code> to use a circular buffer.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#include</span> <span style="color: #177500">&lt;package1/package1.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;package2/package2.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;util/cbmem.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;log/log.h&gt;</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">uint32_t</span> <span style="color: #000000">cbmem_buf</span>[<span style="color: #000000">MAX_CBMEM_BUF</span>];
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">cbmem</span> <span style="color: #000000">cbmem</span>;
<span style="color: #A90D91">void</span> <span style="color: #000000">app_log_init</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #000000">log_register</span>(<span style="color: #C41A16">&quot;package1_log&quot;</span>, <span style="color: #000000">&amp;package1_log</span>, <span style="color: #000000">&amp;log_console_handler</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">LOG_SYSLEVEL</span>);
<span style="color: #000000">cbmem_init</span>(<span style="color: #000000">&amp;cbmem</span>, <span style="color: #000000">cbmem_buf</span>, <span style="color: #000000">MAX_CBMEM_BUF</span>);
<span style="color: #000000">log_register</span>(<span style="color: #C41A16">&quot;package2_log&quot;</span>, <span style="color: #000000">&amp;package2_log</span>, <span style="color: #000000">&amp;log_cbmem_handler</span>, <span style="color: #000000">&amp;cbmem</span>, <span style="color: #000000">LOG_SYSLEVEL</span>);
}
</code></pre></div>
<p><br></p>
<h3 id="implementing-a-package-that-uses-logging">Implementing a Package that Uses Logging</h3>
<p>This example shows how a package logs to console. The package registers default logging properties to use the console, but allows an application to override the values. It defines the <code>my_package_log</code> variable and makes it external so an application can override log handler.</p>
<p>Make the <code>my_package_log</code> variable external:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* my_package.h*/</span>
<span style="color: #177500">/* pick a unique name here */</span>
<span style="color: #A90D91">extern</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">log</span> <span style="color: #000000">my_package_log</span>;
</code></pre></div>
<p><br></p>
<p>Define the <code>my_package_log</code> variable and register the console log handler: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/* my_package.c */</span>
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">log</span> <span style="color: #000000">my_package_log</span>;
{
...
<span style="color: #177500">/* register my log with a name to the system */</span>
<span style="color: #000000">log_register</span>(<span style="color: #C41A16">&quot;log&quot;</span>, <span style="color: #000000">&amp;my_package_log</span>, <span style="color: #000000">&amp;log_console_handler</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">LOG_LEVEL_DEBUG</span>);
<span style="color: #000000">LOG_DEBUG</span>(<span style="color: #000000">&amp;my_package_log</span>, <span style="color: #000000">LOG_MODULE_DEFAULT</span>, <span style="color: #C41A16">&quot;bla&quot;</span>);
<span style="color: #000000">LOG_DEBUG</span>(<span style="color: #000000">&amp;my_package_log</span>, <span style="color: #000000">LOG_MODULE_DEFAULT</span>, <span style="color: #C41A16">&quot;bab&quot;</span>);
}
</code></pre></div>
<h3 id="log-api-and-log-levels">Log API and Log Levels</h3>
<p>For more information on the <code>log</code> API and log levels, see the <code>sys/log/full/include/log/log.h</code> header file.</p>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt (incubating) is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt
project logo are either registered trademarks or trademarks of the Apache
Software Foundation in the United States and other countries.
</small>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../../js/highlight.pack.js"></script>
<script src="../../../../js/base.js"></script>
<script src="../../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>