summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarko Kiiskila <marko@runtime.io>2016-05-19 14:56:52 -0700
committerMarko Kiiskila <marko@runtime.io>2016-05-19 14:56:52 -0700
commitf54eda03b7881b9168bb027c9a352bacf73199b0 (patch)
tree08698545e6ef8b82b799f8041459f8175c812e88 /sys
parentffd7dd376df7393d516b62853eb8dee302e0931b (diff)
parentc75f8e493628d9ea3796d3019a0f753e0346ab96 (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.h40
-rw-r--r--sys/log/src/log.c15
-rw-r--r--sys/log/src/log_nmgr.c327
-rw-r--r--sys/stats/src/stats_nmgr.c59
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 */