Skip to content

Commit d044e7d

Browse files
kderdarlubos
authored andcommitted
logging: rpc: add history usage threshold signaling
This commit introduces log history usage threshold value indicating that the server shall send an RPC event when the log history ring buffer usage exceeds the threshold. Signed-off-by: Konrad Derda <[email protected]> Signed-off-by: Damian Krolik <[email protected]>
1 parent f2f212f commit d044e7d

File tree

9 files changed

+213
-17
lines changed

9 files changed

+213
-17
lines changed

include/logging/log_rpc.h

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define LOG_RPC_H_
99

1010
#include <stddef.h>
11+
#include <stdint.h>
1112

1213
/**
1314
* @file
@@ -21,7 +22,7 @@ extern "C" {
2122
#endif
2223

2324
/**
24-
* nRF RPC logging level.
25+
* @brief nRF RPC logging level.
2526
*/
2627
enum log_rpc_level {
2728
LOG_RPC_LEVEL_NONE = 0,
@@ -32,55 +33,93 @@ enum log_rpc_level {
3233
};
3334

3435
/**
35-
* Log history handler.
36+
* @brief Log history handler.
3637
*
3738
* The type of a callback function that is invoked for each received log message
3839
* while fetching the log history from the remote device.
3940
*
40-
* @param level The message level, see @c log_rpc_level.
41+
* @param level The message level, see @ref log_rpc_level.
4142
* @param msg A pointer to the message payload.
4243
* @param msg_len The message payload length.
4344
*/
4445
typedef void (*log_rpc_history_handler_t)(enum log_rpc_level level, const char *msg,
4546
size_t msg_len);
4647

48+
/** @brief Log history threshold reached handler.
49+
*
50+
* The type of a callback function that is invoked when the log history usage
51+
* threshold configured with @ref log_rpc_set_history_level has been reached for
52+
* the first time.
53+
*/
54+
typedef void (*log_rpc_history_threshold_reached_handler_t)(void);
55+
4756
/**
48-
* Sets the log streaming verbosity level.
57+
* @brief Sets the log streaming verbosity level.
4958
*
5059
* The log streaming is the feature of nRF RPC logging that allows receiving log
5160
* messages as they are generated by the application running on the remote device.
5261
*
5362
* This function issues an nRF RPC command that configures the remote device to
5463
* stream log messages whose level is less than or equal to the specified level.
5564
*
56-
* @param level Logging level, see @c log_rpc_level.
65+
* @param level Logging level, see @ref log_rpc_level.
5766
*
5867
* @retval 0 On success.
5968
* @retval -errno On failure.
6069
*/
6170
int log_rpc_set_stream_level(enum log_rpc_level level);
6271

6372
/**
64-
* Sets the log history verbosity level.
73+
* @brief Sets the log history verbosity level.
6574
*
6675
* The log history is the feature of nRF RPC logging that allows saving log
6776
* messages generated by the application running on the remote device into
6877
* a ring buffer, and then retrieving the log history when needed.
6978
*
70-
* The function issues an nRF RPC command that configures the remote device to
79+
* This function issues an nRF RPC command that configures the remote device to
7180
* save log messages whose level is less than or equal to the specified level.
7281
*
73-
* @param level Logging level, see @c log_rpc_level.
82+
* @param level Logging level, see @ref log_rpc_level.
7483
*
7584
* @retval 0 On success.
7685
* @retval -errno On failure.
7786
*/
7887
int log_rpc_set_history_level(enum log_rpc_level level);
7988

8089
/**
81-
* Fetches the log history.
90+
* @brief Gets the current history usage threshold.
91+
*
92+
* This function fetches the current history usage threshold.
93+
*
94+
* @returns The current history usage threshold in percentage.
95+
*/
96+
uint8_t log_rpc_get_history_usage_threshold(void);
97+
98+
/**
99+
* @brief Sets the current history usage threshold.
100+
*
101+
* The log history is the feature of nRF RPC logging that allows saving log
102+
* messages generated by the application running on the remote device into
103+
* a ring buffer, and then retrieving the log history when needed.
104+
*
105+
* This function issues an nRF RPC command that requests the remote device to
106+
* emit an nRF RPC event when the ring buffer occupancy exceeds the requested
107+
* threshold for the first time after the threshold is set or the log history
108+
* is flushed.
109+
*
110+
* @param handler The handler that is invoked when the configured log
111+
* history usage threshold has been reached, see
112+
* @ref log_rpc_history_threshold_reached_handler_t.
113+
* @param threshold The history usage threshold in percentage (0 - 100).
114+
* Passing 0 disables this feature.
115+
*/
116+
void log_rpc_set_history_usage_threshold(log_rpc_history_threshold_reached_handler_t handler,
117+
uint8_t threshold);
118+
119+
/**
120+
* @brief Fetches the log history.
82121
*
83-
* The function issues an nRF RPC command that starts the log history transfer
122+
* This function issues an nRF RPC command that starts the log history transfer
84123
* from the remote device. The @c handler callback function is invoked for each
85124
* received log message. Additionally, it is invoked with @c msg argument set to
86125
* NULL after all log messages have been received.
@@ -89,7 +128,7 @@ int log_rpc_set_history_level(enum log_rpc_level level);
89128
* still is in progress, the process is restarted from the current oldest
90129
* log message saved in the log history on the remote device.
91130
*
92-
* @param handler History handler, see @c log_rpc_history_handler_t.
131+
* @param handler History handler, see @ref log_rpc_history_handler_t.
93132
*
94133
* @retval 0 On success.
95134
* @retval -errno On failure.
@@ -99,7 +138,7 @@ int log_rpc_fetch_history(log_rpc_history_handler_t handler);
99138
/**
100139
* @brief Retrieves the crash log retained on the remote device.
101140
*
102-
* The function issues an nRF RPC command to obtain the last crash log retained
141+
* This function issues an nRF RPC command to obtain the last crash log retained
103142
* on the remote device, and then it copies the received log chunk into the
104143
* specified buffer.
105144
*
@@ -120,7 +159,7 @@ int log_rpc_get_crash_log(size_t offset, char *buffer, size_t buffer_length);
120159
/**
121160
* @brief Generates a log message on the remote device.
122161
*
123-
* The function issues an nRF RPC command that requests the remote device to
162+
* This function issues an nRF RPC command that requests the remote device to
124163
* generate a log message with the given level. This function can be used to
125164
* test other functions of Logging over nRF RPC library.
126165
*/

samples/nrf_rpc/protocols_serialization/client/src/log_rpc_shell.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,39 @@ static int cmd_log_rpc_history_fetch(const struct shell *sh, size_t argc, char *
9999
return 0;
100100
}
101101

102+
static void history_threshold_reached_handler(void)
103+
{
104+
shell_print(shell, "History usage threshold reached");
105+
}
106+
107+
static int cmd_log_rpc_history_threshold(const struct shell *sh, size_t argc, char *argv[])
108+
{
109+
uint32_t threshold;
110+
int rc = 0;
111+
112+
if (argc == 0) {
113+
shell_print(sh, "%u", log_rpc_get_history_usage_threshold());
114+
return 0;
115+
}
116+
117+
threshold = shell_strtoul(argv[1], 0, &rc);
118+
119+
if (rc) {
120+
shell_error(sh, "Invalid argument: %d", rc);
121+
return -EINVAL;
122+
}
123+
124+
if (threshold > 100) {
125+
shell_error(sh, "%u exceeds max value (100)", threshold);
126+
return -EINVAL;
127+
}
128+
129+
shell = sh;
130+
log_rpc_set_history_usage_threshold(history_threshold_reached_handler, (uint8_t)threshold);
131+
132+
return 0;
133+
}
134+
102135
static int cmd_log_rpc_crash(const struct shell *sh, size_t argc, char *argv[])
103136
{
104137
int rc;
@@ -149,6 +182,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
149182
SHELL_CMD_ARG(history_level, NULL, "Set log history level", cmd_log_rpc_history_level, 2,
150183
0),
151184
SHELL_CMD_ARG(history_fetch, NULL, "Fetch log history", cmd_log_rpc_history_fetch, 1, 0),
185+
SHELL_CMD_ARG(history_threshold, NULL, "Get or set history usage threshold",
186+
cmd_log_rpc_history_threshold, 1, 1),
152187
SHELL_CMD_ARG(crash, NULL, "Retrieve remote device crash log", cmd_log_rpc_crash, 1, 0),
153188
SHELL_CMD_ARG(echo, NULL, "Generate log message on remote", cmd_log_rpc_echo, 3, 0),
154189
SHELL_SUBCMD_SET_END);

subsys/logging/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ config LOG_BACKEND_RPC_HISTORY_STORAGE_RAM
5555

5656
config LOG_BACKEND_RPC_HISTORY_STORAGE_FCB
5757
bool "Flash Circular Buffer"
58+
depends on FCB
5859
help
5960
Stores the log history in Flash Circular Buffer located in the "log_history"
6061
flash partition. Note that enabling this option may significantly increase

subsys/logging/log_backend_rpc.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static enum log_rpc_level stream_level = LOG_RPC_LEVEL_NONE;
4949

5050
#ifdef CONFIG_LOG_BACKEND_RPC_HISTORY
5151
static enum log_rpc_level history_level = LOG_RPC_LEVEL_NONE;
52+
static uint8_t history_threshold;
53+
static bool history_threshold_active;
5254
static void history_transfer_task(struct k_work *work);
5355
static K_MUTEX_DEFINE(history_transfer_mtx);
5456
static uint32_t history_transfer_id;
@@ -361,6 +363,15 @@ static void process(const struct log_backend *const backend, union log_msg_gener
361363

362364
if (max_level != LOG_RPC_LEVEL_NONE && level <= max_level) {
363365
log_rpc_history_push(msg_generic);
366+
367+
if (history_threshold_active && log_rpc_history_get_usage() > history_threshold) {
368+
struct nrf_rpc_cbor_ctx ctx;
369+
370+
NRF_RPC_CBOR_ALLOC(&log_rpc_group, ctx, 0);
371+
nrf_rpc_cbor_evt_no_err(&log_rpc_group,
372+
LOG_RPC_EVT_HISTORY_THRESHOLD_REACHED, &ctx);
373+
history_threshold_active = false;
374+
}
364375
}
365376
#endif
366377
}
@@ -519,6 +530,7 @@ static void history_transfer_task(struct k_work *work)
519530
log_rpc_history_free(history_cur_msg);
520531
history_cur_msg = NULL;
521532
log_rpc_history_set_overwriting(true);
533+
history_threshold_active = history_threshold > 0;
522534
}
523535

