Skip to content

Commit cb36bc4

Browse files
sys/metrics: Add shell interface
1 parent 0b1a52c commit cb36bc4

File tree

4 files changed

+303
-0
lines changed

4 files changed

+303
-0
lines changed

sys/metrics/src/cli.c

+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include <stddef.h>
21+
#include <stdlib.h>
22+
#include <string.h>
23+
#include "os/os.h"
24+
#include "shell/shell.h"
25+
#include "console/console.h"
26+
#include "metrics/metrics.h"
27+
#include "tinycbor/cbor.h"
28+
#include "tinycbor/cbor_mbuf_reader.h"
29+
30+
static STAILQ_HEAD(, metrics_event_hdr) g_event_list =
31+
STAILQ_HEAD_INITIALIZER(g_event_list);
32+
33+
static struct metrics_event_hdr *
34+
find_event_by_name(const char *name)
35+
{
36+
struct metrics_event_hdr *hdr;
37+
38+
STAILQ_FOREACH(hdr, &g_event_list, next) {
39+
if (!strcmp(hdr->name, name)) {
40+
break;
41+
}
42+
}
43+
44+
return hdr;
45+
}
46+
47+
static int
48+
find_metric_by_name(struct metrics_event_hdr *hdr, const char *name)
49+
{
50+
int i;
51+
52+
for (i = 0; i < hdr->count; i++) {
53+
if (!strcmp(hdr->defs[i].name, name)) {
54+
return i;
55+
}
56+
}
57+
58+
return -1;
59+
}
60+
61+
static const char *
62+
metric_type_str(uint8_t type)
63+
{
64+
switch (type) {
65+
case METRICS_TYPE_SINGLE_U:
66+
return "unsigned";
67+
case METRICS_TYPE_SINGLE_S:
68+
return "signed";
69+
case METRICS_TYPE_SERIES_U8:
70+
return "unsigned8-series";
71+
case METRICS_TYPE_SERIES_S8:
72+
return "signed8-series";
73+
case METRICS_TYPE_SERIES_U16:
74+
return "unsigned16-series";
75+
case METRICS_TYPE_SERIES_S16:
76+
return "signed16-series";
77+
case METRICS_TYPE_SERIES_U32:
78+
return "unsigned32-series";
79+
case METRICS_TYPE_SERIES_S32:
80+
return "signed32-series";
81+
}
82+
83+
return "<unknown>";
84+
}
85+
86+
static void
87+
print_event_metrics(struct metrics_event_hdr *hdr)
88+
{
89+
int i;
90+
91+
for (i = 0; i < hdr->count; i++) {
92+
console_printf(" %d = %s (%s, %d)\n", i, hdr->defs[i].name,
93+
metric_type_str(hdr->defs[i].type),
94+
!!(hdr->enabled & (1 << i)));
95+
}
96+
}
97+
98+
static int
99+
cmd_list_events(int argc, char **argv)
100+
{
101+
struct metrics_event_hdr *hdr;
102+
bool full = false;
103+
104+
if (argc > 1) {
105+
full = atoi(argv[1]);
106+
}
107+
108+
STAILQ_FOREACH(hdr, &g_event_list, next) {
109+
console_printf("%s\n", hdr->name);
110+
if (full) {
111+
print_event_metrics(hdr);
112+
}
113+
}
114+
115+
return 0;
116+
}
117+
118+
static int
119+
cmd_list_event_metrics(int argc, char **argv)
120+
{
121+
struct metrics_event_hdr *hdr;
122+
123+
if (argc < 2) {
124+
console_printf("Event name not specified\n");
125+
return -1;
126+
}
127+
128+
STAILQ_FOREACH(hdr, &g_event_list, next) {
129+
if (!strcmp(hdr->name, argv[1])) {
130+
print_event_metrics(hdr);
131+
return 0;
132+
}
133+
}
134+
135+
console_printf("Event '%s' not found\n", argv[1]);
136+
137+
return -1;
138+
}
139+
140+
static int
141+
cmd_metric_set(int argc, char **argv)
142+
{
143+
struct metrics_event_hdr *hdr;
144+
int i;
145+
146+
if (argc < 4) {
147+
console_printf("Event and/or metric name not specified\n");
148+
return -1;
149+
}
150+
151+
hdr = find_event_by_name(argv[1]);
152+
if (!hdr) {
153+
console_printf("Event '%s' not found\n", argv[1]);
154+
return -1;
155+
}
156+
157+
i = find_metric_by_name(hdr, argv[2]);
158+
if (i < 0) {
159+
console_printf("Metric '%s' not found\n", argv[2]);
160+
return -1;
161+
}
162+
163+
metrics_set_state(hdr, i, atoi(argv[3]));
164+
165+
return -1;
166+
}
167+
168+
static int
169+
cmd_event_dump(int argc, char **argv)
170+
{
171+
struct cbor_mbuf_reader reader;
172+
struct CborParser parser;
173+
struct CborValue value;
174+
struct metrics_event_hdr *hdr;
175+
struct os_mbuf *om;
176+
177+
if (argc < 2) {
178+
console_printf("Event name not specified\n");
179+
return -1;
180+
}
181+
182+
hdr = find_event_by_name(argv[1]);
183+
if (!hdr) {
184+
console_printf("Event '%s' not found\n", argv[1]);
185+
return -1;
186+
}
187+
188+
/* We use msys so serializing event to CBOR will be non-destructive */
189+
om = os_msys_get_pkthdr(50, 0);
190+
metrics_event_to_cbor(hdr, om);
191+
cbor_mbuf_reader_init(&reader, om, 0);
192+
cbor_parser_init(&reader.r, 0, &parser, &value);
193+
cbor_value_to_pretty(stdout, &value);
194+
os_mbuf_free_chain(om);
195+
196+
console_printf("\n");
197+
198+
return 0;
199+
}
200+
201+
static int
202+
cmd_event_end(int argc, char **argv)
203+
{
204+
struct metrics_event_hdr *hdr;
205+
206+
if (argc < 2) {
207+
console_printf("Event name not specified\n");
208+
return -1;
209+
}
210+
211+
hdr = find_event_by_name(argv[1]);
212+
if (!hdr) {
213+
console_printf("Event '%s' not found\n", argv[1]);
214+
return -1;
215+
}
216+
217+
metrics_event_end(hdr);
218+
219+
return 0;
220+
}
221+
222+
static const struct shell_cmd metrics_commands[] = {
223+
{
224+
.sc_cmd = "list-events",
225+
.sc_cmd_func = cmd_list_events,
226+
},
227+
{
228+
.sc_cmd = "list-event-metrics",
229+
.sc_cmd_func = cmd_list_event_metrics,
230+
},
231+
{
232+
.sc_cmd = "metric-set",
233+
.sc_cmd_func = cmd_metric_set,
234+
},
235+
{
236+
.sc_cmd = "event-dump",
237+
.sc_cmd_func = cmd_event_dump,
238+
},
239+
{
240+
.sc_cmd = "event-end",
241+
.sc_cmd_func = cmd_event_end,
242+
},
243+
{ },
244+
};
245+
246+
int
247+
metrics_cli_register_event(struct metrics_event_hdr *hdr)
248+
{
249+
STAILQ_INSERT_TAIL(&g_event_list, hdr, next);
250+
251+
return 0;
252+
}
253+
254+
int
255+
metrics_cli_init(void)
256+
{
257+
shell_register("metrics", metrics_commands);
258+
259+
return 0;
260+
}

