Skip to main content

better_fetch/plugins/
logger.rs

1use async_trait::async_trait;
2use tracing::{error, info, warn};
3
4use crate::hooks::{ErrorContext, Hooks};
5use crate::plugin::Plugin;
6
7/// Tracing-based logger plugin (request, response, retry, error).
8#[derive(Debug, Clone)]
9pub struct LoggerPlugin {
10    /// When `false`, hooks are registered but do not log.
11    pub enabled: bool,
12    /// When `true`, includes method and URL on each line.
13    pub verbose: bool,
14}
15
16impl LoggerPlugin {
17    /// Creates a plugin with logging enabled.
18    pub fn new() -> Self {
19        Self {
20            enabled: true,
21            verbose: false,
22        }
23    }
24
25    /// Enables or disables log output.
26    pub fn enabled(mut self, enabled: bool) -> Self {
27        self.enabled = enabled;
28        self
29    }
30
31    /// Enables verbose log fields.
32    pub fn verbose(mut self, verbose: bool) -> Self {
33        self.verbose = verbose;
34        self
35    }
36}
37
38impl Default for LoggerPlugin {
39    fn default() -> Self {
40        Self::new()
41    }
42}
43
44#[async_trait]
45impl Plugin for LoggerPlugin {
46    /// Plugin id: `"logger"`.
47    fn id(&self) -> &'static str {
48        "logger"
49    }
50
51    fn hooks(&self) -> Hooks {
52        let enabled = self.enabled;
53        let verbose = self.verbose;
54
55        Hooks::new()
56            .on_request(move |ctx| {
57                let enabled = enabled;
58                let verbose = verbose;
59                async move {
60                    if enabled {
61                        if verbose {
62                            info!(
63                                method = %ctx.method,
64                                url = %ctx.url,
65                                "better-fetch request"
66                            );
67                        } else {
68                            info!(url = %ctx.url, "better-fetch request");
69                        }
70                    }
71                    Ok(ctx)
72                }
73            })
74            .on_response({
75                let enabled = self.enabled;
76                let verbose = self.verbose;
77                move |ctx| {
78                    let enabled = enabled;
79                    let verbose = verbose;
80                    async move {
81                        if enabled {
82                            let status = ctx.response.status();
83                            if verbose {
84                                info!(
85                                    status = %status,
86                                    url = %ctx.request.url,
87                                    "better-fetch response"
88                                );
89                            } else {
90                                info!(status = %status, "better-fetch response");
91                            }
92                        }
93                        Ok(ctx.response)
94                    }
95                }
96            })
97            .on_retry({
98                let enabled = self.enabled;
99                move |ctx| {
100                    let enabled = enabled;
101                    async move {
102                        if enabled {
103                            warn!(
104                                retry_attempt = ctx.request.retry_attempt,
105                                next_attempt = ctx.request.retry_attempt + 1,
106                                status = %ctx.response.status(),
107                                url = %ctx.request.url,
108                                "better-fetch retry"
109                            );
110                        }
111                    }
112                }
113            })
114            .on_error({
115                let enabled = self.enabled;
116                move |ctx: ErrorContext| {
117                    let enabled = enabled;
118                    async move {
119                        if enabled {
120                            error!(
121                                error = %ctx.error,
122                                url = %ctx.request.url,
123                                "better-fetch error"
124                            );
125                        }
126                    }
127                }
128            })
129    }
130}