rskit-logging
Production-ready structured logging built on the tracing ecosystem.
Features
- Structured JSON / pretty console output
- Sensitive data masking (on by default)
- Rate-based log sampling (burst + thereafter)
- Per-module log level overrides via
EnvFilter - OpenTelemetry Logs bridge (OTLP export, behind
otlpfeature flag) - Unified log schema (consistent across gokit, pykit, rskit)
- Drop-based guard ensures all buffered logs are flushed on shutdown
RUST_LOGenv-filter support
Installation
[]
= "0.1.0-alpha.1"
# With OTLP export support
= { = "0.1.0-alpha.1", = ["otlp"] }
Quick Start
use ;
use LoggingConfig;
Configuration
rskit-logging integrates with rskit-config for configuration-driven setup. All logging options come from LoggingConfig:
logging:
level: info # trace | debug | info | warn | error
format: json # json | console
Init Functions
| Function | Description |
|---|---|
init_logging(cfg) -> LoggingResult<LoggingGuard> |
Basic init from LoggingConfig |
init_logging_env() |
Init from RUST_LOG only (no config needed) |
init_logging_with_masking(cfg, masking_cfg) -> LoggingResult<LoggingGuard> |
Sensitive data masking |
init_logging_with_options(cfg, sampling, module_levels, masking) -> LoggingResult<LoggingGuard> |
Sampling + module overrides |
init_logging_full(setup) -> LoggingResult<LoggingGuard> |
Full init with all features (requires otlp feature) |
Full Configuration Example
use HashMap;
use ;
use OtlpConfig; // requires "otlp" feature
use LoggingConfig;
Masking
Masking is enabled by default in MaskingConfig. The DefaultMasker operates at the output layer via MaskingMakeWriter, redacting sensitive data from complete log lines before they reach any sink.
Setup
use ;
use LoggingConfig;
let cfg = default;
let masking = default; // enabled: true
let _guard = init_logging_with_masking?;
// Sensitive fields are now redacted in output
info!;
// output: password=[REDACTED]
Default Masked Fields
| # | Field Name | Description |
|---|---|---|
| 1 | password |
User passwords |
| 2 | secret |
Generic secrets |
| 3 | token |
Generic tokens |
| 4 | api_key |
API keys |
| 5 | apikey |
API keys (alternate) |
| 6 | api-key |
API keys (hyphenated) |
| 7 | authorization |
Auth headers |
| 8 | auth_token |
Authentication tokens |
| 9 | access_token |
OAuth access tokens |
| 10 | refresh_token |
OAuth refresh tokens |
| 11 | private_key |
Private keys |
| 12 | ssn |
Social Security numbers |
| 13 | credit_card |
Credit card numbers |
| 14 | card_number |
Card numbers (alternate) |
| 15 | cvv |
Card verification values |
| 16 | pin |
Personal identification numbers |
Value Patterns
These patterns detect sensitive data regardless of field name:
| # | Pattern | Example Input | Masked Output |
|---|---|---|---|
| 1 | Bearer token | Bearer abc123def |
Bearer [REDACTED] |
| 2 | JWT | eyJhbGci...payload...sig |
[JWT_REDACTED] |
| 3 | AWS Access Key | AKIAIOSFODNN7EXAMPLE |
[AWS_KEY_REDACTED] |
| 4 | Credit Card | 4111-1111-1111-1234 |
****-****-****-1234 |
| 5 | SSN | 123-45-6789 |
***-**-**** |
| 6 | user@example.com |
***@***.*** |
|
| 7 | Hex Secret (32+) | a1b2c3d4e5f6... (32+ hex chars) |
[HEX_REDACTED] |
Adding Custom Fields and Patterns
let masking = MaskingConfig ;
let _guard = init_logging_with_masking?;
Output-Level Masking
Unlike gokit and pykit (which mask at the field level), rskit masks at the output writer level. The MaskingMakeWriter wraps the underlying io::Write and applies both field-name regex patterns (matching JSON "field":"value" and text field=value formats) and value-pattern regexes to complete log lines. This ensures nothing leaks regardless of how fields are formatted.
use Arc;
use ;
let masker: = new;
let writer = new;
Sampling
Sampling reduces log volume in high-throughput services. When enabled, each log level gets an independent counter per one-second window:
- Burst — the first
initial_rateevents per second per level pass through unconditionally. - Thereafter — after the burst, only every
thereafter_rate-th event is kept.
use SamplingConfig;
let sampling = SamplingConfig ;
When to use: Enable sampling on hot-path services producing thousands of log events per second. Leave disabled for low-volume services or during debugging.
The SamplingLayer implements tracing_subscriber::Layer and uses event_enabled() to drop excess events. Counters are protected by parking_lot::Mutex for minimal contention.
Module Levels
Override the global log level for specific modules using tracing_subscriber::EnvFilter directives. Useful for silencing noisy dependencies or enabling debug output for a single crate.
use HashMap;
use init_logging_with_options;
use LoggingConfig;
let cfg = default;
let mut module_levels = new;
module_levels.insert;
module_levels.insert;
module_levels.insert;
let _guard = init_logging_with_options?;
// Generates filter: "info,hyper=error,rdkafka=off,sqlx=warn"
The build_env_filter() function merges the base level with per-module overrides into a single EnvFilter. When RUST_LOG is set, it takes precedence over config.
use build_env_filter;
let filter = build_env_filter;
// Equivalent to: RUST_LOG="info,sqlx=warn,rdkafka=off,hyper=error"
OTLP Export
The OpenTelemetry Logs bridge sends tracing events to an OTLP collector. It uses opentelemetry-appender-tracing to convert every tracing::Event into an OTel log record.
Feature gate: OTLP requires the
otlpcargo feature.
[]
= { = "0.1.0-alpha.1", = ["otlp"] }
Setup
use OtlpConfig;
let otlp = OtlpConfig ;
Full Init with OTLP
let setup = new
.with_sampling
.with_module_levels
.with_otlp;
let _guard = init_logging_full?;
Subscriber Stack
When using init_logging_full, the subscriber layers are composed as:
EnvFilter— base level + per-module overridesSamplingLayer(optional) — rate-based event sampling- Format layer — JSON or console output
OpenTelemetryTracingBridge(optional) — OTLP export
Graceful Shutdown
The LoggingGuard must be held for the lifetime of your service. When dropped, it restores the previous subscriber. When OTLP is enabled, the OtlpProvider::shutdown() method flushes pending records:
Unified Schema
All three kits (gokit, pykit, rskit) share the same structured field names, defined in rskit_logging::fields::names:
| Field | Constant | Description |
|---|---|---|
service |
fields::names::SERVICE |
Service name |
environment |
fields::names::ENVIRONMENT |
Deployment environment |
version |
fields::names::VERSION |
Service version |
component |
fields::names::COMPONENT |
Logical component |
trace_id |
fields::names::TRACE_ID |
Distributed trace ID |
span_id |
fields::names::SPAN_ID |
Span ID within trace |
correlation_id |
fields::names::CORRELATION_ID |
Cross-service correlation |
user_id |
fields::names::USER_ID |
User identifier |
request_id |
fields::names::REQUEST_ID |
HTTP request identifier |
duration_ms |
fields::names::DURATION_MS |
Duration in milliseconds |
Using Field Constants
use *;
info!;
Custom Masker
Implement the Masker trait to provide your own masking logic:
use Cow;
use Masker;
;
Use with MaskingMakeWriter:
use Arc;
use MaskingMakeWriter;
let masker: = new;
let writer = new;
Convenience Re-exports
rskit-logging re-exports core tracing macros for convenience:
use ;
API Reference
| Function / Type | Description |
|---|---|
init_logging(cfg) -> LoggingResult<LoggingGuard> |
Basic subscriber init |
init_logging_env() |
Init from RUST_LOG only |
init_logging_with_masking(cfg, masking) -> LoggingResult<LoggingGuard> |
Output masking |
init_logging_with_options(cfg, sampling, modules, masking) -> LoggingResult<LoggingGuard> |
Sampling + module levels |
init_logging_full(setup) -> LoggingResult<LoggingGuard> |
Full init with OTLP (otlp feature) |
LoggingGuard |
Drop guard — hold for program lifetime |
MaskingConfig |
Masking configuration |
DefaultMasker |
Built-in masker with PII/secret patterns |
Masker (trait) |
Interface for custom maskers |
MaskingMakeWriter |
Writer wrapper that masks output |
SamplingConfig |
Sampling configuration |
SamplingLayer |
Tracing layer for rate-based sampling |
ModuleLevelsConfig |
Per-module level overrides |
build_env_filter(level, modules) |
Build EnvFilter from config |
OtlpConfig |
OTLP export configuration (otlp feature) |
OtlpProvider |
OTel LoggerProvider manager (otlp feature) |