Skip to content

Commit 3a3473e

Browse files
committed
add config trait
1 parent 021e5b4 commit 3a3473e

4 files changed

Lines changed: 107 additions & 34 deletions

File tree

examples/ajj.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,29 @@
2323
//! http://localhost:8080/rpc
2424
//! ```
2525
use ajj::Router;
26-
use eyre::WrapErr;
2726
use init4_bin_base::{
28-
init,
2927
utils::{from_env::FromEnv, metrics::MetricsConfig, tracing::TracingConfig},
28+
Init4Config,
3029
};
3130

31+
#[derive(Debug, FromEnv)]
32+
struct Config {
33+
tracing: TracingConfig,
34+
metrics: MetricsConfig,
35+
}
36+
37+
impl Init4Config for Config {
38+
fn tracing(&self) -> &TracingConfig {
39+
&self.tracing
40+
}
41+
fn metrics(&self) -> &MetricsConfig {
42+
&self.metrics
43+
}
44+
}
45+
3246
#[tokio::main]
3347
async fn main() -> Result<(), Box<dyn std::error::Error>> {
34-
let tracing_config =
35-
TracingConfig::from_env().wrap_err("failed to get tracing config from environment")?;
36-
let metrics_config =
37-
MetricsConfig::from_env().wrap_err("failed to get metrics config from environment")?;
38-
let _guard = init(tracing_config, metrics_config);
48+
let _config_and_guard = init4_bin_base::init::<Config>()?;
3949

4050
let router = Router::<()>::new()
4151
.route("helloWorld", || async {

examples/build-helper.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
1-
use eyre::WrapErr;
21
use init4_bin_base::{
3-
init,
42
utils::{from_env::FromEnv, metrics::MetricsConfig, tracing::TracingConfig},
3+
Init4Config,
54
};
65
use std::sync::{atomic::AtomicBool, Arc};
76

7+
#[derive(Debug, FromEnv)]
8+
struct Config {
9+
tracing: TracingConfig,
10+
metrics: MetricsConfig,
11+
}
12+
13+
impl Init4Config for Config {
14+
fn tracing(&self) -> &TracingConfig {
15+
&self.tracing
16+
}
17+
fn metrics(&self) -> &MetricsConfig {
18+
&self.metrics
19+
}
20+
}
21+
822
fn main() -> eyre::Result<()> {
923
let term: Arc<AtomicBool> = Default::default();
1024

1125
let _ = signal_hook::flag::register(signal_hook::consts::SIGINT, Arc::clone(&term));
1226

13-
let tracing_config =
14-
TracingConfig::from_env().wrap_err("failed to get tracing config from environment")?;
15-
let metrics_config =
16-
MetricsConfig::from_env().wrap_err("failed to get metrics config from environment")?;
17-
init(tracing_config, metrics_config);
27+
let _config_and_guard = init4_bin_base::init::<Config>()?;
1828
Ok(())
1929
}

examples/otlp-export.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,29 @@
1010
use eyre::WrapErr;
1111
use init4_bin_base::{
1212
deps::tracing::{info, info_span},
13-
init,
1413
utils::{from_env::FromEnv, metrics::MetricsConfig, tracing::TracingConfig},
14+
Init4Config,
1515
};
1616
use std::sync::{
1717
atomic::{AtomicBool, Ordering},
1818
Arc,
1919
};
2020

21+
#[derive(Debug, FromEnv)]
22+
struct Config {
23+
tracing: TracingConfig,
24+
metrics: MetricsConfig,
25+
}
26+
27+
impl Init4Config for Config {
28+
fn tracing(&self) -> &TracingConfig {
29+
&self.tracing
30+
}
31+
fn metrics(&self) -> &MetricsConfig {
32+
&self.metrics
33+
}
34+
}
35+
2136
#[tokio::main]
2237
async fn main() -> eyre::Result<()> {
2338
let term: Arc<AtomicBool> = Default::default();
@@ -26,11 +41,7 @@ async fn main() -> eyre::Result<()> {
2641
signal_hook::flag::register(signal_hook::consts::SIGINT, Arc::clone(&term))
2742
.wrap_err("failed to register SIGINT hook")?;
2843

29-
let tracing_config =
30-
TracingConfig::from_env().wrap_err("failed to get tracing config from environment")?;
31-
let metrics_config =
32-
MetricsConfig::from_env().wrap_err("failed to get metrics config from environment")?;
33-
let _guard = init(tracing_config, metrics_config);
44+
let _config_and_guard = init4_bin_base::init::<Config>()?;
3445
let mut counter = 0;
3546
let _outer = info_span!("outer span").entered();
3647

src/lib.rs

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
#![deny(unused_must_use, rust_2018_idioms)]
1313
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
1414

15-
use crate::utils::{metrics::MetricsConfig, otlp::OtelGuard, tracing::TracingConfig};
15+
use crate::utils::{
16+
from_env::{FromEnv, FromEnvErr},
17+
metrics::MetricsConfig,
18+
otlp::OtelGuard,
19+
tracing::TracingConfig,
20+
};
1621

1722
#[cfg(feature = "perms")]
1823
/// Permissioning and authorization utilities for Signet builders.
@@ -100,34 +105,71 @@ pub fn init4() -> Option<OtelGuard> {
100105
guard
101106
}
102107

103-
/// Init metrics and tracing, including OTLP if enabled.
108+
/// Trait for config types that can be used with [`init`].
109+
///
110+
/// Implementors must provide access to [`TracingConfig`] and [`MetricsConfig`],
111+
/// and must be loadable from the environment via [`FromEnv`].
112+
///
113+
/// # Example
114+
///
115+
/// ```ignore
116+
/// #[derive(Debug, FromEnv)]
117+
/// pub struct MyConfig {
118+
/// pub tracing: TracingConfig,
119+
/// pub metrics: MetricsConfig,
120+
/// #[from_env(var = "MY_THING", desc = "some app-specific value")]
121+
/// pub my_thing: String,
122+
/// }
123+
///
124+
/// impl Init4Config for MyConfig {
125+
/// fn tracing(&self) -> &TracingConfig { &self.tracing }
126+
/// fn metrics(&self) -> &MetricsConfig { &self.metrics }
127+
/// }
128+
/// ```
129+
pub trait Init4Config: FromEnv {
130+
/// Get the tracing configuration.
131+
fn tracing(&self) -> &TracingConfig;
132+
/// Get the metrics configuration.
133+
fn metrics(&self) -> &MetricsConfig;
134+
}
135+
136+
/// The result of [`init`]: the loaded config and an optional OTLP guard.
137+
///
138+
/// The [`OtelGuard`] (if present) must be kept alive for the lifetime of the
139+
/// program to ensure the OTLP exporter continues to send data.
140+
#[derive(Debug)]
141+
pub struct ConfigAndGuard<T> {
142+
/// The loaded configuration.
143+
pub config: T,
144+
/// The OTLP guard, if OTLP was enabled.
145+
pub guard: Option<OtelGuard>,
146+
}
147+
148+
/// Load config from the environment and initialize metrics and tracing.
104149
///
105150
/// This will perform the following:
106-
/// - Read environment configuration for tracing
151+
/// - Load `T` from environment variables via [`FromEnv`]
152+
/// - Read tracing configuration from the loaded config
107153
/// - Determine whether to enable OTLP
108154
/// - Install a global tracing subscriber, using the OTLP provider if enabled
109-
/// - Read environment configuration for metrics
155+
/// - Read metrics configuration from the loaded config
110156
/// - Install a global metrics recorder and serve it over HTTP on 0.0.0.0
111157
///
112158
/// See [`init_tracing`] and [`init_metrics`] for more
113159
/// details on specific actions taken and env vars read.
114160
///
115-
/// # Returns
116-
///
117-
/// The OpenTelemetry guard, if OTLP is enabled. This guard should be kept alive
118-
/// for the lifetime of the program to ensure the exporter continues to send
119-
/// data to the remote API.
120-
///
121161
/// [`init_tracing`]: utils::tracing::init_tracing
122162
/// [`init_metrics`]: utils::metrics::init_metrics
123-
pub fn init(tracing_config: TracingConfig, metrics_config: MetricsConfig) -> Option<OtelGuard> {
124-
let guard = utils::tracing::init_tracing_with_config(tracing_config);
125-
utils::metrics::init_metrics_with_config(metrics_config);
163+
pub fn init<T: Init4Config>() -> Result<ConfigAndGuard<T>, FromEnvErr> {
164+
let config = T::from_env()?;
165+
166+
let guard = utils::tracing::init_tracing_with_config(config.tracing().clone());
167+
utils::metrics::init_metrics_with_config(*config.metrics());
126168

127169
// This will install the AWS-LC-Rust TLS provider for rustls, if no other
128170
// provider has been installed yet
129171
#[cfg(feature = "rustls")]
130172
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
131173

132-
guard
174+
Ok(ConfigAndGuard { config, guard })
133175
}

0 commit comments

Comments
 (0)