sys/metrics/src/metrics.c

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "tinycbor/cbor.h"
2929
#include "tinycbor/cbor_mbuf_writer.h"
3030
#include "log/log.h"
31+
#include "metrics_priv.h"
3132

3233
#define MBUF_MEMBLOCK_OVERHEAD \
3334
(sizeof(struct os_mbuf))
@@ -555,4 +556,8 @@ metrics_pkg_init(void)
555556
rc = os_mbuf_pool_init(&event_metric_mbuf_pool, &event_metric_mempool,
556557
MEMPOOL_SIZE, MEMPOOL_COUNT);
557558
assert(rc == 0);
559+
560+
#if MYNEWT_VAL(METRICS_CLI)
561+
metrics_cli_init();
562+
#endif
558563
}

sys/metrics/src/metrics_priv.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#ifndef __METRICS_PRIV_H__
21+
#define __METRICS_PRIV_H__
22+
23+
#ifdef __cplusplus
24+
extern "C" {
25+
#endif
26+
27+
int metrics_cli_init(void);
28+
int metrics_cli_register_event(struct metrics_event_hdr *hdr);
29+
30+
#ifdef __cplusplus
31+
}
32+
#endif
33+
34+
#endif /* __METRICS_PRIV_H__ */

sys/metrics/syscfg.yml

+4
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ syscfg.defs:
2525
METRICS_POOL_COUNT:
2626
description: Block count for metrics' mempool
2727
value: 100
28+
29+
METRICS_CLI:
30+
description: Enable shell interface
31+
value: 0

0 commit comments

Comments
 (0)