timber_rust/config/
config.rs1use crate::config::entry::Entry;
2use crate::service::{FeatureDisabledError, ServiceError};
3use crate::{LogManager, LoggerFactory};
4use std::collections::HashMap;
5use std::fs::{File, OpenOptions};
6use std::io::BufWriter;
7use std::path::Path;
8use fnv64_rs::FnvBuildHasher;
9
10pub struct Config {
11 entries: HashMap<String, Entry, FnvBuildHasher>,
12}
13
14impl Config {
15 pub fn build(self) -> Result<LogManager, ServiceError> {
32 let mut manager = LogManager::new();
33 for (channel, entry) in self.entries {
34 let logger = match entry {
35 Entry::Silent {} => LoggerFactory::silent(),
36 Entry::StdOut {
37 concurrency,
38 max_retries,
39 worker_count,
40 } => {
41 let mut factory = LoggerFactory::cout();
42 if let Some(max_retries) = max_retries {
43 factory = factory.max_retries(max_retries);
44 }
45 if let Some(worker_count) = worker_count {
46 factory = factory.max_retries(worker_count);
47 }
48 factory.build(concurrency)
49 }
50 Entry::StdErr {
51 concurrency,
52 max_retries,
53 worker_count,
54 } => {
55 let mut factory = LoggerFactory::cout();
56 if let Some(max_retries) = max_retries {
57 factory = factory.max_retries(max_retries);
58 }
59 if let Some(worker_count) = worker_count {
60 factory = factory.max_retries(worker_count);
61 }
62 factory.build(concurrency)
63 }
64 Entry::File {
65 path,
66 concurrency,
67 max_retries,
68 worker_count,
69 } => {
70 if let Some(parent) = Path::new(path.as_str()).parent() {
72 std::fs::create_dir_all(parent).map_err(|e| ServiceError::Io(e))?;
73 }
74 let file: File = OpenOptions::new()
76 .append(true) .create(true) .write(true) .open(path)
80 .map_err(|e| ServiceError::Io(e))?;
81 let mut factory = LoggerFactory::io().file(file);
83 if let Some(max_retries) = max_retries {
84 factory = factory.max_retries(max_retries);
85 }
86 if let Some(worker_count) = worker_count {
87 factory = factory.max_retries(worker_count);
88 }
89 factory.build(concurrency)
90 }
91 Entry::BufferedFile {
92 path,
93 concurrency,
94 max_retries,
95 worker_count,
96 } => {
97 if let Some(parent) = Path::new(path.as_str()).parent() {
99 std::fs::create_dir_all(parent).map_err(|e| ServiceError::Io(e))?;
100 }
101 let file: File = OpenOptions::new()
103 .append(true) .create(true) .write(true) .open(path)
107 .map_err(|e| ServiceError::Io(e))?;
108 let mut factory = LoggerFactory::io().buffered_file(BufWriter::new(file));
110 if let Some(max_retries) = max_retries {
111 factory = factory.max_retries(max_retries);
112 }
113 if let Some(worker_count) = worker_count {
114 factory = factory.max_retries(worker_count);
115 }
116 factory.build(concurrency)
117 }
118 Entry::String {
119 concurrency,
120 max_retries,
121 worker_count,
122 capacity,
123 } => {
124 let mut factory = LoggerFactory::fmt().string();
126 if let Some(max_retries) = max_retries {
127 factory = factory.max_retries(max_retries);
128 }
129 if let Some(worker_count) = worker_count {
130 factory = factory.max_retries(worker_count);
131 }
132 if let Some(capacity) = capacity {
133 factory = factory.max_retries(capacity);
134 }
135 factory.build(concurrency)
136 }
137 Entry::Vector {
138 concurrency,
139 max_retries,
140 worker_count,
141 capacity,
142 } => {
143 let mut factory = LoggerFactory::vector();
144 if let Some(max_retries) = max_retries {
145 factory = factory.max_retries(max_retries);
146 }
147 if let Some(worker_count) = worker_count {
148 factory = factory.max_retries(worker_count);
149 }
150 if let Some(capacity) = capacity {
151 factory = factory.max_retries(capacity);
152 }
153 factory.build(concurrency)
154 }
155 #[cfg(feature = "loki")]
156 Entry::Loki { .. } => {
157 let config = entry.build_loki_config().expect("Corrupted memory");
158 LoggerFactory::loki().config(config).build()
159 }
160 #[cfg(feature = "aws")]
161 Entry::CloudWatchConfig { .. } => {
162 let config = entry.build_cloudwatch_config().expect("Corrupted memory");
163 LoggerFactory::cloudwatch().config(config).build()
164 }
165 #[cfg(feature = "aws")]
166 Entry::CloudWatchEnv { log_group } => {
167 LoggerFactory::cloudwatch().env(log_group).build()
168 }
169 #[cfg(feature = "awscout")]
170 Entry::CloudWatchCout {
171 concurrency,
172 max_retries,
173 worker_count,
174 } => {
175 let mut factory = LoggerFactory::cout();
176 if let Some(max_retries) = max_retries {
177 factory = factory.max_retries(max_retries);
178 }
179 if let Some(worker_count) = worker_count {
180 factory = factory.max_retries(worker_count);
181 }
182 factory.build(concurrency)
183 }
184 Entry::DisabledFeature { feature } => {
185 return Err(ServiceError::FeatureDisabled(FeatureDisabledError::new(
186 feature,
187 )));
188 }
189 };
190
191 manager.set_logger(channel, logger);
193 }
194
195 Ok(manager)
196 }
197
198 pub fn get_entry<Q>(&self, channel: &Q) -> Option<&Entry>
202 where
203 Q: AsRef<str> + ?Sized,
204 {
205 self.entries.get(channel.as_ref())
206 }
207
208 pub fn get_entry_mut<Q>(&mut self, channel: &Q) -> Option<&mut Entry>
210 where
211 Q: AsRef<str> + ?Sized,
212 {
213 self.entries.get_mut(channel.as_ref())
214 }
215
216 pub fn remove_entry<Q>(&mut self, channel: &Q) -> Option<Entry>
218 where
219 Q: AsRef<str> + ?Sized,
220 {
221 self.entries.remove(channel.as_ref())
222 }
223
224 pub fn insert_entry<S>(&mut self, channel: S, entry: Entry)
227 where
228 S: Into<String>,
229 {
230 self.entries.insert(channel.into(), entry);
231 }
232}