524536
k_mutex_unlock(&history_transfer_mtx);
@@ -552,6 +564,40 @@ static void log_rpc_fetch_history_handler(const struct nrf_rpc_group *group,
552564
NRF_RPC_CBOR_CMD_DECODER(log_rpc_group, log_rpc_fetch_history_handler, LOG_RPC_CMD_FETCH_HISTORY,
553565
log_rpc_fetch_history_handler, NULL);
554566

567+
static void log_rpc_get_history_usage_threshold_handler(const struct nrf_rpc_group *group,
568+
struct nrf_rpc_cbor_ctx *ctx,
569+
void *handler_data)
570+
{
571+
nrf_rpc_cbor_decoding_done(group, ctx);
572+
nrf_rpc_rsp_send_uint(group, history_threshold);
573+
}
574+
575+
NRF_RPC_CBOR_CMD_DECODER(log_rpc_group, log_rpc_get_history_usage_threshold_handler,
576+
LOG_RPC_CMD_GET_HISTORY_USAGE_THRESHOLD,
577+
log_rpc_get_history_usage_threshold_handler, NULL);
578+
579+
static void log_rpc_set_history_usage_threshold_handler(const struct nrf_rpc_group *group,
580+
struct nrf_rpc_cbor_ctx *ctx,
581+
void *handler_data)
582+
{
583+
uint8_t threshold = nrf_rpc_decode_uint(ctx);
584+
585+
if (!nrf_rpc_decoding_done_and_check(group, ctx)) {
586+
nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, group,
587+
LOG_RPC_CMD_SET_HISTORY_USAGE_THRESHOLD, NRF_RPC_PACKET_TYPE_CMD);
588+
return;
589+
}
590+
591+
history_threshold = threshold;
592+
history_threshold_active = threshold > 0;
593+
594+
nrf_rpc_rsp_send_void(group);
595+
}
596+
597+
NRF_RPC_CBOR_CMD_DECODER(log_rpc_group, log_rpc_set_history_usage_threshold_handler,
598+
LOG_RPC_CMD_SET_HISTORY_USAGE_THRESHOLD,
599+
log_rpc_set_history_usage_threshold_handler, NULL);
600+
555601
#endif
556602

