diff options
author | Marko Kiiskila <marko@runtime.io> | 2016-05-19 14:56:52 -0700 |
---|---|---|
committer | Marko Kiiskila <marko@runtime.io> | 2016-05-19 14:56:52 -0700 |
commit | f54eda03b7881b9168bb027c9a352bacf73199b0 (patch) | |
tree | 08698545e6ef8b82b799f8041459f8175c812e88 /sys | |
parent | ffd7dd376df7393d516b62853eb8dee302e0931b (diff) | |
parent | c75f8e493628d9ea3796d3019a0f753e0346ab96 (diff) |
This closes #55.
Merge branch 'mynewt-add' of https://github.com/vrahane/incubator-mynewt-core into develop
Diffstat (limited to 'sys')
-rw-r--r-- | sys/log/include/log/log.h | 40 | ||||
-rw-r--r-- | sys/log/src/log.c | 15 | ||||
-rw-r--r-- | sys/log/src/log_nmgr.c | 327 | ||||
-rw-r--r-- | sys/stats/src/stats_nmgr.c | 59 |
4 files changed, 377 insertions, 64 deletions
diff --git a/sys/log/include/log/log.h b/sys/log/include/log/log.h index 6109477b..d5b807f3 100644 --- a/sys/log/include/log/log.h +++ b/sys/log/include/log/log.h @@ -24,6 +24,12 @@ #include <os/queue.h> +/* Global log info */ +struct log_info { + int64_t li_timestamp; + uint8_t li_index; +} g_log_info; + struct log; typedef int (*log_walk_func_t)(struct log *, void *arg, void *offset, @@ -57,13 +63,21 @@ struct log_entry_hdr { }__attribute__((__packed__)); #define LOG_ENTRY_HDR_SIZE (sizeof(struct log_entry_hdr)) -#define LOG_LEVEL_DEBUG (0x01) -#define LOG_LEVEL_INFO (0x02) -#define LOG_LEVEL_WARN (0x04) -#define LOG_LEVEL_ERROR (0x08) -#define LOG_LEVEL_CRITICAL (0x10) +#define LOG_LEVEL_DEBUG (0) +#define LOG_LEVEL_INFO (1) +#define LOG_LEVEL_WARN (2) +#define LOG_LEVEL_ERROR (3) +#define LOG_LEVEL_CRITICAL (4) /* Up to 7 custom log levels. */ -#define LOG_LEVEL_PERUSER (0x12) +#define LOG_LEVEL_MAX (255) + +#define LOG_LEVEL_STR(level) \ + (LOG_LEVEL_DEBUG == level ? "DEBUG" :\ + (LOG_LEVEL_INFO == level ? "INFO" :\ + (LOG_LEVEL_WARN == level ? "WARN" :\ + (LOG_LEVEL_ERROR == level ? "ERROR" :\ + (LOG_LEVEL_CRITICAL == level ? "CRITICAL" :\ + "UNKNOWN"))))) /* Log module, eventually this can be a part of the filter. */ #define LOG_MODULE_DEFAULT (0) @@ -72,11 +86,22 @@ struct log_entry_hdr { #define LOG_MODULE_NIMBLE_CTLR (3) #define LOG_MODULE_NIMBLE_HOST (4) #define LOG_MODULE_NFFS (5) -#define LOG_MODULE_PERUSER (64) +#define LOG_MODULE_MAX (255) + +#define LOG_MODULE_STR(module) \ + (LOG_MODULE_DEFAULT == module ? "DEFAULT" :\ + (LOG_MODULE_OS == module ? "OS" :\ + (LOG_MODULE_NEWTMGR == module ? "NEWTMGR" :\ + (LOG_MODULE_NIMBLE_CTLR == module ? "NIMBLE_CTLR" :\ + (LOG_MODULE_NIMBLE_HOST == module ? "NIMBLE_HOST" :\ + (LOG_MODULE_NFFS == module ? "NFFS" :\ + "UNKNOWN")))))) /* UTC Timestamnp for Jan 2016 00:00:00 */ #define UTC01_01_2016 1451606400 +#define LOG_NAME_MAX_LEN (64) + /* Compile in Log Debug by default */ #ifndef LOG_LEVEL #define LOG_LEVEL LOG_LEVEL_DEBUG @@ -120,7 +145,6 @@ struct log_entry_hdr { struct log { char *l_name; struct log_handler *l_log; - uint8_t l_index; STAILQ_ENTRY(log) l_next; }; diff --git a/sys/log/src/log.c b/sys/log/src/log.c index fe22fd6d..484c8c83 100644 --- a/sys/log/src/log.c +++ b/sys/log/src/log.c @@ -103,10 +103,15 @@ log_append(struct log *log, uint16_t module, uint16_t level, void *data, int rc; struct os_timeval tv; - log->l_index++; - ue = (struct log_entry_hdr *) data; + /* Resetting index every millisecond */ + if (g_log_info.li_timestamp > ue->ue_ts + 1000) { + g_log_info.li_index = 0; + } + + g_log_info.li_index++; + /* Try to get UTC Time */ rc = os_gettimeofday(&tv, NULL); if (rc || tv.tv_sec < UTC01_01_2016) { @@ -114,9 +119,11 @@ log_append(struct log *log, uint16_t module, uint16_t level, void *data, } else { ue->ue_ts = tv.tv_sec * 1000000 + tv.tv_usec; } + + g_log_info.li_timestamp = ue->ue_ts; ue->ue_level = level; ue->ue_module = module; - ue->ue_index = log->l_index; + ue->ue_index = g_log_info.li_index; rc = log->l_log->log_append(log, data, len + LOG_ENTRY_HDR_SIZE); if (rc != 0) { @@ -182,7 +189,7 @@ log_flush(struct log *log) goto err; } - log->l_index = 0; + g_log_info.li_index = 0; return (0); err: diff --git a/sys/log/src/log_nmgr.c b/sys/log/src/log_nmgr.c index 03ad16ab..0d0d8365 100644 --- a/sys/log/src/log_nmgr.c +++ b/sys/log/src/log_nmgr.c @@ -35,26 +35,49 @@ static int log_nmgr_read(struct nmgr_jbuf *njb); static int log_nmgr_clear(struct nmgr_jbuf *njb); +static int log_nmgr_module_list(struct nmgr_jbuf *njb); +static int log_nmgr_level_list(struct nmgr_jbuf *njb); +static int log_nmgr_logs_list(struct nmgr_jbuf *njb); static struct nmgr_group log_nmgr_group; -#define LOGS_NMGR_ID_READ (0) -#define LOGS_NMGR_OP_CLEAR (1) + +/* Newtmgr Log opcodes */ +#define LOGS_NMGR_OP_READ (0) +#define LOGS_NMGR_OP_CLEAR (1) +#define LOGS_NMGR_OP_APPEND (2) +#define LOGS_NMGR_OP_MODULE_LIST (3) +#define LOGS_NMGR_OP_LEVEL_LIST (4) +#define LOGS_NMGR_OP_LOGS_LIST (5) /* ORDER MATTERS HERE. * Each element represents the command ID, referenced from newtmgr. */ static struct nmgr_handler log_nmgr_group_handlers[] = { - [LOGS_NMGR_ID_READ] = {log_nmgr_read, log_nmgr_read}, - [LOGS_NMGR_OP_CLEAR] = {log_nmgr_clear, log_nmgr_clear} + [LOGS_NMGR_OP_READ] = {log_nmgr_read, log_nmgr_read}, + [LOGS_NMGR_OP_CLEAR] = {log_nmgr_clear, log_nmgr_clear}, + [LOGS_NMGR_OP_MODULE_LIST] = {log_nmgr_module_list, NULL}, + [LOGS_NMGR_OP_LEVEL_LIST] = {log_nmgr_level_list, NULL}, + [LOGS_NMGR_OP_LOGS_LIST] = {log_nmgr_logs_list, NULL} +}; + +struct encode_off { + struct json_encoder *eo_encoder; + int64_t eo_ts; + uint8_t eo_index; }; +/** + * Log encode entry + * @param log structure, arg:struct passed locally, dataptr, len + * @return 0 on success; non-zero on failure + */ static int -log_nmgr_add_entry(struct log *log, void *arg, void *dptr, uint16_t len) +log_nmgr_encode_entry(struct log *log, void *arg, void *dptr, uint16_t len) { + struct encode_off *encode_off = (struct encode_off *)arg; struct log_entry_hdr ueh; char data[128]; int dlen; - struct json_encoder *encoder; struct json_value jv; int rc; @@ -63,6 +86,13 @@ log_nmgr_add_entry(struct log *log, void *arg, void *dptr, uint16_t len) goto err; } + /* Matching timestamps and indices for sending a log entry */ + if (ueh.ue_ts < encode_off->eo_ts || + (ueh.ue_ts == encode_off->eo_ts && + ueh.ue_index <= encode_off->eo_index)) { + goto err; + } + dlen = min(len-sizeof(ueh), 128); rc = log_read(log, dptr, data, sizeof(ueh), dlen); @@ -71,41 +101,99 @@ log_nmgr_add_entry(struct log *log, void *arg, void *dptr, uint16_t len) } data[rc] = 0; - encoder = (struct json_encoder *) arg; - - json_encode_object_start(encoder); + json_encode_object_start(encode_off->eo_encoder); JSON_VALUE_STRINGN(&jv, data, rc); - rc = json_encode_object_entry(encoder, "msg", &jv); - if (rc != 0) { + rc = json_encode_object_entry(encode_off->eo_encoder, "msg", &jv); + if (rc) { goto err; } JSON_VALUE_INT(&jv, ueh.ue_ts); - rc = json_encode_object_entry(encoder, "ts", &jv); - if (rc != 0) { + rc = json_encode_object_entry(encode_off->eo_encoder, "ts", &jv); + if (rc) { goto err; } JSON_VALUE_UINT(&jv, ueh.ue_level); - rc = json_encode_object_entry(encoder, "level", &jv); - if (rc != 0) { + rc = json_encode_object_entry(encode_off->eo_encoder, "level", &jv); + if (rc) { goto err; } JSON_VALUE_UINT(&jv, ueh.ue_index); - rc = json_encode_object_entry(encoder, "index", &jv); - if (rc != 0) { + rc = json_encode_object_entry(encode_off->eo_encoder, "index", &jv); + if (rc) { goto err; } - json_encode_object_finish(encoder); + JSON_VALUE_UINT(&jv, ueh.ue_module); + rc = json_encode_object_entry(encode_off->eo_encoder, "module", &jv); + if (rc) { + goto err; + } + json_encode_object_finish(encode_off->eo_encoder); return (0); err: return (rc); } +/** + * Log encode entries + * @param log structure, the encoder, timestamp, index + * @return 0 on success; non-zero on failure + */ +static int +log_encode_entries(struct log *log, struct json_encoder *encoder, + int64_t ts, uint32_t index) +{ + int rc; + struct encode_off encode_off; + + json_encode_array_name(encoder, "entries"); + json_encode_array_start(encoder); + + encode_off.eo_encoder = encoder; + encode_off.eo_index = index; + encode_off.eo_ts = ts; + + rc = log_walk(log, log_nmgr_encode_entry, &encode_off); + + return rc; +} + +/** + * Log encode function + * @param log structure, the encoder, json_value, + * timestamp, index + * @return 0 on success; non-zero on failure + */ +static int +log_encode(struct log *log, struct json_encoder *encoder, + struct json_value *jv, int64_t ts, uint32_t index) +{ + int rc; + + json_encode_object_start(encoder); + JSON_VALUE_STRING(jv, log->l_name); + json_encode_object_entry(encoder, "name", jv); + + JSON_VALUE_UINT(jv, log->l_log->log_type); + json_encode_object_entry(encoder, "type", jv); + + rc = log_encode_entries(log, encoder, ts, index); + json_encode_array_finish(encoder); + json_encode_object_finish(encoder); + + return rc; +} + +/** + * Newtmgr Log read handler + * @param nmgr json buffer + * @return 0 on success; non-zero on failure + */ static int log_nmgr_read(struct nmgr_jbuf *njb) { @@ -113,19 +201,49 @@ log_nmgr_read(struct nmgr_jbuf *njb) int rc; struct json_value jv; struct json_encoder *encoder; + char name[LOG_NAME_MAX_LEN] = {0}; + int name_len; + int64_t ts; + uint64_t index; + + const struct json_attr_t attr[4] = { + [0] = { + .attribute = "log_name", + .type = t_string, + .addr.string = name, + .len = sizeof(name) + }, + [1] = { + .attribute = "ts", + .type = t_integer, + .addr.integer = &ts + }, + [2] = { + .attribute = "index", + .type = t_uinteger, + .addr.uinteger = &index + }, + [3] = { + .attribute = NULL + } + }; + + rc = json_read_object(&njb->njb_buf, attr); + if (rc) { + return rc; + } encoder = (struct json_encoder *) &nmgr_task_jbuf.njb_enc; json_encode_object_start(encoder); - JSON_VALUE_INT(&jv, NMGR_ERR_EOK); - json_encode_object_entry(encoder, "rc", &jv); json_encode_array_name(encoder, "logs"); json_encode_array_start(encoder); + name_len = strlen(name); log = NULL; while (1) { log = log_list_get_next(log); - if (log == NULL) { + if (!log) { break; } @@ -133,34 +251,167 @@ log_nmgr_read(struct nmgr_jbuf *njb) continue; } - json_encode_object_start(encoder); - JSON_VALUE_STRING(&jv, log->l_name); - json_encode_object_entry(encoder, "name", &jv); + /* Conditions for returning specific logs */ + if ((name_len > 0) && strcmp(name, log->l_name)) { + continue; + } - JSON_VALUE_INT(&jv, log->l_log->log_type); - json_encode_object_entry(encoder, "type", &jv); + rc = log_encode(log, encoder, &jv, ts, index); + if (rc) { + goto err; + } - json_encode_array_name(encoder, "entries"); - json_encode_array_start(encoder); + /* If a log was found, encode and break */ + if (name_len > 0) { + break; + } + } - rc = log_walk(log, log_nmgr_add_entry, encoder); - if (rc != 0) { - goto err; + + /* Running out of logs list and we have a specific log to look for */ + if (!log && name_len > 0) { + rc = OS_EINVAL; + } + + json_encode_array_finish(encoder); + +err: + JSON_VALUE_INT(&jv, rc); + json_encode_object_entry(encoder, "rc", &jv); + json_encode_object_finish(encoder); + rc = 0; + return (rc); +} + +/** + * Newtmgr Module list handler + * @param nmgr json buffer + * @return 0 on success; non-zero on failure + */ +static int +log_nmgr_module_list(struct nmgr_jbuf *njb) +{ + struct json_value jv; + struct json_encoder *encoder; + int module; + char *str; + + encoder = (struct json_encoder *) &nmgr_task_jbuf.njb_enc; + + json_encode_object_start(encoder); + JSON_VALUE_INT(&jv, NMGR_ERR_EOK); + json_encode_object_entry(encoder, "rc", &jv); + json_encode_object_key(encoder, "module_map"); + json_encode_object_start(encoder); + + module = LOG_MODULE_DEFAULT; + while (module < LOG_MODULE_MAX) { + str = LOG_MODULE_STR(module); + if (!strcmp(str, "UNKNOWN")) { + module++; + continue; + } + + JSON_VALUE_UINT(&jv, module); + json_encode_object_entry(encoder, str, &jv); + + module++; + } + + + json_encode_object_finish(encoder); + json_encode_object_finish(encoder); + + return (0); +} + +/** + * Newtmgr Log list handler + * @param nmgr json buffer + * @return 0 on success; non-zero on failure + */ +static int +log_nmgr_logs_list(struct nmgr_jbuf *njb) +{ + struct json_value jv; + struct json_encoder *encoder; + struct log *log; + + encoder = (struct json_encoder *) &nmgr_task_jbuf.njb_enc; + + json_encode_object_start(encoder); + JSON_VALUE_INT(&jv, NMGR_ERR_EOK); + json_encode_object_entry(encoder, "rc", &jv); + json_encode_array_name(encoder, "log_list"); + json_encode_array_start(encoder); + + log = NULL; + while (1) { + log = log_list_get_next(log); + if (!log) { + break; + } + + if (log->l_log->log_type == LOG_TYPE_STREAM) { + continue; } - json_encode_array_finish(encoder); - json_encode_object_finish(encoder); + JSON_VALUE_STRING(&jv, log->l_name); + json_encode_array_value(encoder, &jv); } json_encode_array_finish(encoder); json_encode_object_finish(encoder); return (0); -err: - nmgr_jbuf_setoerr(njb, rc); +} + +/** + * Newtmgr Log Level list handler + * @param nmgr json buffer + * @return 0 on success; non-zero on failure + */ +static int +log_nmgr_level_list(struct nmgr_jbuf *njb) +{ + struct json_value jv; + struct json_encoder *encoder; + int level; + char *str; + + encoder = (struct json_encoder *) &nmgr_task_jbuf.njb_enc; + + json_encode_object_start(encoder); + JSON_VALUE_INT(&jv, NMGR_ERR_EOK); + json_encode_object_entry(encoder, "rc", &jv); + json_encode_object_key(encoder, "level_map"); + json_encode_object_start(encoder); + + level = LOG_LEVEL_DEBUG; + while (level < LOG_LEVEL_MAX) { + str = LOG_LEVEL_STR(level); + if (!strcmp(str, "UNKNOWN")) { + level++; + continue; + } + + JSON_VALUE_UINT(&jv, level); + json_encode_object_entry(encoder, str, &jv); + + level++; + } + + json_encode_object_finish(encoder); + json_encode_object_finish(encoder); + return (0); } +/** + * Newtmgr log clear handler + * @param nmgr json buffer + * @return 0 on success; non-zero on failure + */ static int log_nmgr_clear(struct nmgr_jbuf *njb) { @@ -180,7 +431,7 @@ log_nmgr_clear(struct nmgr_jbuf *njb) } rc = log_flush(log); - if (rc != 0) { + if (rc) { goto err; } } @@ -198,6 +449,7 @@ err: /** * Register nmgr group handlers. + * @return 0 on success; non-zero on failure */ int log_nmgr_register_group(void) @@ -208,7 +460,7 @@ log_nmgr_register_group(void) log_nmgr_group.ng_group_id = NMGR_GROUP_ID_LOGS; rc = nmgr_group_register(&log_nmgr_group); - if (rc != 0) { + if (rc) { goto err; } @@ -217,5 +469,4 @@ err: return (rc); } - #endif /* NEWTMGR_PRESENT */ diff --git a/sys/stats/src/stats_nmgr.c b/sys/stats/src/stats_nmgr.c index 300b872f..c7b8dff7 100644 --- a/sys/stats/src/stats_nmgr.c +++ b/sys/stats/src/stats_nmgr.c @@ -6,7 +6,7 @@ * 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, @@ -23,30 +23,33 @@ #include <stdio.h> -#ifdef NEWTMGR_PRESENT +#ifdef NEWTMGR_PRESENT -#include "newtmgr/newtmgr.h" -#include "json/json.h" +#include "newtmgr/newtmgr.h" +#include "json/json.h" #include "stats/stats.h" /* Source code is only included if the newtmgr library is enabled. Otherwise * this file is compiled out for code size. */ static int stats_nmgr_read(struct nmgr_jbuf *njb); +static int stats_nmgr_list(struct nmgr_jbuf *njb); static struct nmgr_group shell_nmgr_group; -#define STATS_NMGR_ID_READ (0) +#define STATS_NMGR_ID_READ (0) +#define STATS_NMGR_ID_LIST (1) /* ORDER MATTERS HERE. * Each element represents the command ID, referenced from newtmgr. */ static struct nmgr_handler shell_nmgr_group_handlers[] = { [STATS_NMGR_ID_READ] = {stats_nmgr_read, stats_nmgr_read}, + [STATS_NMGR_ID_LIST] = {stats_nmgr_list, stats_nmgr_list} }; -static int -stats_nmgr_walk_func(struct stats_hdr *hdr, void *arg, char *sname, +static int +stats_nmgr_walk_func(struct stats_hdr *hdr, void *arg, char *sname, uint16_t stat_off) { struct json_encoder *encoder; @@ -62,7 +65,7 @@ stats_nmgr_walk_func(struct stats_hdr *hdr, void *arg, char *sname, case sizeof(uint16_t): JSON_VALUE_UINT(&jv, *(uint16_t *) stat_val); break; - case sizeof(uint32_t): + case sizeof(uint32_t): JSON_VALUE_UINT(&jv, *(uint32_t *) stat_val); break; case sizeof(uint64_t): @@ -74,20 +77,33 @@ stats_nmgr_walk_func(struct stats_hdr *hdr, void *arg, char *sname, if (rc != 0) { goto err; } - + return (0); err: return (rc); } -static int +static int +stats_nmgr_encode_name(struct stats_hdr *hdr, void *arg) +{ + struct json_encoder *encoder; + struct json_value jv; + + encoder = (struct json_encoder *)arg; + JSON_VALUE_STRING(&jv, hdr->s_name); + json_encode_array_value(encoder, &jv); + + return (0); +} + +static int stats_nmgr_read(struct nmgr_jbuf *njb) { struct stats_hdr *hdr; #define STATS_NMGR_NAME_LEN (32) char stats_name[STATS_NMGR_NAME_LEN]; struct json_attr_t attrs[] = { - { "name", t_string, .addr.string = &stats_name[0], + { "name", t_string, .addr.string = &stats_name[0], .len = sizeof(stats_name) }, { NULL }, }; @@ -126,11 +142,27 @@ err: return (0); } +static int +stats_nmgr_list(struct nmgr_jbuf *njb) +{ + struct json_value jv; + + json_encode_object_start(&njb->njb_enc); + JSON_VALUE_INT(&jv, NMGR_ERR_EOK); + json_encode_object_entry(&nmgr_task_jbuf.njb_enc, "rc", &jv); + json_encode_array_name(&nmgr_task_jbuf.njb_enc, "stat_list"); + json_encode_array_start(&nmgr_task_jbuf.njb_enc); + stats_group_walk(stats_nmgr_encode_name, &nmgr_task_jbuf.njb_enc); + json_encode_array_finish(&njb->njb_enc); + json_encode_object_finish(&njb->njb_enc); + + return (0); +} /** - * Register nmgr group handlers. + * Register nmgr group handlers */ -int +int stats_nmgr_register_group(void) { int rc; @@ -148,5 +180,4 @@ err: return (rc); } - #endif /* NEWTMGR_PRESENT */ |