• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / pg_replicate / 15020176331

14 May 2025 12:04PM UTC coverage: 39.718% (-0.2%) from 39.958%
15020176331

Pull #115

github

web-flow
Merge 7d65c0ad6 into 41511c371
Pull Request #115: Improve logging in the API

0 of 74 new or added lines in 1 file covered. (0.0%)

2 existing lines in 1 file now uncovered.

2451 of 6171 relevant lines covered (39.72%)

18.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/api/src/telemetry.rs
1
use thiserror::Error;
2
use tracing::subscriber::{set_global_default, SetGlobalDefaultError};
3
use tracing_appender::{
4
    non_blocking::WorkerGuard,
5
    rolling::{self, InitError},
6
};
7
use tracing_log::{log_tracer::SetLoggerError, LogTracer};
8
use tracing_subscriber::{
9
    fmt::{self, format::FmtSpan},
10
    EnvFilter, FmtSubscriber,
11
};
12

13
use crate::configuration::{DEV_ENV_NAME, PROD_ENV_NAME};
14

15
#[derive(Debug, Error)]
16
pub enum TracingError {
17
    #[error("failed to build rolling file appender: {0}")]
18
    InitAppender(#[from] InitError),
19

20
    #[error("failed to init log tracer: {0}")]
21
    InitLogTracer(#[from] SetLoggerError),
22

23
    #[error("failed to set global default subscriber: {0}")]
24
    SetGlobalDefault(#[from] SetGlobalDefaultError),
25
}
26

27
#[must_use]
28
pub enum LogFlusher {
29
    Flusher(WorkerGuard),
30
    NullFlusher,
31
}
32

33
/// Initializes tracing for the application.
NEW
34
pub fn init_tracing() -> Result<LogFlusher, TracingError> {
×
NEW
35
    // Initialize the log tracer to capture logs from the `log` crate
×
NEW
36
    // and send them to the `tracing` subscriber. This captures logs
×
NEW
37
    // from libraries that use the `log` crate.
×
NEW
38
    LogTracer::init()?;
×
39

NEW
40
    let is_prod =
×
NEW
41
        std::env::var("APP_ENVIRONMENT").unwrap_or_else(|_| DEV_ENV_NAME.into()) == PROD_ENV_NAME;
×
NEW
42

×
NEW
43
    // Set the default log level to `info` if not specified in the RUST_LOG environment variable.
×
NEW
44
    let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into());
×
45

NEW
46
    let log_flusher = if is_prod {
×
NEW
47
        configure_prod_tracing(filter)?
×
48
    } else {
NEW
49
        configure_dev_tracing(filter)?
×
50
    };
51

52
    // Return the log flusher to ensure logs are flushed before the application exits
53
    // without this the logs in memory may not be flushed to the file
NEW
54
    Ok(log_flusher)
×
NEW
55
}
×
56

NEW
57
fn configure_prod_tracing(filter: EnvFilter) -> Result<LogFlusher, TracingError> {
×
NEW
58
    let app_name = env!("CARGO_CRATE_NAME");
×
NEW
59
    let filename_suffix = "log";
×
NEW
60
    let log_dir = "logs";
×
NEW
61
    let file_appender = rolling::Builder::new()
×
NEW
62
        .filename_prefix(app_name)
×
NEW
63
        .filename_suffix(filename_suffix)
×
NEW
64
        // rotate the log file every day
×
NEW
65
        .rotation(rolling::Rotation::DAILY)
×
NEW
66
        // keep a maximum of 5 log files
×
NEW
67
        .max_log_files(5)
×
NEW
68
        .build(log_dir)?;
×
69

70
    // Create a non-blocking appender to avoid blocking the logging thread
71
    // when writing to the file. This is important for performance.
NEW
72
    let (file_appender, guard) = tracing_appender::non_blocking(file_appender);
×
NEW
73

×
NEW
74
    let format = fmt::format()
×
NEW
75
        .with_level(true)
×
NEW
76
        // ANSI colors are only for terminal output
×
NEW
77
        .with_ansi(false)
×
NEW
78
        // Disable target to reduce noise in the logs
×
NEW
79
        .with_target(false);
×
NEW
80

×
NEW
81
    let subscriber = FmtSubscriber::builder()
×
NEW
82
        .event_format(format)
×
NEW
83
        .with_writer(file_appender)
×
NEW
84
        .json()
×
NEW
85
        // emit a log event when a span is closed
×
NEW
86
        // since a request is a span, this will emit a log event
×
NEW
87
        // when the request is completed
×
NEW
88
        .with_span_events(FmtSpan::CLOSE)
×
NEW
89
        .with_env_filter(filter)
×
NEW
90
        .finish();
×
NEW
91

×
NEW
92
    set_global_default(subscriber)?;
×
NEW
93
    Ok(LogFlusher::Flusher(guard))
×
UNCOV
94
}
×
95

NEW
96
fn configure_dev_tracing(filter: EnvFilter) -> Result<LogFlusher, TracingError> {
×
NEW
97
    let format = fmt::format()
×
NEW
98
        // Emit the log level in the log output
×
NEW
99
        .with_level(true)
×
NEW
100
        // Enable ANSI colors for terminal output
×
NEW
101
        .with_ansi(true)
×
NEW
102
        // Make it pretty
×
NEW
103
        .pretty()
×
NEW
104
        // Disable line number, file, and target in the log output
×
NEW
105
        // to reduce noise in the logs
×
NEW
106
        .with_line_number(false)
×
NEW
107
        .with_file(false)
×
NEW
108
        .with_target(false);
×
NEW
109

×
NEW
110
    let subscriber = FmtSubscriber::builder()
×
NEW
111
        .event_format(format)
×
NEW
112
        // emit a log event when a span is closed
×
NEW
113
        // since a request is a span, this will emit a log event
×
NEW
114
        // when the request is completed
×
NEW
115
        .with_span_events(FmtSpan::CLOSE)
×
NEW
116
        .with_env_filter(filter)
×
NEW
117
        .finish();
×
NEW
118

×
NEW
119
    set_global_default(subscriber)?;
×
NEW
120
    Ok(LogFlusher::NullFlusher)
×
UNCOV
121
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc