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
2 changes: 2 additions & 0 deletions Cargo.lock

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

8 changes: 6 additions & 2 deletions crates/bin/cratesfyi/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use anyhow::Result;
use clap::Parser;
use cratesfyi::daemon::start_daemon;
use docs_rs_config::AppConfig as _;
use docs_rs_context::Context;
use std::env;
use tokio::runtime;

fn main() {
// set the global log::logger for backwards compatibility
// through rustwide.
docs_rs_builder::logging::init();
let guard = docs_rs_logging::init().expect("error initializing logging");
let logging_config =
docs_rs_logging::Config::from_environment().expect("error loading logging config");
docs_rs_builder::logging::init(&logging_config);
let guard =
docs_rs_logging::init_with_config(&logging_config).expect("error initializing logging");

if let Err(err) = CommandLine::parse().handle_args() {
eprintln!("error running watcher: {:?}", err);
Expand Down
2 changes: 1 addition & 1 deletion crates/bin/docs_rs_admin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::iter;

#[tokio::main]
async fn main() -> Result<()> {
let _guard = docs_rs_logging::init().context("error initializing logging")?;
let _guard = docs_rs_logging::init_from_environment().context("error initializing logging")?;

if let Err(err) = CommandLine::parse().handle_args().await {
eprintln!("error running admin CLI: {:?}", err);
Expand Down
9 changes: 7 additions & 2 deletions crates/bin/docs_rs_builder/src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use docs_rs_logging::Config;
use tracing_log::LogTracer;

pub fn init() {
rustwide::logging::init_with(LogTracer::new());
pub fn init(config: &Config) {
if config.log_build_logs {
rustwide::logging::init_with(LogTracer::new());
} else {
rustwide::logging::init();
}
}
6 changes: 4 additions & 2 deletions crates/bin/docs_rs_builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ use std::{path::PathBuf, sync::Arc};
use tokio::runtime;

fn main() -> Result<()> {
docs_rs_builder::logging::init();
let _guard = docs_rs_logging::init().context("error initializing logging")?;
let logging_config = docs_rs_logging::Config::from_environment()?;
docs_rs_builder::logging::init(&logging_config);
let _guard =
docs_rs_logging::init_with_config(&logging_config).context("error initializing logging")?;

if let Err(err) = CommandLine::parse().handle_args() {
eprintln!("error running builder: {:?}", err);
Expand Down
3 changes: 2 additions & 1 deletion crates/bin/docs_rs_builder/src/testing/test_env.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{Config as BuilderConfig, RustwideBuilder};
use anyhow::Result;
use docs_rs_config::AppConfig as _;

pub(crate) type TestEnvironment = docs_rs_context::testing::BlockingTestEnvironment<BuilderConfig>;

Expand All @@ -9,7 +10,7 @@ pub(crate) trait TestEnvironmentExt {

impl TestEnvironmentExt for TestEnvironment {
fn build_builder(&self) -> Result<RustwideBuilder> {
crate::logging::init(); // initialize rustwide logging
crate::logging::init(&docs_rs_logging::Config::test_config()?); // initialize rustwide logging
RustwideBuilder::init(self.config().clone(), self)
}
}
2 changes: 1 addition & 1 deletion crates/bin/docs_rs_import_release/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use docs_rs_types::{KrateName, ReqVersion};

#[tokio::main]
async fn main() -> Result<()> {
let _guard = docs_rs_logging::init().context("error initializing logging")?;
let _guard = docs_rs_logging::init_from_environment().context("error initializing logging")?;

if let Err(err) = CommandLine::parse().handle_args().await {
eprintln!("error importing release: {err:?}");
Expand Down
2 changes: 1 addition & 1 deletion crates/bin/docs_rs_watcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
let _guard = docs_rs_logging::init().context("error initializing logging")?;
let _guard = docs_rs_logging::init_from_environment().context("error initializing logging")?;

if let Err(err) = CommandLine::parse().handle_args().await {
eprintln!("error running watcher: {:?}", err);
Expand Down
2 changes: 1 addition & 1 deletion crates/bin/docs_rs_web/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct Cli {

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let _guard = docs_rs_logging::init().context("error initializing logging")?;
let _guard = docs_rs_logging::init_from_environment().context("error initializing logging")?;

let args = Cli::parse();
let context = build_context().await?;
Expand Down
7 changes: 6 additions & 1 deletion crates/lib/docs_rs_logging/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ repository.workspace = true
edition.workspace = true

[features]
testing = []
testing = ["docs_rs_config/testing"]

[dependencies]
anyhow = { workspace = true }
docs_rs_config = { path = "../docs_rs_config" }
docs_rs_env_vars = { path = "../docs_rs_env_vars" }
docs_rs_utils = { path = "../docs_rs_utils" }
sentry = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { version = "0.3.20", default-features = false, features = ["ansi", "fmt", "json", "env-filter", "tracing-log"] }

[dev-dependencies]
docs_rs_config = { path = "../docs_rs_config", features = ["testing"] }
55 changes: 55 additions & 0 deletions crates/lib/docs_rs_logging/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::LogFormat;
use docs_rs_config::AppConfig;
use docs_rs_env_vars::{env, maybe_env};
use std::str::FromStr;
use tracing_subscriber::{EnvFilter, filter::Directive};

#[derive(Debug)]
pub struct SentryConfig {
pub dsn: sentry::types::Dsn,
pub traces_sample_rate: f32,
}

#[derive(Debug)]
pub struct Config {
pub format: LogFormat,
pub filter: EnvFilter,
pub sentry: Option<SentryConfig>,

/// Whether to output the build logs to stdout too,
/// or just store them on S3.
pub log_build_logs: bool,
}

impl Config {
fn filter_from_env(default_directive: &str) -> anyhow::Result<EnvFilter> {
Ok(EnvFilter::builder()
.with_default_directive(Directive::from_str(default_directive)?)
.with_env_var("DOCSRS_LOG")
.from_env_lossy())
}
}

impl AppConfig for Config {
fn from_environment() -> anyhow::Result<Self> {
Ok(Self {
format: maybe_env("DOCSRS_LOG_FORMAT")?.unwrap_or_default(),
filter: Self::filter_from_env("info")?,
sentry: maybe_env("SENTRY_DSN")?.map(|dsn| SentryConfig {
dsn,
traces_sample_rate: env("SENTRY_TRACES_SAMPLE_RATE", 0.0).unwrap_or(0.0),
}),
log_build_logs: env("DOCSRS_LOG_BUILD_LOGS", true)?,
})
}

#[cfg(any(test, feature = "testing"))]
fn test_config() -> anyhow::Result<Self> {
Ok(Self {
format: LogFormat::Pretty,
filter: Self::filter_from_env("trace")?,
sentry: None,
log_build_logs: true,
})
}
}
46 changes: 22 additions & 24 deletions crates/lib/docs_rs_logging/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
mod config;
pub mod log_format;
#[cfg(feature = "testing")]
pub mod testing;

pub use config::Config;
pub use log_format::LogFormat;

use docs_rs_config::AppConfig as _;
use sentry::{
TransactionContext, integrations::panic as sentry_panic,
integrations::tracing as sentry_tracing,
};
use std::{env, str::FromStr as _, sync::Arc};
use tracing_subscriber::{EnvFilter, filter::Directive, prelude::*};
use std::sync::Arc;
use tracing_subscriber::prelude::*;

/// defines the transaction name to be used for our rustwide builder.
///
Expand All @@ -22,25 +28,21 @@ pub struct Guard {
sentry_guard: Option<sentry::ClientInitGuard>,
}

pub fn init() -> anyhow::Result<Guard> {
let log_formatter = {
let log_format = env::var("DOCSRS_LOG_FORMAT").unwrap_or_default();
pub fn init_from_environment() -> anyhow::Result<Guard> {
init_with_config(&Config::from_environment()?)
}

if log_format == "json" {
tracing_subscriber::fmt::layer().json().boxed()
} else {
tracing_subscriber::fmt::layer().boxed()
}
pub fn init_with_config(config: &Config) -> anyhow::Result<Guard> {
let log_formatter = match config.format {
LogFormat::Json => tracing_subscriber::fmt::layer().json().boxed(),
LogFormat::Pretty => tracing_subscriber::fmt::layer().boxed(),
};

let tracing_registry = tracing_subscriber::registry().with(log_formatter).with(
EnvFilter::builder()
.with_default_directive(Directive::from_str("info")?)
.with_env_var("DOCSRS_LOG")
.from_env_lossy(),
);
let tracing_registry = tracing_subscriber::registry()
.with(log_formatter)
.with(config.filter.clone());

let sentry_guard = if let Ok(sentry_dsn) = env::var("SENTRY_DSN") {
let sentry_guard = if let Some(sentry_config) = &config.sentry {
tracing::subscriber::set_global_default(tracing_registry.with(
sentry_tracing::layer().event_filter(|md| {
if md.fields().field("reported_to_sentry").is_some() {
Expand All @@ -51,11 +53,7 @@ pub fn init() -> anyhow::Result<Guard> {
}),
))?;

let traces_sample_rate = env::var("SENTRY_TRACES_SAMPLE_RATE")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(0.0);

let sample_rate = sentry_config.traces_sample_rate;
let traces_sampler = move |ctx: &TransactionContext| -> f32 {
if let Some(sampled) = ctx.sampled() {
// if the transaction was already marked as "to be sampled" by
Expand All @@ -67,12 +65,12 @@ pub fn init() -> anyhow::Result<Guard> {
// record all transactions for builds
1.
} else {
traces_sample_rate
sample_rate
}
};

Some(sentry::init((
sentry_dsn,
sentry_config.dsn.clone(),
sentry::ClientOptions {
release: Some(docs_rs_utils::BUILD_VERSION.into()),
attach_stacktrace: true,
Expand Down
31 changes: 31 additions & 0 deletions crates/lib/docs_rs_logging/src/log_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::{fmt, str::FromStr};

#[derive(Debug, Default)]
pub enum LogFormat {
Json,
#[default]
Pretty,
}

#[derive(Debug)]
pub struct InvalidLogFormat(String);

impl fmt::Display for InvalidLogFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "invalid log format: {}", self.0)
}
}

impl std::error::Error for InvalidLogFormat {}

impl FromStr for LogFormat {
type Err = InvalidLogFormat;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"json" => Ok(Self::Json),
"pretty" => Ok(Self::Pretty),
_ => Err(InvalidLogFormat(s.to_string())),
}
}
}
1 change: 1 addition & 0 deletions justfiles/testing.just
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ sqlx-prepare *args: _ensure_db_and_s3_are_running
-- --all-targets --all-features

for subcrate in crates/lib/* crates/bin/*; do
echo "Preparing SQLx metadata for ${subcrate}..."
# NOTE: potential optimization: only run this command when `sqlx`
# is in the dependencies of the subcrate.
(cd "${subcrate}" && cargo sqlx prepare \
Expand Down
Loading