clap_logflag/lib.rs
1//! The [clap-logflag](https://crates.io/crates/clap-logflag) library can be used to add a `--log` flag to
2//! [clap](https://crates.io/crates/clap) based command line applications that allows users to configure
3//! logging from the command line. It can log to stderr, files and syslog, powered by the
4//! [fern](https://crates.io/crates/fern) logging backend.
5//!
6//! # Examples
7//! ```bash
8//! # Log to a single destination
9//! $ ./your-cli --log syslog
10//! $ ./your-cli --log file:/path/to/file
11//!
12//! # Log to both stderr and a file
13//! $ ./your-cli --log stderr --log file:/path/to/file
14//!
15//! # Filter log levels. Debug (and higher) gets logged to stderr.
16//! # Info (and higher) additionally gets logged to a file.
17//! $ ./your-cli --log DEBUG:stderr --log INFO:file:/path/to/file
18//!
19//! # Disable logging
20//! $ ./your-cli --log none
21//!
22//! # Use default logging setup (defined by the application developer)
23//! $ ./your-cli
24//! ```
25//!
26//! # Setup
27//! To use clap-logflag, first add [clap-logflag](https://crates.io/crates/clap-logflag), [clap](https://crates.io/crates/clap) and [log](https://crates.io/crates/log) to your `Cargo.toml`.
28//!
29//! Then, add the [LogArgs](crate::clap::LogArgs) struct to your clap definition and initialize logging with it:
30//!
31// Note: This example is from [examples/simple_cli.rs]. We could include it here with `#[doc = include_str!(...)]`, but our `gen_readme.sh` script doesn't support that.
32//! ```rust
33//! use clap::Parser;
34//! use clap_logflag::LoggingConfig;
35//! use log::LevelFilter;
36//!
37//! #[derive(Debug, Parser)]
38//! struct CliArgs {
39//! // Use this to add the log flags to your application
40//! #[clap(flatten)]
41//! log: clap_logflag::LogArgs,
42//!
43//! // ... your other cli args ...
44//! }
45//!
46//! fn main() {
47//! let args = CliArgs::parse();
48//!
49//! // Initialize logging with the flags from clap
50//! clap_logflag::init_logging!(
51//! args.log
52//! // If no `--log` arguments are present, disable logging.
53//! // You can change this to define the default behavior,
54//! // see the "default_logging" example.
55//! .or_default(LoggingConfig::disabled()),
56//! // Any `--log` argument that doesn't define a level filter will use the
57//! // default level filter defined here, `Info` in this example.
58//! LevelFilter::Info,
59//! );
60//!
61//! // Issue some log messages
62//! log::trace!("Some trace log");
63//! log::debug!("Some debug log");
64//! log::info!("Some info log");
65//! log::warn!("Some warn log");
66//! log::error!("Some error log");
67//! }
68//! ```
69//!
70//! # Command Line Syntax
71//! See [LogArgs](crate::clap::LogArgs) for a detailed explanation of the syntax for the `--log` argument.
72//!
73//! # Log Format
74//! The format of the log messages uses an opinionated, reasonably pretty format by default. At the moment, this library does not offer a way to modify the format.
75//!
76//! ![Example log file][example_log.png]
77//!
78//! Log lines contain a UTC timestamp, the log level and an executable name.
79//!
80//! When the logging destination is stderr and stderr is a terminal, then the log level is colorized.
81//! When logging to a file, syslog or to a stderr that is redirected to a file, the log level is not colorized.
82//!
83//! # Help message
84//! [clap-logflag](https://crates.io/crates/clap-logflag) will automatically add a detailed help message to the `--help` output of your application,
85//! explaining the usage of the `--log` flag to your users.
86//! At the moment, this library does not offer a way to modify the help message.
87//!
88//! ```bash
89//! Usage: simple_cli [OPTIONS]
90//!
91//! Options:
92//! --log <LOG>
93//! Log definition consisting of an optional log level filter, and a log destination.
94//! You can define this argument multiple times for multiple log destinations.
95//!
96//! Logging can be disabled with `--log none`.
97//! If combined with other log definitions, those will take precedence and logging will not be disabled.
98//!
99//! The argument can be combined with a level filter to only log messages of a certain level or higher to that destination.
100//!
101//! Format: destination | level_filter:destination
102//! * level_filter = "ERROR" | "WARN" | "INFO" | "DEBUG" | "TRACE"
103//! * destination = "stderr" | "syslog" | "file:path" | "none"
104//!
105//! Examples:
106//! * `--log syslog`
107//! * `--log stderr`
108//! * `--log file:/path/to/file`
109//! * `--log INFO:stderr`
110//! * `--log DEBUG:file:/path/to/file`
111//! * `--log TRACE:syslog`
112//! * `--log none`
113//!
114//! -h, --help
115//! Print help (see a summary with '-h')
116//!
117//! ```
118//!
119
120#![cfg_attr(all(), doc = ::embed_doc_image::embed_image!("example_log.png", "example_log.png"))]
121#![allow(clippy::needless_doctest_main)]
122#![forbid(unsafe_code)]
123#![deny(missing_docs)]
124// We need to add explicit links because our `gen_readme.sh` script requires them.
125#![allow(rustdoc::redundant_explicit_links)]
126
127mod clap;
128mod config;
129mod fern;
130mod parser;
131
132pub use clap::LogArgs;
133pub use config::{LogDestination, LogDestinationConfig, LoggingConfig};
134pub use fern::_init_logging;