Compare commits

...

36 Commits

Author SHA1 Message Date
Eric Eastwood
1f95a3b867 Prefer PreserveLoggingContext() defaults
See https://github.com/element-hq/synapse/pull/18870#discussion_r2337820664
2025-09-10 15:28:37 -05:00
Eric Eastwood
e6685cc6ec Remove db profiling looping_call change
See https://github.com/element-hq/synapse/pull/18870#discussion_r2337807988
2025-09-10 15:23:31 -05:00
Eric Eastwood
9c74f6919e Fix lints 2025-09-10 15:14:53 -05:00
Eric Eastwood
6bbd0bf686 Revise changelog 2025-09-10 15:14:24 -05:00
Eric Eastwood
dcf5fca77e Merge branch 'develop' into madlittlemods/remove-sentinel-context 2025-09-10 14:38:37 -05:00
Eric Eastwood
e626f093ad Add changelog 2025-09-09 00:15:03 -05:00
Eric Eastwood
fab546d618 Add logcontext to database profiling loop 2025-09-08 22:04:57 -05:00
Eric Eastwood
e741daf24e Simplify atexit logcontext 2025-09-08 21:59:15 -05:00
Eric Eastwood
74ab47f97b Add context for "Shutting down..." log 2025-09-08 21:58:02 -05:00
Eric Eastwood
b8c0857263 Re-establish logcontext at start
We lose the `main` context once we start the reactor. We need to re-establish
the logcontext at the reactor callback entrypoints.
2025-09-08 21:52:47 -05:00
Eric Eastwood
5c05a0b309 Revert "DEBUG: lost main context after request"
This reverts commit 7938e8cef4.
2025-09-08 21:12:48 -05:00
Eric Eastwood
ae8055a313 Revert "Debug: Eliminate variables"
This reverts commit b97b2ddac6.
2025-09-08 21:12:29 -05:00
Eric Eastwood
4b61570cd1 Revert "DEBUG: test"
This reverts commit 301a71449c.
2025-09-08 21:12:23 -05:00
Eric Eastwood
37a388c767 Revert "Explain the sentinel context better"
This reverts commit d8f68d09dd.
2025-09-08 21:12:11 -05:00
Eric Eastwood
4aa0aa0aa5 Revert "Clarify when to use the sentinel context"
This reverts commit 71cd3c43ce.
2025-09-08 21:12:10 -05:00
Eric Eastwood
b5ec2daba8 Revert "Explain logging context in run_as_background_process"
This reverts commit 0e990e67e6.
2025-09-08 21:12:09 -05:00
Eric Eastwood
bbe1ee7b91 Revert "Add potential future simplication of run_as_background_process"
This reverts commit 6a98096139.
2025-09-08 21:12:07 -05:00
Eric Eastwood
1f4b3919e7 Revert "Add log context explanation to run_in_background"
This reverts commit ea5a841678.
2025-09-08 21:12:03 -05:00
Eric Eastwood
4b2e88fe27 Merge branch 'madlittlemods/remove-sentinel-context' of github.com:element-hq/synapse into madlittlemods/remove-sentinel-context 2025-09-08 13:35:48 -05:00
Eric Eastwood
ea5a841678 Add log context explanation to run_in_background 2025-09-08 13:34:52 -05:00
Eric Eastwood
6a98096139 Add potential future simplication of run_as_background_process 2025-09-08 13:21:20 -05:00
Eric Eastwood
0e990e67e6 Explain logging context in run_as_background_process 2025-09-08 13:18:54 -05:00
Eric Eastwood
71cd3c43ce Clarify when to use the sentinel context 2025-09-08 12:40:55 -05:00
Eric Eastwood
d8f68d09dd Explain the sentinel context better 2025-09-08 12:34:42 -05:00
Eric Eastwood
c1996b62cf WIP: Pair with @erikjohnston 2025-09-08 10:59:25 -05:00
Eric Eastwood
301a71449c DEBUG: test 2025-09-05 21:59:12 -05:00
Eric Eastwood
b97b2ddac6 Debug: Eliminate variables
Reproduction:

 1. `poetry run synapse_homeserver --config-path homeserver.yaml`
 1. Ctrl + C to stop the server
 1. Notice `LoggingContext: Expected logging context main was lost` in the logs
