Skip to content

add observability infrastructure for cli subcmds

Charles Hall requested to merge charles/cli-observability into main

We have a bunch of MRs that aim to add more CLI subcommands, and they'll all need logging set up. This MR adds some infrastructure to make it easy to add CLI-oriented subcommands with observability in the future without a bunch of merge conflicts and provides a single place to review these changes.

Here's an example of how this is intended to be used:

diff --git a/src/cli.rs b/src/cli.rs
index 87b18029..44af4790 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -29,6 +29,9 @@ pub(crate) struct Args {
 pub(crate) enum Command {
     /// Run the server.
     Serve(ServeArgs),
+
+    /// Crash the program
+    Crash(CrashArgs),
 }

 /// Wrapper for the `--config` arg.
@@ -80,6 +83,12 @@ pub(crate) struct ServeArgs {
     pub(crate) config: ConfigArg,
 }

+#[derive(clap::Args)]
+pub(crate) struct CrashArgs {
+    #[clap(flatten)]
+    observability: ObservabilityArgs,
+}
+
 impl Args {
     pub(crate) async fn run(self) -> Result<(), error::Main> {
         if let Some((format, filter)) = self.command.cli_observability_args() {
@@ -88,6 +97,10 @@ impl Args {

         match self.command {
             Command::Serve(args) => serve::run(args).await?,
+            Command::Crash(_) => {
+                tracing::warn!("Crashing the program as instructed");
+                panic!()
+            }
         }
         Ok(())
     }
@@ -98,6 +111,10 @@ impl Command {
         // All subcommands other than `serve` should return `Some`. Keep these
         // match arms sorted by the enum variant name.
         match self {
+            Command::Crash(args) => Some((
+                args.observability.log_format,
+                args.observability.log_filter.clone(),
+            )),
             Command::Serve(_) => None,
         }
     }

And here's what the help text looks like:

Crash the program

Usage: grapevine crash [OPTIONS]

Options:
      --log-format <LOG_FORMAT>
          Log format

          [default: full]

          Possible values:
          - pretty:  Multiple lines per event, includes all information
          - full:    One line per event, includes most information
          - compact: One line per event, includes less information
          - json:    One JSON object per line per event, includes most information

      --log-filter <LOG_FILTER>
          Log filter

          For information about the syntax, see here: <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>

          [default: info]

  -h, --help
          Print help (see a summary with '-h')

Merge request reports