let log t =
  let open Log in
  let item name l = s name % s ": " % l in
  let toplevel l = separate n l in
  let sublist l = n % indent (separate n l) in
  let common =
    sublist [
      item "Debug-level" (i t.debug_level);
      item "Plugins" (match t.plugins with
        | [] -> s "None"
        | more -> sublist (List.map more ~f:(function
          | `Compiled path -> item "Compiled"  (quote path)
          | `OCamlfind pack -> item "OCamlfind package" (quote pack))))
    ] in
  let ui t =
    sublist [
      item "Colors"
        (if t.with_color then s "with colors" else s "without colors");
      item "Get-key"
        (if t.with_cbreak then s "uses `cbreak`" else s "classic readline");
      item "Explorer"
        (let { request_targets_ids; targets_per_page; targets_to_prefetch } =
           t.explorer in
         sublist [
           item "Default request"
             (match request_targets_ids with
             | `Younger_than (`Days days) ->
               s "Targets younger than " % f days % s " days"
             | `All -> s "All targets");
           item "Targets-per-page" (i targets_per_page);
           item "Targets-to-prefectch" (i targets_to_prefetch);
         ]);
    ] in
  let engine { database_parameters; turn_unix_ssh_failure_into_target_failure;
               host_timeout_upper_bound; maximum_successive_attempts } =
    sublist [
      item "Database" (quote database_parameters);
      item "Unix-failure"
        ((if turn_unix_ssh_failure_into_target_failure
          then s "turns"
          else s "does not turn") % s " into target failure");
      item "Host-timeout-upper-bound"
        (option f host_timeout_upper_bound);
      item "Maximum-successive-attempts" (i maximum_successive_attempts);
    ] in
  let authorized_tokens = function
  | `Path path -> s "Path: " % quote path
  | `Inline (name, value) ->
    s "Inline " % parens (s "Name: " % s name % s ", Value: " % quote value)
  in
  match t.mode with
  | `Standalone {standalone_engine; standalone_ui} ->
    toplevel [
      item "Mode" (s "Standalone");
      item "Engine" (engine standalone_engine);
      item "UI" (ui standalone_ui);
      item "Misc" common;
    ]
  | `Client client ->
    toplevel [
      item "Mode" (s "Client");
      item "Connection" (quote client.connection);
      item "Auth-token" (quote client.token);
      item "UI" (ui client.client_ui);
      item "Misc" common;
    ]
  | `Server srv ->
    toplevel [
      item "Mode" (s "Server");
      item "Engine" (engine srv.server_engine);
      item "UI" (ui srv.server_ui);
      item "HTTP-server" (sublist [
          item "Authorized tokens"
            (sublist (List.map ~f:authorized_tokens srv.authorized_tokens));
          item "Daemonize" (OCaml.bool srv.daemon);
          item "Command Pipe" (OCaml.option quote srv.command_pipe);
          item "Log-path" (OCaml.option quote srv.log_path);
          item "Return-error-messages" (OCaml.bool srv.return_error_messages);
          item "Listen"
            (let `Tls (cert, key, port) = srv.listen_to in
             sublist [
               item "Port" (i port);
               item "Certificate" (quote cert);
               item "Key" (quote key);
             ])
        ]);
      item "Misc" common;
    ]