andrzej-kaczmarek closed pull request #1149: sys/log: Add log storage usage
tracking and watermarking
URL: https://github.com/apache/mynewt-core/pull/1149
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/fs/fcb/include/fcb/fcb.h b/fs/fcb/include/fcb/fcb.h
index ebafc6a899..d6677b23a0 100644
--- a/fs/fcb/include/fcb/fcb.h
+++ b/fs/fcb/include/fcb/fcb.h
@@ -84,6 +84,11 @@ int fcb_init(struct fcb *fcb);
struct fcb_log {
struct fcb fl_fcb;
uint8_t fl_entries;
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ /* Internal - tracking storage use */
+ uint32_t fl_watermark_off;
+#endif
};
/**
diff --git a/sys/log/common/include/log_common/log_common.h
b/sys/log/common/include/log_common/log_common.h
index fc3d214f23..16010af6db 100644
--- a/sys/log/common/include/log_common/log_common.h
+++ b/sys/log/common/include/log_common/log_common.h
@@ -87,12 +87,13 @@ extern "C" {
#endif
/* 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)
+#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)
+#define LOGS_NMGR_OP_SET_WATERMARK (6)
#define LOG_PRINTF_MAX_ENTRY_LEN (128)
diff --git a/sys/log/full/include/log/log.h b/sys/log/full/include/log/log.h
index 778eb25180..2d7657dfca 100644
--- a/sys/log/full/include/log/log.h
+++ b/sys/log/full/include/log/log.h
@@ -50,6 +50,19 @@ struct log_offset {
void *lo_arg;
};
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+/**
+ * Log storage information
+ */
+struct log_storage_info {
+ uint32_t size;
+ uint32_t used;
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ uint32_t used_unread;
+#endif
+};
+#endif
+
typedef int (*log_walk_func_t)(struct log *, struct log_offset *log_offset,
void *dptr, uint16_t len);
@@ -72,6 +85,12 @@ typedef int (*lh_append_mbuf_body_func_t)(struct log *log,
typedef int (*lh_walk_func_t)(struct log *,
log_walk_func_t walk_func, struct log_offset *log_offset);
typedef int (*lh_flush_func_t)(struct log *);
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+typedef int (*lh_storage_info_func_t)(struct log *, struct log_storage_info *);
+#endif
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+typedef int (*lh_set_watermark_func_t)(struct log *, uint32_t);
+#endif
typedef int (*lh_registered_func_t)(struct log *);
struct log_handler {
@@ -84,6 +103,12 @@ struct log_handler {
lh_append_mbuf_body_func_t log_append_mbuf_body;
lh_walk_func_t log_walk;
lh_flush_func_t log_flush;
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+ lh_storage_info_func_t log_storage_info;
+#endif
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ lh_set_watermark_func_t log_set_watermark;
+#endif
/* Functions called only internally (no API for apps) */
lh_registered_func_t log_registered;
};
@@ -542,6 +567,36 @@ log_level_set(uint8_t module, uint8_t level)
}
#endif
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+/**
+ * Return information about log storage
+ *
+ * This return information about size and usage of storage on top of which log
+ * instance is created.
+ *
+ * @param log The log to query.
+ * @param info The destination to write information to.
+ *
+ * @return 0 on success, error code otherwise
+ *
+ */
+int log_storage_info(struct log *log, struct log_storage_info *info);
+#endif
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+/**
+ * Set watermark on log
+ *
+ * This sets watermark on log item with given index. This information is used
+ * to calculate size of entries which were logged after watermark item, i.e.
+ * unread items. The watermark is stored persistently for each log.
+ *
+ * @param log The log to set watermark on.
+ * @param index The index of a watermarked item.
+ *
+ * @return 0 on success, error code otherwise.
+ */
+int log_set_watermark(struct log *log, uint32_t index);
+#endif
/* Handler exports */
#if MYNEWT_VAL(LOG_CONSOLE)
diff --git a/sys/log/full/pkg.yml b/sys/log/full/pkg.yml
index 4c82518e35..15c9756997 100644
--- a/sys/log/full/pkg.yml
+++ b/sys/log/full/pkg.yml
@@ -40,6 +40,9 @@ pkg.deps.LOG_NEWTMGR:
- "@apache-mynewt-core/encoding/cborattr"
- "@apache-mynewt-core/encoding/tinycbor"
+pkg.deps.LOG_STORAGE_WATERMARK:
+ - sys/config
+
pkg.apis:
- log
diff --git a/sys/log/full/src/log.c b/sys/log/full/src/log.c
index f7f7c0b5ce..99f0b99d71 100644
--- a/sys/log/full/src/log.c
+++ b/sys/log/full/src/log.c
@@ -25,6 +25,9 @@
#include "os/mynewt.h"
#include "cbmem/cbmem.h"
#include "log/log.h"
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+#include "config/config.h"
+#endif
#if MYNEWT_VAL(LOG_CLI)
#include "shell/shell.h"
@@ -50,6 +53,59 @@ struct shell_cmd g_shell_slot1_cmd = {
.sc_cmd_func = shell_log_slot1_cmd,
};
#endif
+
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+int shell_log_storage_cmd(int, char **);
+struct shell_cmd g_shell_storage_cmd = {
+ .sc_cmd = "log-storage",
+ .sc_cmd_func = shell_log_storage_cmd,
+};
+#endif
+#endif
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+static int log_conf_set(int argc, char **argv, char *val);
+
+static struct conf_handler log_conf = {
+ .ch_name = "log",
+ .ch_get = NULL,
+ .ch_set = log_conf_set,
+ .ch_commit = NULL,
+ .ch_export = NULL,
+};
+
+static int
+log_conf_set(int argc, char **argv, char *val)
+{
+ struct log *cur;
+
+ if (argc < 2) {
+ return -1;
+ }
+
+ /* Only support log/<name>/mark entries for now */
+ if (strcmp("mark", argv[1])) {
+ return -1;
+ }
+
+ /* Find proper log */
+ STAILQ_FOREACH(cur, &g_log_list, l_next) {
+ if (!strcmp(argv[0], cur->l_name)) {
+ break;
+ }
+ }
+
+ if (!cur) {
+ return -1;
+ }
+
+ /* Set watermark if supported */
+ if (cur->l_log->log_set_watermark) {
+ cur->l_log->log_set_watermark(cur, atoi(val));
+ }
+
+ return 0;
+}
#endif
void
@@ -73,6 +129,9 @@ log_init(void)
#if MYNEWT_VAL(LOG_FCB_SLOT1)
shell_cmd_register(&g_shell_slot1_cmd);
#endif
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+ shell_cmd_register(&g_shell_storage_cmd);
+#endif
#endif
#if MYNEWT_VAL(LOG_NEWTMGR)
@@ -83,6 +142,11 @@ log_init(void)
#if MYNEWT_VAL(LOG_CONSOLE)
log_console_init();
#endif
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ rc = conf_register(&log_conf);
+ SYSINIT_PANIC_ASSERT(rc == 0);
+#endif
}
struct log *
@@ -654,3 +718,56 @@ log_flush(struct log *log)
err:
return (rc);
}
+
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+int
+log_storage_info(struct log *log, struct log_storage_info *info)
+{
+ int rc;
+
+ if (!log->l_log->log_storage_info) {
+ rc = OS_ENOENT;
+ goto err;
+ }
+
+ rc = log->l_log->log_storage_info(log, info);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+#endif
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+int
+log_set_watermark(struct log *log, uint32_t index)
+{
+ char log_path[CONF_MAX_NAME_LEN];
+ char mark_val[10]; /* fits uint32_t + \0 */
+ int rc;
+
+ if (!log->l_log->log_set_watermark) {
+ rc = OS_ENOENT;
+ goto err;
+ }
+
+ rc = log->l_log->log_set_watermark(log, index);
+ if (rc != 0) {
+ goto err;
+ }
+
+ snprintf(log_path, CONF_MAX_NAME_LEN, "log/%s/mark", log->l_name);
+ log_path[CONF_MAX_NAME_LEN - 1] = '\0';
+
+ sprintf(mark_val, "%u", (unsigned)index);
+
+ conf_save_one(log_path, mark_val);
+
+ return (0);
+err:
+ return (rc);
+}
+#endif
diff --git a/sys/log/full/src/log_cbmem.c b/sys/log/full/src/log_cbmem.c
index 3c9c7a40c8..bf4e948412 100644
--- a/sys/log/full/src/log_cbmem.c
+++ b/sys/log/full/src/log_cbmem.c
@@ -206,6 +206,31 @@ log_cbmem_flush(struct log *log)
return (rc);
}
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+static int
+log_cbmem_storage_info(struct log *log, struct log_storage_info *info)
+{
+ struct cbmem *cbmem;
+ uint32_t size;
+ uint32_t used;
+
+ cbmem = (struct cbmem *)log->l_arg;
+
+ size = cbmem->c_buf_end - cbmem->c_buf;
+
+ used = (uint32_t)cbmem->c_entry_end + cbmem->c_entry_end->ceh_len -
+ (uint32_t)cbmem->c_entry_start;
+ if ((int32_t)used < 0) {
+ used += size;
+ }
+
+ info->size = size;
+ info->used = used;
+
+ return 0;
+}
+#endif
+
const struct log_handler log_cbmem_handler = {
.log_type = LOG_TYPE_MEMORY,
.log_read = log_cbmem_read,
@@ -216,4 +241,7 @@ const struct log_handler log_cbmem_handler = {
.log_append_mbuf_body = log_cbmem_append_mbuf_body,
.log_walk = log_cbmem_walk,
.log_flush = log_cbmem_flush,
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+ .log_storage_info = log_cbmem_storage_info,
+#endif
};
diff --git a/sys/log/full/src/log_fcb.c b/sys/log/full/src/log_fcb.c
index 42d41daa46..7a7184e863 100644
--- a/sys/log/full/src/log_fcb.c
+++ b/sys/log/full/src/log_fcb.c
@@ -39,6 +39,7 @@ log_fcb_start_append(struct log *log, int len, struct
fcb_entry *loc)
{
struct fcb *fcb;
struct fcb_log *fcb_log;
+ struct flash_area *old_fa;
int rc = 0;
fcb_log = (struct fcb_log *)log->l_arg;
@@ -62,10 +63,27 @@ log_fcb_start_append(struct log *log, int len, struct
fcb_entry *loc)
continue;
}
+ old_fa = fcb->f_oldest;
+ (void)old_fa; /* to avoid #ifdefs everywhere... */
+
rc = fcb_rotate(fcb);
if (rc) {
goto err;
}
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ /*
+ * FCB was rotated successfully so let's check if watermark was within
+ * oldest flash area which was erased. If yes, then move watermark to
+ * beginning of current oldest area.
+ */
+ if ((fcb_log->fl_watermark_off >= old_fa->fa_off) &&
+ (fcb_log->fl_watermark_off < old_fa->fa_off + old_fa->fa_size)) {
+ fcb_log->fl_watermark_off = fcb->f_oldest->fa_off;
+ }
+#endif
+
+
}
err:
@@ -386,6 +404,134 @@ log_fcb_flush(struct log *log)
return fcb_clear(&((struct fcb_log *)log->l_arg)->fl_fcb);
}
+static int
+log_fcb_registered(struct log *log)
+{
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ struct fcb_log *fl;
+ struct fcb *fcb;
+ struct fcb_entry loc;
+
+ fl = (struct fcb_log *)log->l_arg;
+ fcb = &fl->fl_fcb;
+
+ /* Set watermark to first element */
+ memset(&loc, 0, sizeof(loc));
+ if (fcb_getnext(fcb, &loc)) {
+ fl->fl_watermark_off = loc.fe_area->fa_off + loc.fe_elem_off;
+ } else {
+ fl->fl_watermark_off = fcb->f_oldest->fa_off;
+ }
+#endif
+ return 0;
+}
+
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+static int
+log_fcb_storage_info(struct log *log, struct log_storage_info *info)
+{
+ struct fcb_log *fl;
+ struct fcb *fcb;
+ struct flash_area *fa;
+ uint32_t el_min;
+ uint32_t el_max;
+ uint32_t fa_min;
+ uint32_t fa_max;
+ uint32_t fa_size;
+ uint32_t fa_used;
+ int rc;
+
+ fl = (struct fcb_log *)log->l_arg;
+ fcb = &fl->fl_fcb;
+
+ rc = os_mutex_pend(&fcb->f_mtx, OS_WAIT_FOREVER);
+ if (rc && rc != OS_NOT_STARTED) {
+ return FCB_ERR_ARGS;
+ }
+
+ /*
+ * Calculate location of 1st entry.
+ * We assume 1st log entry starts at beginning of oldest sector in FCB.
+ * This is because even if 1st entry is in the middle of sector (is this
+ * even possible?) we will never use free space before it thus that space
+ * can be also considered used.
+ */
+ el_min = fcb->f_oldest->fa_off;
+
+ /* Calculate end location of last entry */
+ el_max = fcb->f_active.fe_area->fa_off + fcb->f_active.fe_elem_off;
+
+ /* Sectors assigned to FCB are guaranteed to be contiguous */
+ fa = &fcb->f_sectors[0];
+ fa_min = fa->fa_off;
+ fa = &fcb->f_sectors[fcb->f_sector_cnt - 1];
+ fa_max = fa->fa_off + fa->fa_size;
+ fa_size = fa_max - fa_min;
+
+ /* Calculate used size */
+ fa_used = el_max - el_min;
+ if ((int32_t)fa_used < 0) {
+ fa_used += fa_size;
+ }
+
+ info->size = fa_size;
+ info->used = fa_used;
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ /* Calculate used size */
+ fa_used = el_max - fl->fl_watermark_off;
+ if ((int32_t)fa_used < 0) {
+ fa_used += fa_size;
+ }
+ info->used_unread = fa_used;
+#endif
+
+ os_mutex_release(&fcb->f_mtx);
+
+ return 0;
+}
+#endif
+
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+static int
+log_fcb_set_watermark(struct log *log, uint32_t index)
+{
+ struct fcb_log *fl;
+ struct fcb *fcb;
+ struct log_entry_hdr ueh;
+ struct fcb_entry loc;
+ uint32_t end_off;
+ int rc;
+
+ fl = (struct fcb_log *)log->l_arg;
+ fcb = &fl->fl_fcb;
+
+ memset(&loc, 0, sizeof(loc));
+ end_off = fcb->f_oldest->fa_off;
+ rc = 0;
+
+ while (fcb_getnext(fcb, &loc) == 0) {
+ rc = log_fcb_read(log, &loc, &ueh, 0, sizeof(ueh));
+
+ if (rc != sizeof(ueh)) {
+ break;
+ }
+
+ if (ueh.ue_index > index) {
+ break;
+ }
+
+ /* Move end offset max pointer to end of this element */
+ end_off = loc.fe_area->fa_off + loc.fe_data_off + loc.fe_data_len;
+ }
+
+ /* End of last element found is now our watermark */
+ fl->fl_watermark_off = end_off;
+
+ return rc;
+}
+#endif
+
/**
* Copies one log entry from source fcb to destination fcb
* @param src_fcb, dst_fcb
@@ -533,6 +679,13 @@ const struct log_handler log_fcb_handler = {
.log_append_mbuf_body = log_fcb_append_mbuf_body,
.log_walk = log_fcb_walk,
.log_flush = log_fcb_flush,
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+ .log_storage_info = log_fcb_storage_info,
+#endif
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ .log_set_watermark = log_fcb_set_watermark,
+#endif
+ .log_registered = log_fcb_registered,
};
#endif
diff --git a/sys/log/full/src/log_fcb_slot1.c b/sys/log/full/src/log_fcb_slot1.c
index d5265db713..a3ad43ac1f 100644
--- a/sys/log/full/src/log_fcb_slot1.c
+++ b/sys/log/full/src/log_fcb_slot1.c
@@ -102,6 +102,18 @@ log_fcb_slot1_flush(struct log *log)
return LOG_FCB_SLOT1_CALL(log, log_flush);
}
+static int
+log_fcb_slot1_storage_info(struct log *log, struct log_storage_info *info)
+{
+ return LOG_FCB_SLOT1_CALL(log, log_storage_info, info);
+}
+
+static int
+log_fcb_slot1_set_watermark(struct log *log, uint32_t index)
+{
+ return LOG_FCB_SLOT1_CALL(log, log_set_watermark, index);
+}
+
static int
log_fcb_slot1_registered(struct log *log)
{
@@ -126,6 +138,10 @@ log_fcb_slot1_registered(struct log *log)
s1->l_current = NULL;
}
+ if (s1->l_current && s1->l_current->l_log->log_registered) {
+ s1->l_current->l_log->log_registered(s1->l_current);
+ }
+
os_mutex_release(&g_log_slot1_mutex);
return 0;
@@ -141,6 +157,12 @@ const struct log_handler log_fcb_slot1_handler = {
.log_append_mbuf_body = log_fcb_slot1_append_mbuf_body,
.log_walk = log_fcb_slot1_walk,
.log_flush = log_fcb_slot1_flush,
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+ .log_storage_info = log_fcb_slot1_storage_info,
+#endif
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ .log_set_watermark = log_fcb_slot1_set_watermark,
+#endif
.log_registered = log_fcb_slot1_registered,
};
@@ -207,6 +229,10 @@ log_fcb_slot1_lock(void)
s1->l_current = NULL;
}
+ if (s1->l_current && s1->l_current->l_log->log_registered) {
+ s1->l_current->l_log->log_registered(s1->l_current);
+ }
+
os_mutex_release(&s1->mutex);
}
@@ -292,6 +318,9 @@ log_fcb_slot1_unlock(void)
}
s1->l_current = &s1->l_fcb;
+ if (s1->l_current->l_log->log_registered) {
+ s1->l_current->l_log->log_registered(s1->l_current);
+ }
os_mutex_release(&s1->mutex);
}
diff --git a/sys/log/full/src/log_nmgr.c b/sys/log/full/src/log_nmgr.c
index c8bb3eceda..53ba441be2 100644
--- a/sys/log/full/src/log_nmgr.c
+++ b/sys/log/full/src/log_nmgr.c
@@ -38,6 +38,7 @@ static int log_nmgr_clear(struct mgmt_cbuf *njb);
static int log_nmgr_module_list(struct mgmt_cbuf *njb);
static int log_nmgr_level_list(struct mgmt_cbuf *njb);
static int log_nmgr_logs_list(struct mgmt_cbuf *njb);
+static int log_nmgr_set_watermark(struct mgmt_cbuf *njb);
static struct mgmt_group log_nmgr_group;
@@ -49,7 +50,8 @@ static struct mgmt_handler log_nmgr_group_handlers[] = {
[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}
+ [LOGS_NMGR_OP_LOGS_LIST] = {log_nmgr_logs_list, NULL},
+ [LOGS_NMGR_OP_SET_WATERMARK] = {log_nmgr_set_watermark, NULL},
};
struct log_encode_data {
@@ -581,6 +583,79 @@ log_nmgr_clear(struct mgmt_cbuf *cb)
return 0;
}
+static int
+log_nmgr_set_watermark(struct mgmt_cbuf *cb)
+{
+ struct log *log;
+ int rc;
+ char name[LOG_NAME_MAX_LEN] = {0};
+ int name_len;
+ uint64_t index;
+
+ const struct cbor_attr_t attr[4] = {
+ [0] = {
+ .attribute = "log_name",
+ .type = CborAttrTextStringType,
+ .addr.string = name,
+ .len = sizeof(name)
+ },
+ [1] = {
+ .attribute = "index",
+ .type = CborAttrUnsignedIntegerType,
+ .addr.uinteger = &index
+ },
+ [2] = {
+ .attribute = NULL
+ }
+ };
+
+ rc = cbor_read_object(&cb->it, attr);
+ if (rc) {
+ return rc;
+ }
+
+ name_len = strlen(name);
+ log = NULL;
+ while (1) {
+ log = log_list_get_next(log);
+ if (!log) {
+ break;
+ }
+
+ if (log->l_log->log_type == LOG_TYPE_STREAM) {
+ continue;
+ }
+
+ /* Conditions for returning specific logs */
+ if ((name_len > 0) && strcmp(name, log->l_name)) {
+ continue;
+ }
+
+ rc = log_set_watermark(log, index);
+ if (rc) {
+ goto err;
+ }
+
+ /* If a log was found, encode and break */
+ if (name_len > 0) {
+ break;
+ }
+ }
+
+ /* Running out of logs list and we have a specific log to look for */
+ if (!log && name_len > 0) {
+ rc = OS_EINVAL;
+ }
+
+err:
+ rc = mgmt_cbuf_setoerr(cb, 0);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return (rc);
+}
+
/**
* Register nmgr group handlers.
* @return 0 on success; non-zero on failure
diff --git a/sys/log/full/src/log_shell.c b/sys/log/full/src/log_shell.c
index 1605acad7c..6d482f9e19 100644
--- a/sys/log/full/src/log_shell.c
+++ b/sys/log/full/src/log_shell.c
@@ -128,6 +128,40 @@ shell_log_slot1_cmd(int argc, char **argv)
}
#endif
+#if MYNEWT_VAL(LOG_STORAGE_INFO)
+int
+shell_log_storage_cmd(int argc, char **argv)
+{
+ struct log *log;
+ struct log_storage_info info;
+
+ log = NULL;
+ while (1) {
+ log = log_list_get_next(log);
+ if (log == NULL) {
+ break;
+ }
+
+ if (log->l_log->log_type == LOG_TYPE_STREAM) {
+ continue;
+ }
+
+ if (log_storage_info(log, &info)) {
+ console_printf("Storage info not supported for %s\n", log->l_name);
+ } else {
+ console_printf("%s: %d of %d used\n", log->l_name,
+ (unsigned)info.used, (unsigned)info.size);
+#if MYNEWT_VAL(LOG_STORAGE_WATERMARK)
+ console_printf("%s: %d of %d used by unread entries\n",
log->l_name,
+ (unsigned)info.used_unread, (unsigned)info.size);
+#endif
+ }
+ }
+
+ return (0);
+}
+#endif
+
#endif
diff --git a/sys/log/full/syscfg.yml b/sys/log/full/syscfg.yml
index 04a0065e5e..66e861dcd6 100644
--- a/sys/log/full/syscfg.yml
+++ b/sys/log/full/syscfg.yml
@@ -71,3 +71,19 @@ syscfg.defs:
Writes with a level less than the module's minimum level are
discarded. Enabling this setting requires 128 bytes of bss.
value: 1
+
+ LOG_STORAGE_INFO:
+ description: >
+ Enable "storage_info" API which keeps track of log storage usage
and
+ can return total number of bytes available for log and number of
+ bytes used by entries in log.
+ value: 0
+
+ LOG_STORAGE_WATERMARK:
+ description: >
+ Enable "set_watermark" API which can watermark log by entry index
and
+ thus allow to e.g. keep track of read items in log e.g. (via
newtmgr).
+ This also extends information returned by "storage_info" to number
of
+ bytes used by entries above watermark.
+ value: 0
+ restrictions: LOG_STORAGE_INFO
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services