blob: 345a5cbbac9ff8296c9a15ee4b2823d761b28c01 [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" selected="selected" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
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="../../sensor_framework/sensor_framework_overview/">Sensor Framework</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>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/modules/logs/logs.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.1.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="syscfg-settings">Syscfg Settings</h4>
<p>The <code>LOG_LEVEL</code> syscfg setting allows you to specify the level of logs to enable in your application. Only logs for levels higher or equal to the value of <code>LOG_LEVEL</code> are enabled. The amount of logs you include affects your application code size. <code>LOG_LEVEL: 0</code> specifies LOG_LEVEL_DEBUG and includes all logs. You set <code>LOG_LEVEL: 255</code> to disable all logging. The <code>#defines</code> for the log levels are specified in the <code>sys/log/full/include/log/log.h</code> file. For example the following setting corresponds to LOG_LEVEL_ERROR:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>syscfg.vals:
LOG_LEVEL: 3
</code></pre></div>
<p>The <code>LOG_LEVEL</code> setting applies to all modules registered with the log package.</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 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>