Byre
Byre is a toolbox for bootstrapping services quickly. Providing tracing, logging, configuration file generation and loading, and command line argument parsing.
Byre leans on tracing, opentelemetry, clap, doku, tokio and others.
Byre is a rough fork of Cloudflare Foundations with some bits copied directly and others used as inspiration. Byre differs from Foundations in the ecosystems that it draws from.
Quick Start
Add byre and tokio to your Cargo.toml:
[]
= "0.3"
= "0.21"
= "1"
= "1"
= { = "4", = ["derive"] } # Only if defining custom CLI Arguments
Application Config Generation
Byre is opinionated about application configuration. Configuration generation MUST be available by running the application. The clap crate is used for the cli argument parsing and help display:
Config generation uses Doku. The following Settings struct will produce the toml below.
use PathBuf;
use Document;
use Deserialize;
/// Data Archive Settings
The generated toml config file:
# App Settings
[]
# Port to listen on for gRPC status requests
= 8080
# Hostname to listen on for gRPC status requests
= "localhost"
# Directory where the application databases are located
= "/var/db/reverb"
[]
# Optional
= "http://localhost:4317"
[]
= "debug,yourcrate=trace"
= "warn,yourcrate=debug"
# Optional
= "http://localhost:4317"
[]
# Optional
= "http://localhost:4318/v1/metrics"
As you can see, the doc comments are written into the config, and the Doku example becomes the value.
Application start-up
Parsing CLI arguments, loading app config file, and setting up telemetry is done in approximately 4 lines (excluding the structs for the config), making it simple and consistent to use.
use Document;
use Deserialize;
async
Config overrides from the environment
Environment variables override the values parsed from the config file. In this example "APP_" is the common prefix. If you do not want a prefix, pass an empty string ("").
let Some = try_new? else ;
Overriding values in a nested structure is possible. For example, if we wanted to override the application.listen_port you would set an environment variable APP_APPLICATION__LISTEN_PORT. Notice the double underscore (__), it is used in place of a period (.).
OpenTelemetry
Setting up the connection to OpenTelemetry systems is done by calling init:
let _telemetry = init?;
Logging, Tracing, and Metrics are available. To disable sending traces, logs, or metrics you can remove the optional endpoint. If you want to disable console logs set console_level to "off".
[]
# Optional
= "http://localhost:4317"
[]
= "debug,yourcrate=trace"
= "warn,yourcrate=debug"
# Optional
= "http://localhost:4317"
[]
# Optional
= "http://localhost:4318/v1/metrics"
Log Level Filtering
The otel_level filter is applied first to the tracing subscriber, then console_level filters what gets printed to the console. This means console_level can only show logs that pass through otel_level. For example, if otel_level is warn, then console_level can only display warn, error, or be set to off.
To prevent infinite telemetry loops, logs from the following crates are automatically filtered out and will not be sent to OpenTelemetry endpoints: hyper, opentelemetry, tonic, h2, and reqwest.
Examples
See the full example in the source tree for a complete working application.