557603
#ifdef CONFIG_LOG_BACKEND_RPC_ECHO

subsys/logging/log_backend_rpc_history.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ void log_rpc_history_set_overwriting(bool overwriting);
1717
union log_msg_generic *log_rpc_history_pop(void);
1818
void log_rpc_history_free(const union log_msg_generic *msg);
1919

20+
uint8_t log_rpc_history_get_usage(void);
21+
2022
#endif /* LOG_RPC_HISTORY_H_ */

subsys/logging/log_backend_rpc_history_fcb.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,21 @@ void log_rpc_history_free(const union log_msg_generic *msg)
153153
{
154154
k_free((void *)msg);
155155
}
156+
157+
uint8_t log_rpc_history_get_usage(void)
158+
{
159+
int num_free_sectors;
160+
161+
k_mutex_lock(&fcb_lock, K_FOREVER);
162+
163+
num_free_sectors = fcb_free_sector_cnt(&fcb);
164+
165+
k_mutex_unlock(&fcb_lock);
166+
167+
/*
168+
* This calculates the usage with the sector size granularity.
169+
* Unforunately, there is no FCB API for getting more accurate usage, but it can be
170+
* implemented by hand if the greater accuraccy turns out to be needed.
171+
*/
172+
return (fcb.f_sector_cnt - num_free_sectors) * 100 / fcb.f_sector_cnt;
173+
}