2025-09-05 18:50:50 -05:00
Eric Eastwood
0a865fd2ab Revert "Fix run_as_background_process not following Synapse log context rules"
This reverts commit 675d94a0ec.

Things get stuck with this, see https://github.com/element-hq/synapse/pull/18870#discussion_r2322891926
2025-09-04 15:17:30 -05:00
Eric Eastwood
7938e8cef4 DEBUG: lost main context after request
Reproduction instructions:

 1. `poetry run synapse_homeserver --config-path homeserver.yaml`
 1. `curl http://localhost:8008/_matrix/client/versions`
 1. Stop Synapse (`Ctrl + c`)

Notice the bad log:

```
synapse.logging.context - WARNING - sentinel - LoggingContext: Expected logging context main was lost
```
2025-09-04 15:17:24 -05:00
Eric Eastwood
1bf7049a7f Merge branch 'develop' into madlittlemods/remove-sentinel-context 2025-08-27 19:13:24 -05:00
Eric Eastwood
675d94a0ec Fix run_as_background_process not following Synapse log context rules
Resulting in bad logs being seen:

```
PreserveLoggingContext: Expected logging context sentinel but found main
```

```
LoggingContext: Expected logging context main was lost
```
2025-08-27 02:17:24 -05:00
Eric Eastwood
af1944bec4 Revert "DEBUG: Logging contexts getting lost"
This reverts commit fce59b2284.
2025-08-27 02:12:24 -05:00
Eric Eastwood
fce59b2284 DEBUG: Logging contexts getting lost
Running a normal server (`daemonize: false`):

```
poetry run synapse_homeserver --config-path homeserver.yaml
```

Bad logs being seen:

```
PreserveLoggingContext: Expected logging context sentinel but found main
```

```
LoggingContext: Expected logging context main was lost
```
2025-08-27 01:56:07 -05:00
Eric Eastwood
a677d9b319 Remove sentinel context from atexit daemonize logs
```
2025-08-26 18:40:27,996 - my.synapse.linux.server - synapse.app.homeserver - 187 - WARNING - main - Starting daemon.
2025-08-26 18:40:27,996 - my.synapse.linux.server - synapse.app.homeserver - 181 - WARNING - atexit - Stopping daemon.
```
2025-08-26 21:40:02 -05:00
Eric Eastwood
bf21b4ab8b Simplify stop/start context pattern in daemonize_process 2025-08-26 21:39:24 -05:00
Eric Eastwood
ea6c5871e2 Remove sentinel context from start_reactor (daemonize_process/run)
Relevant comment introductions:

 - https://github.com/matrix-org/synapse/pull/5609
 - 067b00d49d
2025-08-26 21:38:38 -05:00
5 changed files with 53 additions and 33 deletions

1
changelog.d/18870.misc Normal file
View File

@@ -0,0 +1 @@
Remove `sentinel` logcontext usage where we log in `setup`, `start` and exit.

View File

