blob: f32e62fdb4b3b1a8fe0b143c5e792a18269d8321 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "os/os.h"
#include "shell/shell.h"
#include "console/console.h"
#include "metrics/metrics.h"
#include "tinycbor/cbor.h"
#include "tinycbor/cbor_mbuf_reader.h"
static STAILQ_HEAD(, metrics_event_hdr) g_event_list =
STAILQ_HEAD_INITIALIZER(g_event_list);
static struct metrics_event_hdr *
find_event_by_name(const char *name)
{
struct metrics_event_hdr *hdr;
STAILQ_FOREACH(hdr, &g_event_list, next) {
if (!strcmp(hdr->name, name)) {
break;
}
}
return hdr;
}
static int
find_metric_by_name(struct metrics_event_hdr *hdr, const char *name)
{
int i;
for (i = 0; i < hdr->count; i++) {
if (!strcmp(hdr->defs[i].name, name)) {
return i;
}
}
return -1;
}
static const char *
metric_type_str(uint8_t type)
{
switch (type) {
case METRICS_TYPE_SINGLE_U:
return "unsigned";
case METRICS_TYPE_SINGLE_S:
return "signed";
case METRICS_TYPE_SERIES_U8:
return "unsigned8-series";
case METRICS_TYPE_SERIES_S8:
return "signed8-series";
case METRICS_TYPE_SERIES_U16:
return "unsigned16-series";
case METRICS_TYPE_SERIES_S16:
return "signed16-series";
case METRICS_TYPE_SERIES_U32:
return "unsigned32-series";
case METRICS_TYPE_SERIES_S32:
return "signed32-series";
}
return "<unknown>";
}
static void
print_event_metrics(struct metrics_event_hdr *hdr)
{
int i;
for (i = 0; i < hdr->count; i++) {
console_printf(" %d = %s (%s, %d)\n", i, hdr->defs[i].name,
metric_type_str(hdr->defs[i].type),
!!(hdr->enabled & (1 << i)));
}
}
static int
cmd_list_events(int argc, char **argv)
{
struct metrics_event_hdr *hdr;
bool full = false;
if (argc > 1) {
full = atoi(argv[1]);
}
STAILQ_FOREACH(hdr, &g_event_list, next) {
console_printf("%s\n", hdr->name);
if (full) {
print_event_metrics(hdr);
}
}
return 0;
}
static int
cmd_list_event_metrics(int argc, char **argv)
{
struct metrics_event_hdr *hdr;
if (argc < 2) {
console_printf("Event name not specified\n");
return -1;
}
STAILQ_FOREACH(hdr, &g_event_list, next) {
if (!strcmp(hdr->name, argv[1])) {
print_event_metrics(hdr);
return 0;
}
}
console_printf("Event '%s' not found\n", argv[1]);
return -1;
}
static int
cmd_metric_set(int argc, char **argv)
{
struct metrics_event_hdr *hdr;
int i;
if (argc < 4) {
console_printf("Event and/or metric name not specified\n");
return -1;
}
hdr = find_event_by_name(argv[1]);
if (!hdr) {
console_printf("Event '%s' not found\n", argv[1]);
return -1;
}
i = find_metric_by_name(hdr, argv[2]);
if (i < 0) {
console_printf("Metric '%s' not found\n", argv[2]);
return -1;
}
metrics_set_state(hdr, i, atoi(argv[3]));
return -1;
}
static int
cmd_event_dump(int argc, char **argv)
{
struct cbor_mbuf_reader reader;
struct CborParser parser;
struct CborValue value;
struct metrics_event_hdr *hdr;
struct os_mbuf *om;
if (argc < 2) {
console_printf("Event name not specified\n");
return -1;
}
hdr = find_event_by_name(argv[1]);
if (!hdr) {
console_printf("Event '%s' not found\n", argv[1]);
return -1;
}
/* We use msys so serializing event to CBOR will be non-destructive */
om = os_msys_get_pkthdr(50, 0);
metrics_event_to_cbor(hdr, om);
cbor_mbuf_reader_init(&reader, om, 0);
cbor_parser_init(&reader.r, 0, &parser, &value);
cbor_value_to_pretty(stdout, &value);
os_mbuf_free_chain(om);
console_printf("\n");
return 0;
}
static int
cmd_event_end(int argc, char **argv)
{
struct metrics_event_hdr *hdr;
if (argc < 2) {
console_printf("Event name not specified\n");
return -1;
}
hdr = find_event_by_name(argv[1]);
if (!hdr) {
console_printf("Event '%s' not found\n", argv[1]);
return -1;
}
metrics_event_end(hdr);
return 0;
}
static const struct shell_cmd metrics_commands[] = {
{
.sc_cmd = "list-events",
.sc_cmd_func = cmd_list_events,
},
{
.sc_cmd = "list-event-metrics",
.sc_cmd_func = cmd_list_event_metrics,
},
{
.sc_cmd = "metric-set",
.sc_cmd_func = cmd_metric_set,
},
{
.sc_cmd = "event-dump",
.sc_cmd_func = cmd_event_dump,
},
{
.sc_cmd = "event-end",
.sc_cmd_func = cmd_event_end,
},
{ },
};
int
metrics_cli_register_event(struct metrics_event_hdr *hdr)
{
STAILQ_INSERT_TAIL(&g_event_list, hdr, next);
return 0;
}
int
metrics_cli_init(void)
{
shell_register("metrics", metrics_commands);
return 0;
}