Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ resolver = "2"

[workspace.package]
edition = "2021"
version = "0.3.17"
version = "0.3.18"


description = "Tower is the best way to host Python data apps in production"
rust-version = "1.77"
Expand Down
80 changes: 7 additions & 73 deletions crates/tower-telemetry/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,13 @@
pub mod logging;
pub mod context;

pub use context::Context;

/// reexport tracing to make sure that it gets included everywhere.
pub use tracing;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{registry::Registry, layer::Layer, fmt, EnvFilter};

/// LogLevel describes the various log levels that can be used in the application.
pub enum LogLevel {
Debug,
Info,
Warn,
Error,
}

impl AsRef<str> for LogLevel {
fn as_ref(&self) -> &str {
match self {
LogLevel::Debug => "debug",
LogLevel::Info => "info",
LogLevel::Warn => "warn",
LogLevel::Error => "error",
}
}
}

pub enum LogDestination {
Stdout,
File(String),
}

pub enum LogFormat {
Plain,
Json,
}

type BoxedFmtLayer = Box<dyn Layer<Registry> + Send + Sync>;

fn create_fmt_layer(format: LogFormat, destination: LogDestination) -> BoxedFmtLayer {
match destination {
LogDestination::Stdout => {
match format {
LogFormat::Plain => Box::new(fmt::layer().event_format(fmt::format().pretty())),
LogFormat::Json => Box::new(fmt::layer().event_format(fmt::format().json())),
}
}
LogDestination::File(path) => {
let file_appender = tracing_appender::rolling::daily(".", path);
match format {
LogFormat::Plain => {
Box::new(
fmt::layer()
.event_format(fmt::format().pretty())
.with_writer(file_appender)
)
}
LogFormat::Json => {
Box::new(
fmt::layer()
.event_format(fmt::format().json())
.with_writer(file_appender)
)
}
}
}
}
}

pub fn enable_logging(level: LogLevel, format: LogFormat, destination: LogDestination) {
let fmt_layer = create_fmt_layer(format, destination);
let filter = EnvFilter::new(level);
let subscriber = tracing_subscriber::registry().with(fmt_layer).with(filter);

tracing::subscriber::set_global_default(subscriber)
.expect("Failed to set global default subscriber");
}
pub use context::Context;
pub use logging::{
LogFormat,
LogDestination,
LogLevel,
enable_logging
};
106 changes: 105 additions & 1 deletion crates/tower-telemetry/src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
use tracing_subscriber::prelude::*;
use tracing_subscriber::{
registry::Registry,
layer::Layer,
filter::EnvFilter,
fmt,
};

#[macro_export]
macro_rules! event_with_level {
// With context
($level:expr, ctx: $ctx:expr, $fmt:expr, $($arg:tt)+) => {
if let Some(runid) = &$ctx.runid {
$crate::tracing::event!($level, runid = %runid, "{}", format!($fmt, $($arg)+))
$crate::tracing::event!($level, "tower.runid" = %runid, "{}", format!($fmt, $($arg)+))
} else {
$crate::tracing::event!($level, "{}", format!($fmt, $($arg)+))
}
Expand All @@ -15,6 +23,29 @@ macro_rules! event_with_level {
};
}

#[macro_export]
macro_rules! trace {
// With context, format string and arguments
(ctx: $ctx:expr, $fmt:expr, $($arg:tt)+) => {
$crate::event_with_level!($crate::tracing::Level::TRACE, ctx: $ctx, $fmt, $($arg)+)
};

// With context, just message
(ctx: $ctx:expr, $msg:expr) => {
$crate::event_with_level!($crate::tracing::Level::TRACE, ctx: $ctx, "{}", $msg)
};

// Without context, format string and arguments
($fmt:expr, $($arg:tt)*) => {
$crate::event_with_level!($crate::tracing::Level::TRACE, $fmt, $($arg)*)
};

// Without context, just message
($msg:expr) => {
$crate::event_with_level!($crate::tracing::Level::TRACE, "{}", $msg)
};
}

#[macro_export]
macro_rules! debug {
// With context, format string and arguments
Expand Down Expand Up @@ -107,4 +138,77 @@ macro_rules! error {
};
}

/// LogLevel describes the various log levels that can be used in the application.
pub enum LogLevel {
Debug,
Info,
Warn,
Error,
}

impl AsRef<str> for LogLevel {
fn as_ref(&self) -> &str {
match self {
LogLevel::Debug => "debug",
LogLevel::Info => "info",
LogLevel::Warn => "warn",
LogLevel::Error => "error",
}
}
}

pub enum LogDestination {
Stdout,
File(String),
}

pub enum LogFormat {
Plain,
Json,
}

type BoxedFmtLayer = Box<dyn Layer<Registry> + Send + Sync>;

fn create_fmt_layer(format: LogFormat, destination: LogDestination) -> BoxedFmtLayer {
match destination {
LogDestination::Stdout => {
match format {
LogFormat::Plain => Box::new(fmt::layer().event_format(fmt::format().pretty())),
LogFormat::Json => Box::new(fmt::layer().event_format(fmt::format().json())),
}
}
LogDestination::File(path) => {
let file_appender = tracing_appender::rolling::daily(".", path);
match format {
LogFormat::Plain => {
Box::new(
fmt::layer()
.event_format(fmt::format().pretty())
.with_writer(file_appender)
)
}
LogFormat::Json => {
Box::new(
fmt::layer()
.event_format(fmt::format().json())
.with_writer(file_appender)
)
}
}
}
}
}

pub fn enable_logging(level: LogLevel, format: LogFormat, destination: LogDestination) {
let filter = EnvFilter::new(level)
.add_directive("h2=off".parse().unwrap())
.add_directive("tower::buffer=off".parse().unwrap())
.add_directive("hyper_util=off".parse().unwrap());

let subscriber = tracing_subscriber::registry()
.with(create_fmt_layer(format, destination))
.with(filter);

tracing::subscriber::set_global_default(subscriber)
.expect("Failed to set global default subscriber");
}
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ build-backend = "maturin"

[project]
name = "tower"
version = "0.3.17"
version = "0.3.18"


description = "Tower CLI and runtime environment for Tower."
authors = [{ name = "Tower Computing Inc.", email = "brad@tower.dev" }]
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading