1#[macro_use]
2extern crate shadow_rs;
3
4use pretty_assertions::{assert_eq, assert_ne};
5use tap::prelude::*;
6use itertools::Itertools;
7use eyre::{WrapErr, Result};
8
9
10pub fn print_version() {
11 shadow!(build);
12 eprintln!("{} {}", build::PROJECT_NAME, build::PKG_VERSION);
13 eprintln!(" > build_time: {}", build::BUILD_TIME_2822);
14 eprintln!(" > build_env: {} on {}, channel: {}",
15 build::RUST_VERSION, build::BUILD_OS, build::BUILD_RUST_CHANNEL);
16 eprintln!(" > branch: {} tag: {} commit: {}", build::BRANCH, build::TAG, build::SHORT_COMMIT);
17}
18
19
20pub static LOGGING_GUARD: once_cell::sync::Lazy<LoggingGuard> = once_cell::sync::Lazy::new(|| {
21 setup_logging().unwrap()
22});
23
24pub struct LoggingGuard {
25 sentry: Option<sentry::ClientInitGuard>,
26}
27
28pub fn setup_failfast() {
30 use std::panic;
31 use std::process;
32 let orig_hook = panic::take_hook();
33 panic::set_hook(Box::new(move |panic_info| {
34 orig_hook(panic_info);
36 process::exit(1);
37 }));
38}
39
40pub fn setup_logging() -> Result<LoggingGuard> {
41 use tracing_subscriber::layer::SubscriberExt;
42 use tracing_subscriber::util::SubscriberInitExt;
43 use metrics_exporter_prometheus::PrometheusBuilder;
44 use std::net::SocketAddr;
45 color_eyre::install().wrap_err("Failed to initialize `color_eyre`.")?;
46 let mut layers = tracing_subscriber::registry()
47 .with(tracing_subscriber::EnvFilter::from_env("LOG_LEVEL"))
48 .with(tracing_subscriber::fmt::layer()
49 .with_line_number(true)
50 .with_file(true)
51 .with_thread_ids(true));
52 let mut builder = PrometheusBuilder::new();
53 if let Ok(url) = std::env::var("PROMETHEUS_PUSH_GATEWAY_URL") {
54 builder = builder.with_push_gateway(
55 url, std::time::Duration::from_secs(10)
56 ).expect("cannot start prometheus push gateway");
57 }
58 if let Ok(_) = std::env::var("ENABLE_PROMETHEUS_EXPORTER") {
59 builder = builder.with_http_listener(SocketAddr::from(([0, 0, 0, 0], 9000)));
60 }
61 builder.install().wrap_err("Failed to initialize prometheus exporter.")?;
62 let guard = LoggingGuard {
63 sentry: match std::env::var("SENTRY_URL") {
64 Ok(ref url) => {
65 let guard = Some(sentry::init(
66 (url.as_str(), sentry::ClientOptions {
67 release: sentry::release_name!(),
68 ..Default::default()
69 })));
70 tracing::info!("sentry integration enabled");
71 let layers = layers.with(sentry_tracing::layer());
72 layers.init();
73 guard
74 }
75 Err(_) => {
76 layers.init();
77 None
78 }
79 }
80 };
81 return Ok(guard);
82}
83
84
85