Skip to content

Conversation

dongcarl
Copy link
Contributor

@dongcarl dongcarl commented Sep 1, 2022

1. Make logs available to journalctl (systemd's logging system) by not
   specifying -daemonwait, which rightfully has its own set of stdout
   and stderr descriptors (a user invoking with -daemonwait on the
   command line should not see any logs). It makes more sense not to
   daemonize in the systemd context anyway.

2. Make systemd aware of when bitcoind is started and in steady state by
   specifying -startupnotify='systemd-notify --ready' and Type=notify.
   NotifyAccess=all is necessary so that the spawned thread for
   startupnotify is allowed to inform systemd of bitcoind's readiness.

   Note that NotifyAccess=exec won't work because it only allows
   sd_notify readiness signalling from Exec*= declarations in the
   .service file.

Note that we currently don't allow multiple startupnotify commands, but
users can override it in systemd via:

  # systemctl edit bitcoind

By specifying something like:

  [Service]
  ExecStart=/usr/bin/bitcoind -pid=/run/bitcoind/bitcoind.pid \
                              -conf=/etc/bitcoin/bitcoin.conf \
                              -datadir=/var/lib/bitcoind \
                              -startupnotify='systemd-notify --ready; mycommandhere'

@jamesob
Copy link
Contributor

jamesob commented Sep 6, 2022

Concept ACK

@luke-jr
Copy link
Member

luke-jr commented Sep 9, 2022

Related: #22372

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 23, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK real-or-random
Concept ACK jamesob, fanquake

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

No conflicts as of last run.

@dongcarl
Copy link
Contributor Author

Anything else needed here?

@fanquake
Copy link
Member

Anything else needed here?

Someone to actually sanity-check / test / review / leave an ACK? I don't use systemd, so can't test, and don't generally know if this is an improvement or not.

Looks like it at least partially reverts #21418, which was done in combination with #21007; where Type=forking was chosen specifically over Type=notify:

An alternative would be to implement support for Type=notify and do readyness notification through sd_notify. But I opted for daemonwait because it seems more generally useful.

Does this change break / compormise that behaviour?

@kristapsk
Copy link
Contributor

Will try to look at these proposed changes with my RaspiBolt, which uses systemd (although with custom systemd unit file, but it is similar).

@dongcarl
Copy link
Contributor Author

dongcarl commented Dec 12, 2022

Does this change break / compormise that behaviour?

I think what laanwj was saying there was that if we had integrated libsystemd and called sd_notify ourselves, then we'd have startup notification logic that was only specific to systemd which is less than ideal since it's an extra dependency and we (at least strive to) support other init systems.

So that's why we started using -daemonwait, which is a somewhat portable readiness notification method for almost all init systems.

However, IIRC, in using -daemonwait, the forked/exec'd (I'm probably using this terminology wrong) bitcoind process will have a different set of stdout/stderr than the original process, which means that the logs that it prints will be discarded.

With the introduction of -startupnotify, however, we can run bitcoind without forking/exec-ing, and instead invoke systemd-notify --ready (basically just a CLI wrapper around libsystemd that all systemd systems have) to signal readiness. This means that the logs in stdout/stderr will flow to journald as expected on systemd systems.

Sidenote: There's currently no way I can find to tell systemd: My spawned process will append logs to /var/lib/bitcoind/debug.log so have journald watch that file for logs.

Sidenote 2: While it doesn't make sense to modify -daemonwait such that the child process inherits the parent's stdout/stderr (those invoking -daemonwait on the CLI expect the process to be fully detached), it might make sense to add a -daemonwaitinherit or something like that, but I think that might be an unwanted bloat of the CLI interface and that -startupnotify is good enough here.

@achow101
Copy link
Member

The feature request didn't seem to attract much attention in the past. Also, the issue seems not important enough right now to keep it sitting around idle in the list of open issues.

Closing due to lack of interest. Pull requests with improvements are always welcome.

