Skip to content

Commit 48f3ed8

Browse files
lightningd/log: Improve logging to handle multi-line messages
Changelog-Added: Improved logging format in `lightningd/log` to handle multi-line messages by unescaping '\n' and logging each line separately. Signed-off-by: Nishant Bansal <[email protected]>
1 parent 86b160a commit 48f3ed8

File tree

1 file changed

+42
-29
lines changed

1 file changed

+42
-29
lines changed

lightningd/log.c

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#include "config.h"
22
#include <ccan/err/err.h>
33
#include <ccan/io/io.h>
4+
#include <ccan/json_escape/json_escape.h>
45
#include <ccan/read_write_all/read_write_all.h>
56
#include <ccan/str/hex/hex.h>
67
#include <ccan/tal/link/link.h>
78
#include <ccan/tal/str/str.h>
89
#include <common/configvar.h>
910
#include <common/json_command.h>
10-
#include <ccan/json_escape/json_escape.h>
1111
#include <common/json_param.h>
1212
#include <common/memleak.h>
1313
#include <errno.h>
@@ -558,48 +558,61 @@ static void maybe_notify_log(struct logger *log,
558558
notify_log(log->log_book->ld, l);
559559
}
560560

561+
static void add_one_log_entry(struct logger *log, enum log_level level,
562+
const struct node_id *node_id, bool call_notifier,
563+
const char *log_msg)
564+
{
565+
struct log_entry *l = new_log_entry(log, level, node_id);
566+
567+
l->log = strdup(log_msg);
568+
569+
/* Sanitize any non-printable characters, and replace with '?'
570+
*/
571+
for (size_t i = 0; log_msg[i] != '\0'; i++)
572+
if (l->log[i] < ' ' || l->log[i] >= 0x7f)
573+
l->log[i] = '?';
574+
575+
maybe_print(log, l);
576+
maybe_notify_log(log, l);
577+
578+
add_entry(log, &l);
579+
580+
if (call_notifier)
581+
notify_warning(log->log_book->ld, l);
582+
}
583+
561584
void logv(struct logger *log, enum log_level level,
562585
const struct node_id *node_id,
563586
bool call_notifier,
564587
const char *fmt, va_list ap)
565588
{
566589
int save_errno = errno;
567-
struct log_entry *l = new_log_entry(log, level, node_id);
590+
char *log_msg = NULL;
591+
const char *unescaped_log;
568592

569593
/* This is WARN_UNUSED_RESULT, because everyone should somehow deal
570594
* with OOM, even though nobody does. */
571-
if (vasprintf(&l->log, fmt, ap) == -1)
595+
if (vasprintf(&log_msg, fmt, ap) == -1)
572596
abort();
573597

574-
tal_t *ctx = tal(NULL, char);
575-
const char *log_line = tal_strdup(
576-
ctx, json_escape_unescape(ctx, (struct json_escape *)l->log));
577-
char **lines = tal_strsplit(ctx, log_line, "\n", STR_NO_EMPTY);
578-
579-
/* Split to lines and log them separately. */
580-
for (size_t i = 0; i < tal_count(lines) - 1; i++) {
581-
struct log_entry *line_entry =
582-
new_log_entry(log, level, node_id);
583-
line_entry->log = tal_strdup(ctx, lines[i]);
584-
585-
/* Sanitize any non-printable characters, and replace with '?'
586-
*/
587-
size_t line_len = strlen(line_entry->log);
588-
for (size_t i = 0; i < line_len; i++)
589-
if (line_entry->log[i] < ' ' ||
590-
line_entry->log[i] >= 0x7f)
591-
line_entry->log[i] = '?';
592-
593-
maybe_print(log, line_entry);
594-
maybe_notify_log(log, line_entry);
595-
596-
add_entry(log, &line_entry);
598+
/* Nothing to escape: simple copy */
599+
if (!strchr(log_msg, '\\'))
600+
add_one_log_entry(log, level, node_id, call_notifier, log_msg);
601+
/* If it's weird, unescaping can fail */
602+
else if ((unescaped_log = json_escape_unescape(
603+
tmpctx, (struct json_escape *)log_msg)) == NULL)
604+
add_one_log_entry(log, level, node_id, call_notifier, log_msg);
605+
else {
606+
char **lines = tal_strsplit(unescaped_log, unescaped_log, "\n",
607+
STR_EMPTY_OK);
608+
/* Split to lines and log them separately. */
609+
for (size_t i = 0; lines[i]; i++)
610+
add_one_log_entry(log, level, node_id, call_notifier,
611+
lines[i]);
597612
}
598613

599-
if (call_notifier)
600-
notify_warning(log->log_book->ld, l);
614+
free(log_msg);
601615

602-
tal_free(ctx);
603616
errno = save_errno;
604617
}
605618

0 commit comments

Comments
 (0)