subsys/logging/log_backend_rpc_history_ram.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,13 @@ void log_rpc_history_free(const union log_msg_generic *msg)
8181

8282
mpsc_pbuf_free(&log_history_pbuf, &msg->buf);
8383
}
84+
85+
uint8_t log_rpc_history_get_usage(void)
86+
{
87+
size_t total_size;
88+
size_t current_size;
89+
90+
mpsc_pbuf_get_utilization(&log_history_pbuf, &total_size, &current_size);
91+
92+
return current_size * 100 / total_size;
93+
}

subsys/logging/log_forwarder_rpc.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ LOG_MODULE_REGISTER(remote, LOG_LEVEL_DBG);
2626
static K_MUTEX_DEFINE(history_transfer_mtx);
2727
static uint32_t history_transfer_id;
2828
static log_rpc_history_handler_t history_handler;
29+
static log_rpc_history_threshold_reached_handler_t history_threshold_reached_handler;
2930

3031
static void log_rpc_msg_handler(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx,
3132
void *handler_data)
@@ -204,3 +205,44 @@ void log_rpc_echo(enum log_rpc_level level, const char *message)
204205

205206
nrf_rpc_cbor_decoding_done(&log_rpc_group, &ctx);
206207
}
208+
209+
static void log_rpc_history_threshold_reached_handler(const struct nrf_rpc_group *group,
210+
struct nrf_rpc_cbor_ctx *ctx,
211+
void *handler_data)
212+
{
213+
nrf_rpc_cbor_decoding_done(&log_rpc_group, ctx);
214+
215+
if (history_threshold_reached_handler) {
216+
history_threshold_reached_handler();
217+
}
218+
}
219+
220+
NRF_RPC_CBOR_EVT_DECODER(log_rpc_group, log_rpc_history_threshold_reached_handler,
221+
LOG_RPC_EVT_HISTORY_THRESHOLD_REACHED,
222+
log_rpc_history_threshold_reached_handler, NULL);
223+
224+
uint8_t log_rpc_get_history_usage_threshold(void)
225+
{
226+
struct nrf_rpc_cbor_ctx ctx;
227+
uint8_t threshold;
228+
229+
NRF_RPC_CBOR_ALLOC(&log_rpc_group, ctx, 0);
230+
231+
nrf_rpc_cbor_cmd_no_err(&log_rpc_group, LOG_RPC_CMD_GET_HISTORY_USAGE_THRESHOLD, &ctx,
232+
nrf_rpc_rsp_decode_u8, &threshold);
233+
234+
return threshold;
235+
}
236+
237+
void log_rpc_set_history_usage_threshold(log_rpc_history_threshold_reached_handler_t handler,
238+
uint8_t threshold)
239+
{
240+
struct nrf_rpc_cbor_ctx ctx;
241+
242+
history_threshold_reached_handler = handler;
243+
244+
NRF_RPC_CBOR_ALLOC(&log_rpc_group, ctx, 2);
245+
nrf_rpc_encode_uint(&ctx, threshold);
246+
nrf_rpc_cbor_cmd_no_err(&log_rpc_group, LOG_RPC_CMD_SET_HISTORY_USAGE_THRESHOLD, &ctx,
247+
nrf_rpc_rsp_decode_void, NULL);
248+
}

subsys/logging/log_rpc_group.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ NRF_RPC_GROUP_DEFINE(log_rpc_group, "log", &log_rpc_tr, NULL, NULL, NULL);
2929

3030
enum log_rpc_evt_forwarder {
3131
LOG_RPC_EVT_MSG = 0,
32+
LOG_RPC_EVT_HISTORY_THRESHOLD_REACHED = 1,
3233
};
3334

3435
enum log_rpc_cmd_forwarder {
@@ -37,10 +38,12 @@ enum log_rpc_cmd_forwarder {
3738

3839
enum log_rpc_cmd_backend {
3940
LOG_RPC_CMD_SET_STREAM_LEVEL = 0,
40-
LOG_RPC_CMD_SET_HISTORY_LEVEL = 1,
41-
LOG_RPC_CMD_FETCH_HISTORY = 2,
42-
LOG_RPC_CMD_GET_CRASH_LOG = 3,
43-
LOG_RPC_CMD_ECHO = 4,
41+
LOG_RPC_CMD_SET_HISTORY_LEVEL,
42+
LOG_RPC_CMD_GET_HISTORY_USAGE_THRESHOLD,
43+
LOG_RPC_CMD_SET_HISTORY_USAGE_THRESHOLD,
44+
LOG_RPC_CMD_FETCH_HISTORY,
45+
LOG_RPC_CMD_GET_CRASH_LOG,
46+
LOG_RPC_CMD_ECHO,
4447
};
4548

4649
#ifdef __cplusplus

0 commit comments

Comments
 (0)