@achow101 achow101 closed this Apr 25, 2023
Copy link
Contributor

@real-or-random real-or-random left a comment

Choose a reason for hiding this comment

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

ACK mod nits

This is very useful for systemd users. The changes match systemd docs and I tested that process management and logging works as intended.

@achow101 Can you reopen this?

One minor issue: This means what (with default config), we have log output both in systemd's journal and in the log file. In principle, it may make sense to also pass -nodebuglogfile, but I'm not sure if this is really what we want because it means that the user can't override this option in the config file anymore... Maybe a Changelog entry should be added, recommending systemd users to consider disabling writing logs to a file.

A more sophisticated solution would be to add a --systemd-notify command line option, that sets modifies the defaults of startupnotify, shutdownnotify, and debuglogfile (or even better avoids the problem that users who want to use further startup commands need to modify the systemd unit file). But I'm not convinced that adding this option is worth the hassle. It's probably good to have all systemd-specific code just in this unit file here. Anyway, this PR is clearly an improvement for systemd users, so even if --systemd-notify is a good idea for the future, it should not hold up this PR.

@maflcko maflcko reopened this May 2, 2023
1. Make logs available to journalctl (systemd's logging system) by not
   specifying -daemonwait, which rightfully has its own set of stdout
   and stderr descriptors (a user invoking with -daemonwait on the
   command line should not see any logs). It makes more sense not to
   daemonize in the systemd context anyway.

2. Make systemd aware of when bitcoind is started and in steady state by
   specifying -startupnotify='systemd-notify --ready' and Type=notify.
   NotifyAccess=all is necessary so that the spawned thread for
   startupnotify is allowed to inform systemd of bitcoind's readiness.

   Note that NotifyAccess=exec won't work because it only allows
   sd_notify readiness signalling from Exec*= declarations in the
   .service file.

3. Also make systemd aware of when bitcoind is stopping by specifying
   -shutdownnotify='systemd-notify --stopping'

Note that we currently don't allow multiple *notify commands, but users
can override it in systemd via:

  # systemctl edit bitcoind

By specifying something like:

  [Service]
  ExecStart=/usr/bin/bitcoind -pid=/run/bitcoind/bitcoind.pid \
                              -conf=/etc/bitcoin/bitcoin.conf \
                              -datadir=/var/lib/bitcoind \
                              -startupnotify='systemd-notify --ready; mystartupcommandhere' \
                              -shutdownnotify='systemd-notify --stopping; myshutdowncommandhere'
@dongcarl dongcarl force-pushed the 2022-09-systemd-improve branch from 42bcabb to 689a65d Compare May 28, 2023 17:13
@dongcarl
Copy link
Contributor Author

@dongcarl
Copy link
Contributor Author

I think whether or not to to add a -nodebuglogfile is somewhat tangential to the systemd integration and more related to whether or not -daemonwait is specified or even more specifically whether or not we're writing logs to stdout+stderr.

As in: Does a user of bitcoind that doesn't specify -daemonwait and expects logs on stdout+stderr also expect the debug log file to be written to or no?

In any case, I think we can leave that discussion for another time.

Copy link
Contributor

@real-or-random real-or-random left a comment

Choose a reason for hiding this comment

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

ACK 689a65d tested this service file with 25.0

@fanquake fanquake merged commit 769dd1e into bitcoin:master May 29, 2023
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 29, 2023
@Sjors
Copy link
Member

Sjors commented Jun 16, 2023

This is great. Can you (or someone else) make a release note? Otherwise I'm probably to forget to use these changes myself on the next release :-) I'll go ahead and try them now.

I certainly prefer to keep using my debug.log file. I generally only use journalctl if there's a problem starting a service (or to see if indeed got the right version after an update).

archlinux-github pushed a commit to archlinux/aur that referenced this pull request Dec 24, 2023
Remove .service file patch since it's now in the release

See: bitcoin/bitcoin#25975
@bitcoin bitcoin locked and limited conversation to collaborators Oct 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.