@@ -72,7 +72,7 @@ from synapse.events.auto_accept_invites import InviteAutoAccepter
from synapse.events.presence_router import load_legacy_presence_router
from synapse.handlers.auth import load_legacy_password_auth_providers
from synapse.http.site import SynapseSite
from synapse.logging.context import PreserveLoggingContext
from synapse.logging.context import LoggingContext, PreserveLoggingContext
from synapse.logging.opentracing import init_tracer
from synapse.metrics import install_gc_manager, register_threadpool
from synapse.metrics.background_process_metrics import run_as_background_process
@@ -183,25 +183,23 @@ def start_reactor(
if gc_thresholds:
gc.set_threshold(*gc_thresholds)
install_gc_manager()
run_command()
# make sure that we run the reactor with the sentinel log context,
# otherwise other PreserveLoggingContext instances will get confused
# and complain when they see the logcontext arbitrarily swapping
# between the sentinel and `run` logcontexts.
#
# We also need to drop the logcontext before forking if we're daemonizing,
# otherwise the cputime metrics get confused about the per-thread resource usage
# appearing to go backwards.
with PreserveLoggingContext():
if daemonize:
assert pid_file is not None
# Reset the logging context when we start the reactor (whenever we yield control
# to the reactor, the `sentinel` logging context needs to be set so we don't
# leak the current logging context and erroneously apply it to the next task the
# reactor event loop picks up)
with PreserveLoggingContext():
run_command()
if print_pidfile:
print(pid_file)
if daemonize:
assert pid_file is not None
daemonize_process(pid_file, logger)
run()
if print_pidfile:
print(pid_file)
daemonize_process(pid_file, logger)
run()
def quit_with_error(error_string: str) -> NoReturn:
@@ -601,10 +599,12 @@ async def start(hs: "HomeServer") -> None:
hs.get_datastores().main.db_pool.start_profiling()
hs.get_pusherpool().start()
def log_shutdown() -> None:
with LoggingContext("log_shutdown"):
logger.info("Shutting down...")
# Log when we start the shut down process.
hs.get_reactor().addSystemEventTrigger(
"before", "shutdown", logger.info, "Shutting down..."
)
hs.get_reactor().addSystemEventTrigger("before", "shutdown", log_shutdown)
setup_sentry(hs)
setup_sdnotify(hs)

View File

@@ -355,7 +355,12 @@ def start(config_options: List[str]) -> None:
except Exception as e:
handle_startup_exception(e)
register_start(_base.start, hs)
async def start() -> None:
# Re-establish log context now that we're back from the reactor
with LoggingContext("start"):
await _base.start(hs)
register_start(start)
# redirect stdio to the logs, if configured.
if not hs.config.logging.no_redirect_stdio:

View File

@@ -377,15 +377,17 @@ def setup(config_options: List[str]) -> SynapseHomeServer:
handle_startup_exception(e)
async def start() -> None:
# Load the OIDC provider metadatas, if OIDC is enabled.
if hs.config.oidc.oidc_enabled:
oidc = hs.get_oidc_handler()
# Loading the provider metadata also ensures the provider config is valid.
await oidc.load_metadata()
# Re-establish log context now that we're back from the reactor
with LoggingContext("start"):
# Load the OIDC provider metadatas, if OIDC is enabled.
if hs.config.oidc.oidc_enabled:
oidc = hs.get_oidc_handler()
# Loading the provider metadata also ensures the provider config is valid.
await oidc.load_metadata()
await _base.start(hs)
await _base.start(hs)
hs.get_datastores().main.db_pool.updates.start_doing_background_updates()
hs.get_datastores().main.db_pool.updates.start_doing_background_updates()
register_start(start)

View File

@@ -29,6 +29,11 @@ import sys
from types import FrameType, TracebackType
from typing import NoReturn, Optional, Type
from synapse.logging.context import (
LoggingContext,
PreserveLoggingContext,
)
def daemonize_process(pid_file: str, logger: logging.Logger, chdir: str = "/") -> None:
"""daemonize the current process
@@ -64,8 +69,14 @@ def daemonize_process(pid_file: str, logger: logging.Logger, chdir: str = "/") -
pid_fh.write(old_pid)
sys.exit(1)
# Fork, creating a new process for the child.
process_id = os.fork()
# Stop the existing context *before* we fork the process. Otherwise the cputime
# metrics get confused about the per-thread resource usage appearing to go backwards
# because we're comparing the resource usage from the original process to the forked
# process. `PreserveLoggingContext` already takes care of restarting the original
# context *after* the block.
with PreserveLoggingContext():
# Fork, creating a new process for the child.
process_id = os.fork()
if process_id != 0:
# parent process: exit.
@@ -140,9 +151,10 @@ def daemonize_process(pid_file: str, logger: logging.Logger, chdir: str = "/") -
# Cleanup pid file at exit.
def exit() -> None:
logger.warning("Stopping daemon.")
os.remove(pid_file)
sys.exit(0)
with LoggingContext("atexit"):
logger.warning("Stopping daemon.")
os.remove(pid_file)
sys.exit(0)
atexit.register(exit)