qubit_progress/reporter/impls/json_logger_progress_reporter.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use qubit_function::ArcConsumer;
11
12use super::json_progress_reporter::JsonProgressReporter;
13use crate::{
14 model::ProgressEvent,
15 reporter::ProgressReporter,
16};
17
18/// Progress reporter that emits JSON metric snapshots through `log`.
19pub struct JsonLoggerProgressReporter {
20 /// Log target used for emitted records.
21 target: String,
22 /// Log level used for emitted records.
23 level: log::Level,
24 /// JSON reporter that consumes formatted strings.
25 inner: JsonProgressReporter,
26}
27
28impl JsonLoggerProgressReporter {
29 /// Creates a JSON logger reporter at [`log::Level::Info`].
30 ///
31 /// # Parameters
32 ///
33 /// * `target` - Log target used for emitted records.
34 ///
35 /// # Returns
36 ///
37 /// A JSON logger-backed progress reporter.
38 #[inline]
39 pub fn new(target: &str) -> Self {
40 Self::with_target_and_level(target, log::Level::Info)
41 }
42
43 /// Returns a copy configured with a log level.
44 ///
45 /// # Parameters
46 ///
47 /// * `level` - Log level used for emitted records.
48 ///
49 /// # Returns
50 ///
51 /// This reporter configured with `level`.
52 #[inline]
53 #[must_use]
54 pub fn with_level(self, level: log::Level) -> Self {
55 Self::with_target_and_level(self.target.as_str(), level)
56 }
57
58 /// Returns the log target.
59 ///
60 /// # Returns
61 ///
62 /// The target used for emitted log records.
63 #[inline]
64 pub fn target(&self) -> &str {
65 self.target.as_str()
66 }
67
68 /// Returns the log level.
69 ///
70 /// # Returns
71 ///
72 /// The level used for emitted log records.
73 #[inline]
74 pub const fn level(&self) -> log::Level {
75 self.level
76 }
77
78 /// Creates a JSON logger reporter from target and level.
79 ///
80 /// # Parameters
81 ///
82 /// * `target` - Log target used for emitted records.
83 /// * `level` - Log level used for emitted records.
84 ///
85 /// # Returns
86 ///
87 /// A configured JSON logger reporter.
88 fn with_target_and_level(target: &str, level: log::Level) -> Self {
89 let target = target.to_owned();
90 let log_target = target.clone();
91 let consumer = ArcConsumer::new(move |line: &String| {
92 log::log!(target: log_target.as_str(), level, "{line}");
93 });
94 Self {
95 target,
96 level,
97 inner: JsonProgressReporter::new(consumer),
98 }
99 }
100}
101
102impl Default for JsonLoggerProgressReporter {
103 /// Creates a JSON logger reporter with the default target.
104 ///
105 /// # Returns
106 ///
107 /// A JSON logger-backed reporter at [`log::Level::Info`].
108 #[inline]
109 fn default() -> Self {
110 Self::new("qubit_progress")
111 }
112}
113
114impl ProgressReporter for JsonLoggerProgressReporter {
115 /// Logs one JSON line for every metric snapshot in the event.
116 ///
117 /// # Parameters
118 ///
119 /// * `event` - Progress event to log.
120 #[inline]
121 fn report(&self, event: &ProgressEvent) {
122 self.inner.report(event);
123 }
124}