pred
This commit is contained in:
parent
3a6d29b4cb
commit
7928ec9588
5 changed files with 177 additions and 0 deletions
32
Cargo.toml
Normal file
32
Cargo.toml
Normal file
|
@ -0,0 +1,32 @@
|
|||
[package]
|
||||
name = "pred"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.6.20", features = ["macros", "headers"] }
|
||||
reqwest = "0.11"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
select = "0.5"
|
||||
dotenvy = "~0"
|
||||
cfg-if = "~1"
|
||||
|
||||
# -- Tracing
|
||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json", "std"], optional = true }
|
||||
tracing = { version = "~0", features = ["log", "log-always"] }
|
||||
opentelemetry = {version ="0.20.0", features = ["rt-tokio"], optional = true }
|
||||
opentelemetry-otlp = { version = "0.13.0", optional = true }
|
||||
tracing-opentelemetry = { version = "0.21.0", optional = true }
|
||||
tracing-log = { version = "~0", optional = true, features = ["env_logger"] }
|
||||
tracing-bunyan-formatter = { version = "0.3.9", optional = true }
|
||||
|
||||
# Misc
|
||||
thiserror = "~1"
|
||||
log = "~0"
|
||||
|
||||
[features]
|
||||
default = ["tracing", "bunyan"]
|
||||
tracing = ["tracing-log", "tracing-subscriber", "tracing-opentelemetry", "opentelemetry", "opentelemetry-otlp"]
|
||||
bunyan = ["tracing-bunyan-formatter"]
|
29
src/error.rs
Normal file
29
src/error.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use opentelemetry::trace::TraceError;
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
TraceErr(String),
|
||||
SetGlobalDefaultErr(String)
|
||||
}
|
||||
|
||||
impl From<tracing::subscriber::SetGlobalDefaultError> for Error {
|
||||
fn from(_: tracing::subscriber::SetGlobalDefaultError) -> Self {
|
||||
Error::SetGlobalDefaultErr("Set global err".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TraceError> for Error {
|
||||
fn from(_: TraceError) -> Self {
|
||||
Error::TraceErr("Trace err".to_string())
|
||||
}
|
||||
}
|
||||
impl core::fmt::Display for Error {
|
||||
fn fmt(
|
||||
&self,
|
||||
fmt: &mut core::fmt::Formatter,
|
||||
) -> core::result::Result<(), core::fmt::Error> {
|
||||
write!(fmt, "{self:?}")
|
||||
}
|
||||
}
|
47
src/main.rs
Normal file
47
src/main.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
// use crate::observability;
|
||||
|
||||
mod observability;
|
||||
mod error;
|
||||
use axum::{response::Html, routing::get, Router};
|
||||
use tracing::debug;
|
||||
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> error::Result<()> {
|
||||
|
||||
// Set up a tracing subscriber with JSON formatting
|
||||
tracing_log::LogTracer::builder()
|
||||
.ignore_crate("sqlx")
|
||||
.with_max_level(log::LevelFilter::Info)
|
||||
.init()
|
||||
.expect("could not initialize log tracer");
|
||||
|
||||
match observability::configure_observability().await {
|
||||
Ok(_) => {
|
||||
tracing::debug!("tracing configured");
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!("error configuring tracing: {}", err);
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
|
||||
// build our application with a route
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
// run it
|
||||
debug!("listening on 0.0.0.0:3000");
|
||||
|
||||
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.expect("server failed");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
async fn handler() -> Html<&'static str> {
|
||||
Html("<h1>Hello, World!</h1>")
|
||||
}
|
1
src/mod.rs
Normal file
1
src/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod observability;
|
68
src/observability.rs
Executable file
68
src/observability.rs
Executable file
|
@ -0,0 +1,68 @@
|
|||
use opentelemetry_otlp::WithExportConfig;
|
||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
|
||||
use crate::error::Result;
|
||||
use tracing::debug;
|
||||
|
||||
const OTEL_EXPORTER_OTLP_ENDPOINT_ENV_VAR: &str = "OTEL_EXPORTER_OTLP_ENDPOINT";
|
||||
const OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT: &str = "http://localhost:4317";
|
||||
|
||||
const OBSERVABILITY_SERVICE_NAME_ENV_VAR: &str = "OBSERVABILITY_SERVICE_NAME";
|
||||
const OBSERVABILITY_SERVICE_NAME_DEFAULT: &str = "pred";
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn configure_observability() -> Result<()> {
|
||||
debug!("{:<12} - configure_observability", "fn");
|
||||
|
||||
let otel_exporter_endpoint =
|
||||
dotenvy::var(OTEL_EXPORTER_OTLP_ENDPOINT_ENV_VAR).unwrap_or_else(|_| {
|
||||
tracing::warn!(
|
||||
"{} Env var not set, using default",
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT
|
||||
);
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT_DEFAULT.to_string()
|
||||
});
|
||||
|
||||
let observability_service_name = dotenvy::var(OBSERVABILITY_SERVICE_NAME_ENV_VAR)
|
||||
.unwrap_or_else(|_| OBSERVABILITY_SERVICE_NAME_DEFAULT.to_string());
|
||||
|
||||
let tracer = opentelemetry_otlp::new_pipeline()
|
||||
.tracing()
|
||||
.with_exporter(
|
||||
opentelemetry_otlp::new_exporter()
|
||||
.tonic()
|
||||
.with_endpoint(otel_exporter_endpoint),
|
||||
)
|
||||
.with_trace_config(opentelemetry::sdk::trace::config().with_resource(
|
||||
opentelemetry::sdk::Resource::new(vec![opentelemetry::KeyValue::new(
|
||||
"service.name",
|
||||
observability_service_name.clone(),
|
||||
)]),
|
||||
))
|
||||
.install_batch(opentelemetry::runtime::Tokio)?;
|
||||
|
||||
// Create a tracing layer with the configured tracer
|
||||
let telemetry_layer = tracing_opentelemetry::layer().with_tracer(tracer);
|
||||
|
||||
let filter = tracing_subscriber::EnvFilter::from_default_env();
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature="bunyan")] {
|
||||
// Create a new formatting layer to print bunyan formatted logs to stdout, pipe into bunyan to view
|
||||
let formatting_layer = BunyanFormattingLayer::new(observability_service_name, std::io::stdout);
|
||||
let subscriber = tracing_subscriber::Registry::default()
|
||||
.with(filter)
|
||||
.with(telemetry_layer)
|
||||
.with(JsonStorageLayer)
|
||||
.with(formatting_layer);
|
||||
} else {
|
||||
let subscriber = tracing_subscriber::Registry::default()
|
||||
.with_filter(filter)
|
||||
.with_writer(std::io::stdout)
|
||||
.with(telemetry_layer);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(tracing::subscriber::set_global_default(subscriber)?)
|
||||
}
|
||||
|
Loading…
Reference in a new issue