blob: d699bcdd84d92fc17b1779357a4f0c07c33d9a3e [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 class="active"><a href="./">Stats</a>
<ul>
</ul>
</li>
<li ><a href="../../logs/logs/">Logs</a>
</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; Stats</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/stats/stats.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>
<h1 id="statistics-module">Statistics Module</h1>
<p>The statistics module allows application, libraries, or drivers to
record statistics that can be shown via the Newtmgr tool and console.</p>
<p>This allows easy integration of statistics for troubleshooting,
maintenance, and usage monitoring.</p>
<p>By creating and registering your statistics, they are automatically
included in the Newtmgr shell and console APIs.</p>
<h3 id="implementation-details">Implementation Details</h3>
<p>A statistic is an unsigned integer that can be set by the
code. When building stats, the implementer chooses the size of the
statistic depending on the frequency of the statistic and the
resolution required before the counter wraps. </p>
<p>Typically the stats are incremented upon code events; however, they are
not limted to that purpose. </p>
<p>Stats are organized into sections. Each section of stats has its own
name and can be queried separately through the API. Each section of stats
also has its own statistic size, allowing the user to separate large (64-bit)
statistics from small (16 bit statistics). NOTE: It is not currently possible
to group different size stats into the same section. Please ensure all stats
in a section have the same size.</p>
<p>Stats sections are currently stored in a single global stats group. </p>
<p>Statistics are stored in a simple structure which contains a small
stats header followed by a list of stats. The stats header contains:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>struct stats_hdr {
char *s_name;
uint8_t s_size;
uint8_t s_cnt;
uint16_t s_pad1;
#if MYNEWT_VAL(STATS_NAMES)
const struct stats_name_map *s_map;
int s_map_cnt;
#endif
STAILQ_ENTRY(stats_hdr) s_next;
};
</code></pre></div>
<p>The fields define with in the <code>#if MYNEWT_VAL(STATS_NAME)</code> directive are only inincluded when the <code>STATS_NAMES</code> syscfg setting is set to 1 and enables use statistic names.
<br></p>
<h4 id="enabling-statistic-names">Enabling Statistic Names</h4>
<p>By default, statistics are queried by number. You can use the <code>STATS_NAMES</code> syscfg setting to enable statistic names and view the results by name. Enabling statistic names provides better descriptions in the reported statistics, but takes code space to store the strings within the image.</p>
<p>To enable statistic names, set the <code>STATS_NAMES</code> value to 1 in the application <code>syscfg.yml</code> file or use the <code>newt target set</code> command to set the syscfg setting value. Here are examples for each method:</p>
<p>Method 1 - Set the value in the application <code>syscfg.yml</code> files:
<br></p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code># Package: apps/myapp
syscfg.vals:
STATS_NAMES: 1
</code></pre></div>
<p><br></p>
<p>Method 2 - Set the target <code>syscfg</code> variable: </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>newt target set myapp syscfg=STATS_NAMES=1
</code></pre></div>
<p><strong>Note:</strong> This <code>newt target set</code> command only sets the syscfg variable for the <code>STATS_NAMES</code> setting as an example. For your target, you should set the syscfg variable with the other settings that you want to override. </p>
<p><br></p>
<h3 id="adding-stats-to-your-code">Adding Stats to your code.</h3>
<p>Creating new stats table requires the following steps.</p>
<ul>
<li>Include the stats header file </li>
<li>Define a stats section</li>
<li>Declare an instance of the section </li>
<li>Define the stat sections names table</li>
<li>Implement stat in your code</li>
<li>Initialize the stats</li>
<li>Register the stats</li>
</ul>
<p><br></p>
<h4 id="include-the-stats-header-file">Include the stats header file</h4>
<p>Add the stats library to your pkg.yml file for your package or app by adding
this line to your package dependencies.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.deps:
- &quot;@apache-mynewt-core/sys/stats&quot;
</code></pre></div>
<p><br></p>
<p>Add this include directive to code files using the stats library.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>#include &lt;stats/stats.h&gt;
</code></pre></div>
<p><br></p>
<h4 id="define-a-stats-section">Define a stats section</h4>
<p>You must use the <code>stats.h</code> macros to define your stats table. A
stats section definition looks like this. </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>STATS_SECT_START(my_stat_section)
STATS_SECT_ENTRY(attempt_stat)
STATS_SECT_ENTRY(error_stat)
STATS_SECT_END
</code></pre></div>
<p><br></p>
<p>In this case we chose to make the stats 32-bits each. <code>stats.h</code> supports three
different stats sizes through the following macros:</p>
<ul>
<li><code>STATS_SIZE_16</code> -- stats are 16 bits (wraps at 65536)</li>
<li><code>STATS_SIZE_32</code> -- stats are 32 bits (wraps at 4294967296)</li>
<li><code>STATS_SIZE_64</code> -- stats are 64-bits</li>
</ul>
<p>When this compiles/pre-processes, it produces a structure definition like this</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>struct stats_my_stat_section {
struct stats_hdr s_hdr;
uint32_t sattempt_stat;
uint32_t serror_stat;
};
</code></pre></div>
<p><br></p>
<p>You can see that the defined structure has a small stats structure
header and the two stats we have defined.</p>
<p>Depending on whether these stats are used in multiple modules, you may need
to include this definition in a header file.</p>
<p><br></p>
<h4 id="declaring-a-variable-to-hold-the-stats">Declaring a variable to hold the stats</h4>
<p>Declare the global variable to hold your statistics. Since it is possible to
have multiple copies of the same section (for example a stat section for
each of 5 identical peripherals), the variable name of the stats section
must be unique.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>STATS_SECT_DECL(my_stat_section) g_mystat;
</code></pre></div>
<p><br></p>
<p>Again, if your stats section is used in multiple C files you will need to
include the above definition in one of the C files and 'extern' this declaration
in your header file.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>extern STATS_SECT_DECL(my_stat_section) g_mystat;
</code></pre></div>
<p><br></p>
<h4 id="define-the-stats-section-name-table">Define the stats section name table</h4>
<p>Whether or not you have <code>STATS_NAMES</code> enabled, you must define
a stats name table. If <code>STATS_NAMES</code> is not enabled, this will
not take any code space or image size. </p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>/* define a few stats for querying */
STATS_NAME_START(my_stat_section)
STATS_NAME(my_stat_section, attempt_stat)
STATS_NAME(my_stat_section, error_stat)
STATS_NAME_END(my_stat_section)
</code></pre></div>
<p><br></p>
<p>When compiled by the preprocessor, it creates a structure that looks like this.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>struct stats_name_map g_stats_map_my_stat_section[] = {
{ __builtin_offsetof (struct stats_my_stat_section, sattempt_stat), &quot;attempt_stat&quot; },
{ __builtin_offsetof (struct stats_my_stat_section, serror_stat), &quot;error_stat&quot; },
};
</code></pre></div>
<p><br></p>
<p>This table will allow the UI components to find a nice string name for the
stat.</p>
<p><br></p>
<h4 id="implement-stats-in-your-code">Implement stats in your code.</h4>
<p>You can use the <code>STATS_INC</code> or <code>STATS_INCN</code> macros to increment your statistics
within your C-code. For example, your code may do this:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> STATS_INC(g_mystat, attempt_stat);
rc = do_task();
if(rc == ERR) {
STATS_INC(g_mystat, error_stat);
}
</code></pre></div>
<p><br></p>
<h4 id="initialize-the-statistics">Initialize the statistics</h4>
<p>You must initialize the stats so they can be operated on by the stats
library. As per our example above, it would look like the following.</p>
<p>This tells the system how large each statistic is and the number of
statistics in the section. It also initialize the name information for
the statistics if enabled as shown above.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> rc = stats_init(
STATS_HDR(g_mystat),
STATS_SIZE_INIT_PARMS(g_mystat, STATS_SIZE_32),
STATS_NAME_INIT_PARMS(my_stat_section));
assert(rc == 0);
</code></pre></div>
<p><br></p>
<h4 id="register-the-statistic-section">Register the statistic section</h4>
<p>If you want the system to know about your stats, you must register them.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> rc = stats_register(&quot;my_stats&quot;, STATS_HDR(g_mystat));
assert(rc == 0);
</code></pre></div>
<p><br></p>
<p>There is also a method that does initialization and registration at the
same time, called <code>stats_init_and_reg</code>.</p>
<p><br></p>
<h3 id="retrieving-stats-through-console-or-newtmgr">Retrieving stats through console or Newtmgr</h3>
<p>If you enable console in your project you can see stats through the
serial port defined.</p>
<p>This is the stats as shown from the example above with names enabled.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>stat my_stats
12274:attempt_stat: 3
12275:error_stat: 0
</code></pre></div>
<p><br></p>
<p>This is the stats as shown from the example without names enabled.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>stat my_stats
29149:s0: 3
29150:s1: 0
</code></pre></div>
<p><br></p>
<h3 id="a-note-on-multiple-stats-sections">A note on multiple stats sections</h3>
<p>If you are implementing a device with multiple instances, you may
want multiple stats sections with the exact same format.</p>
<p>For example, suppose I write a driver for an external distance sensor. My
driver supports up to 5 sensors and I want to record the stats of
each device separately.</p>
<p>This works identically to the example above, except you would need to
register each one separately with a unique name. The stats system will
not let two sections be entered with the same name.</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>