Line data Source code
1 : /*
2 : * License:
3 : * Copyright (c) 2013-2019 Made to Order Software Corp. All Rights Reserved
4 : *
5 : * https://snapwebsites.org/
6 : * contact@m2osw.com
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 2 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License along
19 : * with this program; if not, write to the Free Software Foundation, Inc.,
20 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 : *
22 : * Authors:
23 : * Alexis Wilke alexis@m2osw.com
24 : */
25 :
26 : /** \file
27 : * \brief Implementation of the various logger variable support.
28 : *
29 : * This file implements the few logger variables which retrieves their
30 : * value from the message variable.
31 : */
32 :
33 :
34 : // self
35 : //
36 : #include "snaplogger/exception.h"
37 : #include "snaplogger/format.h"
38 : #include "snaplogger/map_diagnostic.h"
39 : #include "snaplogger/nested_diagnostic.h"
40 : #include "snaplogger/variable.h"
41 :
42 :
43 : // C++ lib
44 : //
45 : #include <iostream>
46 :
47 :
48 : // last include
49 : //
50 : #include <snapdev/poison.h>
51 :
52 :
53 :
54 : namespace snaplogger
55 : {
56 :
57 :
58 : namespace
59 : {
60 :
61 :
62 :
63 11 : DEFINE_LOGGER_VARIABLE(severity)
64 : {
65 0 : severity_t sev(msg.get_severity());
66 0 : severity::pointer_t severity(get_severity(msg, sev));
67 0 : if(severity == nullptr)
68 : {
69 : // not found, write value directly
70 : //
71 0 : value += std::to_string(static_cast<int>(sev));
72 0 : variable::process_value(msg, value);
73 0 : return;
74 : }
75 :
76 0 : auto params(get_params());
77 0 : if(!params.empty())
78 : {
79 0 : if(params[0]->get_name() == "format")
80 : {
81 0 : auto v(params[0]->get_value());
82 0 : if(v != "alpha")
83 : {
84 0 : if(v == "number")
85 : {
86 0 : value += std::to_string(static_cast<int>(sev));
87 0 : variable::process_value(msg, value);
88 0 : return;
89 : }
90 : throw invalid_variable(
91 : "the ${severity:format=alpha|number} variable cannot be set to \""
92 0 : + v
93 0 : + "\".");
94 : }
95 : }
96 : }
97 :
98 0 : value += severity->get_description();
99 :
100 0 : variable::process_value(msg, value);
101 : }
102 :
103 :
104 :
105 32920 : DEFINE_LOGGER_VARIABLE(message)
106 : {
107 32900 : if(msg.get_recursive_message())
108 : {
109 : // do nothing if we find a ${message} inside the message itself
110 0 : return;
111 : }
112 :
113 65800 : std::string const m(msg.get_message());
114 32900 : if(m.find("${") == std::string::npos)
115 : {
116 32900 : value += m;
117 : }
118 : else
119 : {
120 0 : msg.set_recursive_message(true);
121 0 : format f(m);
122 0 : value += f.process_message(msg);
123 0 : msg.set_recursive_message(false);
124 : }
125 :
126 32900 : variable::process_value(msg, value);
127 : }
128 :
129 :
130 :
131 8 : DEFINE_LOGGER_VARIABLE(project_name)
132 : {
133 : // when the advgetopt is properly connected to the logger, then the
134 : // logger will save the program name in its diagnostic map
135 : //
136 0 : map_diagnostics_t map(get_map_diagnostics(msg));
137 0 : auto it(map.find(DIAG_KEY_PROJECT_NAME));
138 0 : if(it != map.end())
139 : {
140 0 : value += it->second;
141 : }
142 :
143 0 : variable::process_value(msg, value);
144 0 : }
145 :
146 :
147 :
148 11 : DEFINE_LOGGER_VARIABLE(progname)
149 : {
150 : // when the advgetopt is properly connected to the logger, then the
151 : // logger will save the program name in its diagnostic map
152 : //
153 0 : map_diagnostics_t map(get_map_diagnostics(msg));
154 0 : auto it(map.find(DIAG_KEY_PROGNAME));
155 0 : if(it != map.end())
156 : {
157 0 : value += it->second;
158 : }
159 :
160 0 : variable::process_value(msg, value);
161 0 : }
162 :
163 :
164 :
165 8 : DEFINE_LOGGER_VARIABLE(version)
166 : {
167 : // when the advgetopt is properly connected to the logger, then the
168 : // logger will save the program name in its diagnostic map
169 : //
170 0 : map_diagnostics_t map(get_map_diagnostics(msg));
171 0 : auto it(map.find(DIAG_KEY_VERSION));
172 0 : if(it != map.end())
173 : {
174 0 : value += it->second;
175 : }
176 :
177 0 : variable::process_value(msg, value);
178 0 : }
179 :
180 :
181 :
182 8 : DEFINE_LOGGER_VARIABLE(build_date)
183 : {
184 : // when the advgetopt is properly connected to the logger, then the
185 : // logger will save the program name in its diagnostic map
186 : //
187 0 : map_diagnostics_t map(get_map_diagnostics(msg));
188 0 : auto it(map.find(DIAG_KEY_BUILD_DATE));
189 0 : if(it != map.end())
190 : {
191 0 : value += it->second;
192 : }
193 :
194 0 : variable::process_value(msg, value);
195 0 : }
196 :
197 :
198 :
199 8 : DEFINE_LOGGER_VARIABLE(build_time)
200 : {
201 : // when the advgetopt is properly connected to the logger, then the
202 : // logger will save the program name in its diagnostic map
203 : //
204 0 : map_diagnostics_t map(get_map_diagnostics(msg));
205 0 : auto it(map.find(DIAG_KEY_BUILD_TIME));
206 0 : if(it != map.end())
207 : {
208 0 : value += it->second;
209 : }
210 :
211 0 : variable::process_value(msg, value);
212 0 : }
213 :
214 :
215 :
216 8 : DEFINE_LOGGER_VARIABLE(filename)
217 : {
218 0 : value += msg.get_filename();
219 :
220 0 : variable::process_value(msg, value);
221 0 : }
222 :
223 :
224 :
225 11 : DEFINE_LOGGER_VARIABLE(basename)
226 : {
227 0 : std::string const filename(msg.get_filename());
228 0 : std::string::size_type const pos(filename.rfind('/'));
229 0 : if(pos == std::string::npos)
230 : {
231 0 : value += filename;
232 : }
233 : else
234 : {
235 0 : value += filename.substr(pos + 1);
236 : }
237 :
238 0 : variable::process_value(msg, value);
239 0 : }
240 :
241 :
242 :
243 8 : DEFINE_LOGGER_VARIABLE(path)
244 : {
245 0 : std::string const filename(msg.get_filename());
246 0 : std::string::size_type const pos(filename.rfind('/'));
247 0 : if(pos != std::string::npos)
248 : {
249 0 : value += filename.substr(0, pos);
250 : }
251 :
252 0 : variable::process_value(msg, value);
253 0 : }
254 :
255 :
256 :
257 11 : DEFINE_LOGGER_VARIABLE(function)
258 : {
259 0 : value += msg.get_function();
260 :
261 0 : variable::process_value(msg, value);
262 0 : }
263 :
264 :
265 :
266 11 : DEFINE_LOGGER_VARIABLE(line)
267 : {
268 0 : value += std::to_string(msg.get_line());
269 :
270 0 : variable::process_value(msg, value);
271 0 : }
272 :
273 :
274 :
275 8 : DEFINE_LOGGER_VARIABLE(diagnostic)
276 : {
277 0 : constexpr int FLAG_NESTED = 0x01;
278 0 : constexpr int FLAG_MAP = 0x02;
279 :
280 0 : std::int64_t nested_depth(-1);
281 0 : std::string key;
282 0 : int flags(0);
283 :
284 0 : for(auto p : get_params())
285 : {
286 0 : if(p->get_name() == "nested")
287 : {
288 0 : nested_depth = p->get_integer();
289 0 : flags |= FLAG_NESTED;
290 : }
291 0 : else if(p->get_name() == "map")
292 : {
293 0 : key = p->get_value();
294 0 : flags |= FLAG_MAP;
295 : }
296 : }
297 :
298 0 : if(flags == 0
299 0 : || (flags & FLAG_NESTED) != 0)
300 : {
301 0 : char sep('{');
302 0 : string_vector_t nested(get_nested_diagnostics(msg));
303 0 : size_t idx(0);
304 0 : if((flags & FLAG_NESTED) != 0
305 0 : && static_cast<ssize_t>(nested.size()) > nested_depth)
306 : {
307 0 : idx = nested.size() - nested_depth;
308 0 : value += sep;
309 0 : value += "...";
310 0 : sep = '/';
311 : }
312 :
313 0 : for(; idx < nested.size(); ++idx)
314 : {
315 0 : value += sep;
316 0 : sep = '/';
317 0 : value += nested[idx];
318 : }
319 0 : value += "}";
320 : }
321 :
322 0 : if(flags == 0
323 0 : || (flags & FLAG_MAP) != 0)
324 : {
325 0 : auto const diagnostics(get_map_diagnostics(msg));
326 0 : if(!diagnostics.empty())
327 : {
328 0 : if(key.empty())
329 : {
330 0 : char sep('<');
331 0 : for(auto d : diagnostics)
332 : {
333 0 : value += sep;
334 0 : sep = ':';
335 0 : value += d.first;
336 0 : value += '=';
337 0 : value += d.second;
338 : }
339 0 : value += '>';
340 : }
341 : else
342 : {
343 0 : auto it(diagnostics.find(key));
344 0 : if(it != diagnostics.end())
345 : {
346 0 : value += '<';
347 0 : value += key;
348 0 : value += '=';
349 0 : value += it->second;
350 0 : value += '>';
351 : }
352 : }
353 : }
354 : }
355 :
356 0 : variable::process_value(msg, value);
357 0 : }
358 :
359 :
360 : }
361 : // no name namespace
362 :
363 :
364 6 : } // snaplogger namespace
365 : // vim: ts=4 sw=4 et
|