Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lightningd/log: Improve logging to handle multi-line messages #7944

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

NishantBansal2003
Copy link

@NishantBansal2003 NishantBansal2003 commented Dec 16, 2024

Changelog-Added: Improved logging format in lightningd/log to handle multi-line messages by unescaping '\n' and logging each line separately.

Important

24.11 FREEZE NOVEMBER 7TH: Non-bugfix PRs not ready by this date will wait for 25.02.

Fixes: #4912

Log-Output:

2024-12-16T16:19:09.470Z UNUSUAL plugin-bookkeeper: topic 'utxo_deposit' is not a known notification topic                                             ─╯
2024-12-16T16:19:09.471Z UNUSUAL plugin-bookkeeper: topic 'utxo_spend' is not a known notification topic

Could not connect to bitcoind using bitcoin-cli. Is bitcoind running?

Make sure you have bitcoind running and that bitcoin-cli is able to connect to bitcoind.

You can verify that your Bitcoin Core installation is ready for use by running:

    $ bitcoin-cli -rpcclienttimeout=60 echo 'hello world'
2024-12-16T16:19:11.635Z **BROKEN** plugin-bcli: Could not connect to bitcoind using bitcoin-cli. Is bitcoind running?
2024-12-16T16:19:11.635Z **BROKEN** plugin-bcli: Make sure you have bitcoind running and that bitcoin-cli is able to connect to bitcoind.
2024-12-16T16:19:11.635Z **BROKEN** plugin-bcli: You can verify that your Bitcoin Core installation is ready for use by running:
2024-12-16T16:19:11.635Z **BROKEN** plugin-bcli:     $ bitcoin-cli -rpcclienttimeout=60 echo 'hello world'
2024-12-16T16:19:11.635Z INFO    plugin-bcli: Killing plugin: exited before we sent init
The Bitcoin backend died.

Checklist

Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes.
  • Documentation has been reviewed and updated as needed.
  • Related issues have been listed and linked, including any that this PR closes.

Copy link
Contributor

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

lightningd/log.c Outdated Show resolved Hide resolved
lightningd/log.c Outdated Show resolved Hide resolved
@NishantBansal2003
Copy link
Author

Hey @rustyrussell , I made some modifications based on your feedback. Could you please check if everything is covered, or if I need to check anything further?

@NishantBansal2003
Copy link
Author

Hey @rustyrussell, I tried debugging this memory leak issue in CI but couldn't understand the root cause. Could you point me to some documentation that explains how Core Lightning handles memory leaks? Thanks!

Copy link
Contributor

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking much better!

lightningd/log.c Outdated
Comment on lines 577 to 585
struct log_entry *l = new_log_entry(log, level, node_id);

/* Split to lines and log them separately. */
for (size_t j = 0; lines[j]; j++) {
l->log = tal_strdup(log, lines[j]);
l->log = strdup(log_msg);
size_t log_len = strlen(l->log);

/* Sanitize any non-printable characters, and replace with '?'
*/
size_t line_len = strlen(l->log);
for (size_t i = 0; i < line_len; i++)
for (size_t i = 0; i < log_len; i++)
if (l->log[i] < ' ' || l->log[i] >= 0x7f)
l->log[i] = '?';

maybe_print(log, l);
maybe_notify_log(log, l);

add_entry(log, &l);
}

if (call_notifier)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract this common code into a new function, rather than calling twice. Say "add_one_log_entry(log, level, nodeid, string)", which does new_log_entry, strdup, sanitize, maybe_print, maybe_notify_log, add_entry.

Then you can make the code a bit more optimal, and avoid json_escape if there are no escapes:

/* Nothing to escape: simple copy */
if (!strchr(log_msg, '\\'))
   add_one_log_entry(log, level, nodeid, log_msg);
/* If it's weird, unescaping can fail */
else if ((unescaped_log = json_escape_unescape(tmpctx, (struct json_escape *)log_msg)) == NULL) 
   add_one_log_entry(log, level, nodeid, log_msg);
