This crate provides a reusable basis for developing applications with strong, built-in observability.
Note: This crate is intended for internal use within applications developed by Silitics. It is open-source and you are free to use it for whatever purpose you see fit, however, we will not accept any contributions other than bug fixes.
At Silitics, we consider observability a fundamental aspect of building reliable and
maintainable systems. This crate builds upon the well-established [tracing]
ecosystem, which we rely on for instrumentation and structured logging. On top of
[tracing], this crate provides a reusable basis for configuration and logging
initialization—reducing boilerplate, promoting best practices, and supporting useful
log output for users at the console and the integration with observability platforms.
Most functionality provided by this crate is gated by feature flags and can be
configured via environment variables at runtime.
The [Initializer] is the primary interface for setting everything up. Here is a
minimal example:
new.init;
In this example, the string APP is an application-defined prefix for configuration
environment variables. In the following, we will use APP as a placeholder for the
application-defined prefix defined via the [Initializer].
Additional configurations can be [applied][Initializer::apply] to the [Initializer]
via the sealed [Configuration] trait.
Upon initialization, the [Initializer] returns a [FinalizeGuard] which must be
kept around for the lifetime of the application. When dropped, this guard will cleanup
resources and flush internal buffers, e.g., containing logs.
Logging to Stderr
Logging to stderr is enabled by default for informational events. Applications should
use informational events to communicate status information to the user. Applications
should not use [println!] or [eprintln!] for that purpose.
Logging to stderr can be configured via the APP_LOG environment variable using
[EnvFilter] directives.
Logging to stderr produces colorful output using ANSI codes in accordance with the
clicolors specification.
The environment variable APP_LOG_FORMAT can be set to one of the following log
formats:
compact: Compact format for everyday use (the default).full: Verbose format with additional information like timestamps and span attributes.
In addition, an application may make logging to stderr configurable via standardized
command line arguments. Command line arguments have the advantage that they are
discoverable by users by calling the application with --help. To standardize the
respective arguments, this crate provides pre-made integrations with clap.
Here is an example:
# use clap4 as clap;
# use Parser;
use LoggingArgs;
let args = parse;
new.apply.init;
Note that we consider adding arguments with the prefix --log- a non-breaking
change.
OpenTelemetry
When the otlp feature is enabled, this crate supports exporting traces via OTLP to
monitoring and observability tools. While primarily intended for monitoring cloud
applications, this can also be useful for local debugging.
At runtime, OTLP export is enabled and configured via the APP_LOG_OTLP environment
variable using [EnvFilter] directives. Additional environment variables, e.g., for
the configuration of OTLP endpoints and headers, follow the OpenTelemetry standard.
At the moment, trace export is limited to the http/protobuf protocol.
Use the variable OTEL_RESOURCE_ATTRIBUTES to set OpenTelemetry resource attributes.
For instance:
OTEL_RESOURCE_ATTRIBUTES="service.name=my-app,service.instance.id=my-app-instance-1"
For local development and debugging, you can run a Jaeger instance as follows:
It then suffices to set APP_LOG_OTLP=info to send traces to Jaeger. To view the
traces, go to http://localhost:16686.
Feature Flags
This crate has the following feature flags:
clap4: Support for [clap][clap4](version 4) CLI arguments.otlp: Support for exporting traces via OTLP.