[RFC PATCH ubus] cli: improve error logging for call command
Stijn Tintel
stijn at linux-ipv6.be
Fri Feb 18 01:55:59 PST 2022
On 18/02/2022 11:31, Stijn Tintel wrote:
> When the ubus "call" command fails, ubus prints "Command failed: ...".
> This is fine when the call command is executed interactively by the
> user. However, when the call command is executed non-interactively,
> these log messages leave the user completely clueless:
>
> netifd: wan6 (10841): Command failed: Unknown error
>
> procd: /etc/rc.d/S80umdns: Failed to parse message data
>
> These messages contain absolutely no info that explains where they come
> from; it's not even clear they are coming from ubus. This makes tracking
> down what's causing them virtually impossible.
>
> Improve this situation by printing the full ubus call to stderr when
> stderr is not a TTY.
>
> Example of improved error message:
> netifd: wan (2836): Command failed: ubus call network.interface notify_proto { "action": 0, "link-up": false, "keep": false, "interface": "wan" } (Permission denied)
>
> While one might argue not to include the JSON message in the log,
> excluding it will still not help to reproduce the failed command.
> As we only print the full command when stderr is not a TTY, seeing this
> error means we're doing a bad ubus call somewhere, which is a bug and
> should be fixed. Printing the full command makes more sense than
> printing half the command and still requiring us to figure out the exact
> command that failed.
>
> Signed-off-by: Stijn Tintel <stijn at linux-ipv6.be>
> ---
> If anyone wants to argue this isn't useful:
> https://forum.openwrt.org/search?q=%22Command%20failed%22
> ---
> cli.c | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/cli.c b/cli.c
> index 81591ec..bc14daf 100644
> --- a/cli.c
> +++ b/cli.c
> @@ -119,6 +119,19 @@ static void receive_event(struct ubus_context *ctx, struct ubus_event_handler *e
> print_event(type, msg);
> }
>
> +static void print_error(char *msg, char *cmd, int argc, char **argv, int err)
> +{
> + int i;
> +
> + fprintf(stderr, "%s failed: ubus %s ", msg, cmd);
> + for (i = 0; i < argc; i++) {
> + fprintf(stderr, "%s ", argv[i]);
> + }
> + if (err)
> + fprintf(stderr, "(%s)", ubus_strerror(err));
> + fprintf(stderr, "\n");
> +}
> +
> static int ubus_cli_list(struct ubus_context *ctx, int argc, char **argv)
> {
> const char *path = NULL;
> @@ -143,7 +156,7 @@ static int ubus_cli_call(struct ubus_context *ctx, int argc, char **argv)
> blob_buf_init(&b, 0);
> if (argc == 3 && !blobmsg_add_json_from_string(&b, argv[2])) {
> if (!simple_output)
> - fprintf(stderr, "Failed to parse message data\n");
> + print_error("Parsing message data", "call", argc, argv, ret);
Should have used 0 instead of ret here, but instead I will initialize
ret to 0 at the start of the function.
> return -1;
> }
>
> @@ -151,7 +164,13 @@ static int ubus_cli_call(struct ubus_context *ctx, int argc, char **argv)
> if (ret)
> return ret;
>
> - return ubus_invoke(ctx, id, argv[1], b.head, receive_call_result_data, NULL, timeout * 1000);
> + ret = ubus_invoke(ctx, id, argv[1], b.head, receive_call_result_data, NULL, timeout * 1000);
> + if (ret && !simple_output && !isatty(fileno(stderr) == ENOTTY)) {
> + print_error("Command", "call", argc, argv, ret);
> + return -1;
> + }
> +
> + return ret;
> }
>
> struct cli_listen_data {
More information about the openwrt-devel
mailing list