use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::time::Duration;
use tracing_subscriber::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DiagnosticsConfig {
bind: String,
publish_interval: Option<Duration>,
recording_path: Option<PathBuf>,
}
impl DiagnosticsConfig {
pub fn new(bind: impl Into<String>) -> Self {
Self {
bind: bind.into(),
publish_interval: None,
recording_path: None,
}
}
pub fn with_publish_interval(mut self, interval: Duration) -> Self {
self.publish_interval = Some(interval);
self
}
pub fn with_recording_path(mut self, path: impl Into<PathBuf>) -> Self {
self.recording_path = Some(path.into());
self
}
pub fn bind(&self) -> &str {
&self.bind
}
pub fn publish_interval(&self) -> Option<Duration> {
self.publish_interval
}
pub fn recording_path(&self) -> Option<&Path> {
self.recording_path.as_deref()
}
pub fn install(&self) -> Result<(), DiagnosticsInstallError> {
let bind = self
.bind
.parse::<SocketAddr>()
.map_err(|error| DiagnosticsInstallError::InvalidBind(error.to_string()))?;
let mut builder = console_subscriber::Builder::default()
.with_default_env()
.server_addr(bind);
if let Some(interval) = self.publish_interval {
builder = builder.publish_interval(interval);
}
if let Some(path) = &self.recording_path {
builder = builder.recording_path(path);
}
let layer = std::panic::catch_unwind(|| builder.spawn())
.map_err(|_| DiagnosticsInstallError::BackendInstrumentationRequired)?;
tracing_subscriber::registry()
.with(layer)
.try_init()
.map_err(|error| DiagnosticsInstallError::Subscriber(error.to_string()))
}
}
impl Default for DiagnosticsConfig {
fn default() -> Self {
Self::new("127.0.0.1:6669")
}
}
#[derive(Debug, thiserror::Error)]
pub enum DiagnosticsInstallError {
#[error("invalid async diagnostics bind address: {0}")]
InvalidBind(String),
#[error("the current async backend requires RUSTFLAGS=\"--cfg tokio_unstable\" for task instrumentation")]
BackendInstrumentationRequired,
#[error("could not install the async diagnostics subscriber: {0}")]
Subscriber(String),
}