Add --log quiet flag to suppress informational logs - #216
Conversation
hicksy
left a comment
There was a problem hiding this comment.
Thanks for this, and for picking it up so soon after #215. It's the shape I had in mind: --log with quiet as the first value, and nothing changes when the flag is absent. I built it locally and reverted each of the two guards in turn, and log_quiet_suppresses_serve_startup_messages fails both times, so the coverage is real.
A few things before I merge, none of them big:
- The shutdown line still prints. With
--log quiet, stopping the server with SIGTERM or Ctrl+C still writes a blank line andShutting down...to stderr. Most test runners stop the server that way at teardown, so the noise from #215 comes back at the end of the run. The test misses it becausechild.kill()sends SIGKILL. Inline note on where it comes from. - CHANGELOG. The box is ticked but
CHANGELOG.mdisn't in the diff. An entry under[Unreleased]would cover the flag, plus a line forserver::ServerOptionsandserver::start_with_options, since they're new public API in the crate. - The startup line is a documented promise. The "What a container waits on" section of
docs/versioning.mdtells container tooling it can wait onDynoxide listening on http://<host>:<port>. That still holds by default, but a sentence there saying--log quietdrops the line, and that a wait onGET /works either way, would save someone who combines the two a confusing timeout. - Docs placement. Both new doc blocks land mid-flow. Inline notes.
Smaller bits inline: dropping Copy from ServerOptions, a line of help text on Quiet, and the --quiet assertions in the tests.
One thing to leave out: serve --mcp --log quiet still prints the MCP listener line. Quieting it needs a new field on mcp::HttpOptions, which has public fields, so adding one is a breaking change for the crate. I'll pick that up separately along with import --serve, so no need to touch it here.
Not far off - happy to merge once those are sorted.
| } | ||
|
|
||
| axum::serve(listener, app) | ||
| .with_graceful_shutdown(shutdown_signal()) |
There was a problem hiding this comment.
This is where the shutdown message comes from. shutdown_signal() further down prints \nShutting down... once it sees SIGTERM or Ctrl+C, and quiet mode never reaches it. Passing the options through (shutdown_signal(options) or similar) would cover it, and suppress_startup_messages probably wants a broader name like quiet once it covers shutdown too.
For the test, on unix you can send SIGTERM instead of child.kill(), e.g. Command::new("kill").args(["-TERM", &child.id().to_string()]) behind #[cfg(unix)]. Wait for GET / to answer rather than a bare TCP connect, then assert the process exits successfully. A clean exit shows the signal went through the handler; if it ever arrives before the handler is installed, the process dies from the signal and the test fails loudly instead of passing without checking anything.
There was a problem hiding this comment.
great catch, totally missed this one thank you 🙏
| const STREAMS_TARGET_PREFIX: &str = "DynamoDBStreams_20120810."; | ||
|
|
||
| /// Options controlling HTTP server startup. | ||
| #[derive(Debug, Clone, Copy, Default)] |
There was a problem hiding this comment.
Could we drop Copy? ServerOptions is public, and the obvious next field is whatever --log verbose needs for #14, which may well not be Copy. Taking the derive away later is a breaking change for the crate. mcp::HttpOptions and McpConfig derive Clone, Debug only.
|
|
||
| #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | ||
| enum LogMode { | ||
| Quiet, |
There was a problem hiding this comment.
--help only says "Logging mode" at the moment. A doc comment on the variant gets picked up, so /// Suppress informational startup and shutdown messages above Quiet shows under "Possible values" in serve --help.
| } | ||
|
|
||
| #[test] | ||
| fn legacy_and_unsupported_log_modes_are_rejected() { |
There was a problem hiding this comment.
There's never been a --quiet flag, so "legacy" is a bit misleading, and clap rejects unknown flags anyway. verbose is the value I'm planning to add for #14, so this would need deleting then. A nonsense value like --log loud covers the invalid-value case without pinning either.
| } | ||
|
|
||
| #[test] | ||
| fn serve_help_lists_log_but_not_quiet_flag() { |
There was a problem hiding this comment.
Same here. The --log <MODE> check is worth having and matches the --schema help tests above, but the --quiet half can go (in root_help_lists_log_but_not_quiet_flag too), and the names can lose the "but_not_quiet" bit.
| dynoxide --schema schema.json --port 8000 | ||
| ``` | ||
|
|
||
| ## Logging |
There was a problem hiding this comment.
This lands between the schema example and "Then use the AWS CLI or any DynamoDB SDK pointed at localhost", so that sentence now follows the logging section. Moving it to the end of the page keeps start-then-connect together.
| npx dynoxide --port 8000 | ||
| ``` | ||
|
|
||
| Add `--log quiet` to suppress informational startup messages on stderr (useful |
There was a problem hiding this comment.
The next two paragraphs start "Or install it..." and "Or run it in Docker...", offering alternatives to the npx line, so they read oddly after this note. Could it go after the "Point any AWS SDK..." paragraph instead?
|
Merged - thanks @zhua633, and for turning the feedback round so quickly. I reverted the shutdown guard to check the new SIGTERM test and it fails, so it's covering what it should. I'll follow up with a |
What this changes
Thanks for looking at the issue 🙏 This attempts to add
--log quietas described, let me know if this isn't quite what you had in mindTested locally built binary:
Checklist
cargo fmt --checkandcargo clippy -- -D warningspass locallyCHANGELOG.mdupdated if this is a user-visible changemotivation
(MIT License and Apache License, Version 2.0)
DynamoDB compatibility note (delete if not applicable)