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;