else {
  char **lines = tal_strsplit(unescaped_log, unescaped_log, "\n", STR_EMPTY_OK);
	/* Split to lines and log them separately. */
		for (size_t i = 0; lines[i]; i++)
                     add_one_log_entry(log, level, nodeid, lines[i]);
}

lightningd/log.c Outdated
log, json_escape_unescape(log, (struct json_escape *)log_msg), "\n",
STR_NO_EMPTY);
const char *unescaped_log =
json_escape_unescape(NULL, (struct json_escape *)log_msg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the cause of your leak, BTW. Every tal allocation is off some other tal allocation (or NULL). There's a special throwaway one called tmpctx which automagically gets cleaned in the event loop. Since you used NULL here, and don't free it, it gets caught as a leak by our leak detection code (and it is!).

lightningd/log.c Outdated
char *log_msg = NULL;

/* This is WARN_UNUSED_RESULT, because everyone should somehow deal
* with OOM, even though nobody does. */
if (vasprintf(&log_msg, fmt, ap) == -1)
abort();

char **lines = tal_strsplit(
log, json_escape_unescape(log, (struct json_escape *)log_msg), "\n",
STR_NO_EMPTY);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STR_EMPTY_OK, since you want to log empty lines too I think?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the output will look something like:

 $ bitcoin-cli -rpcclienttimeout=60 echo 'hello world'
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: 
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: Could not connect to bitcoind using bitcoin-cli. Is bitcoind running?
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: 
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: Make sure you have bitcoind running and that bitcoin-cli is able to connect to bitcoind.
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: 
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: You can verify that your Bitcoin Core installation is ready for use by running:
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli: 
2024-12-19T06:39:55.230Z **BROKEN** plugin-bcli:     $ bitcoin-cli -rpcclienttimeout=60 echo 'hello world'
2024-12-19T06:39:55.230Z INFO    plugin-bcli: Killing plugin: exited before we sent init
The Bitcoin backend died.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's right, TBH?

@NishantBansal2003
Copy link
Author

NishantBansal2003 commented Dec 19, 2024

Hey @rustyrussell, thank you for helping me out with this PR—it means a lot to me. I learned something new while working on this.

One more thing: could you please let me know what configuration/tool the core-lightning codebase uses to format its C code? I noticed a lot of formatting changes happening on save.

Copy link
Contributor

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking really good now. Since you're a new contributor I've really nit-picked it, so there are two more trivial changes.

Also, squish it into a single commit please, so I can apply it!

lightningd/log.c Outdated
@@ -558,70 +558,60 @@ static void maybe_notify_log(struct logger *log,
notify_log(log->log_book->ld, l);
}

static void add_one_log_entry(struct logger *log, enum log_level level,
const struct node_id *node_id, bool call_notifier,
char *log_msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const char * - we always use const when we can (it's a C bug that it's not the default!)

lightningd/log.c Outdated
Comment on lines 568 to 572
size_t log_len = strlen(l->log);

/* Sanitize any non-printable characters, and replace with '?'
*/
for (size_t i = 0; i < log_len; i++)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop log_len, use log_msg[i] != '\0'?

@rustyrussell
Copy link
Contributor

Hey @rustyrussell, thank you for helping me out with this PR—it means a lot to me. I learned something new while working on this.

One more thing: could you please let me know what configuration/tool the core-lightning codebase uses to format its C code? I noticed a lot of formatting changes happening on save.

I use emacs, so that just does it all for me :(

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 <nishant.bansal.282003@gmail.com>

lightningd/log: Improve log handling
Changelog-Added: Improved log handling to save memory.

Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>

lightningd/log: Refactor code for logging
Changelog-Added: Refactored code for log handling.

Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

plugin-bcli returning "\n" instead of line break in the logfile
2 participants