Line data Source code
1 : // Copyright (c) 2013-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snaplogger
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : #pragma once
20 :
21 : /** \file
22 : * \brief Variables are used to dynamically add parameters to log messages.
23 : *
24 : * This file declares the base variable class.
25 : *
26 : * The format defines \em functions which are written as in
27 : * `${function-name}`.
28 : *
29 : * Parameters can be passed to these functions by adding `:<param>`
30 : * to those definitions. These are named parameters and their default
31 : * value is "present" or not. A specific value can be assignd using
32 : * the equal sign as in `:param=<value>`.
33 : *
34 : * For example, the date function can be called as follow:
35 : *
36 : * \code
37 : * ${date:year:align=right:exact_width=2}
38 : * \endcode
39 : *
40 : * The `year` parameter is specific to the `date` function. The other
41 : * parameters are available whatever the function. This variable asks
42 : * to truncate the year to 2 character right aligned (i.e. "18" in
43 : * "2018".)
44 : *
45 : * In C++, this would look something like:
46 : *
47 : * \code
48 : * date(FLAG_YEAR, ALIGN_RIGHT, 2);
49 : * \endcode
50 : */
51 :
52 :
53 : // self
54 : //
55 : #include "snaplogger/message.h"
56 :
57 :
58 : // libutf8 lib
59 : //
60 : #include <libutf8/libutf8.h>
61 :
62 :
63 : // C++
64 : //
65 : #include <vector>
66 :
67 :
68 :
69 : namespace snaplogger
70 : {
71 :
72 : // variables
73 : // Variable Type
74 : #define SNAPLOGGER_VAR_BASENAME "basename" // logger_variable.cpp
75 : #define SNAPLOGGER_VAR_BOOTID "boot_id" // system_variable.cpp
76 : #define SNAPLOGGER_VAR_BUILD_DATE "build_date" // logger_variable.cpp
77 : #define SNAPLOGGER_VAR_BUILD_TIME "build_time" // logger_variable.cpp
78 : #define SNAPLOGGER_VAR_DATE "date" // date_variable.cpp
79 : #define SNAPLOGGER_VAR_DIAGNOSTIC "diagnostic" // logger_variable.cpp
80 : #define SNAPLOGGER_VAR_DIRECT "direct" // variable.cpp
81 : #define SNAPLOGGER_VAR_DOMAINNAME "domainname" // system_variable.cpp
82 : #define SNAPLOGGER_VAR_ENV "env" // environment_variable.cpp
83 : #define SNAPLOGGER_VAR_FIELD "field" // logger_variable.cpp
84 : #define SNAPLOGGER_VAR_FIELDS "fields" // logger_variable.cpp
85 : #define SNAPLOGGER_VAR_FILENAME "filename" // logger_variable.cpp
86 : #define SNAPLOGGER_VAR_FUNCTION "function" // logger_variable.cpp
87 : #define SNAPLOGGER_VAR_GID "gid" // user_variable.cpp
88 : #define SNAPLOGGER_VAR_GROUPNAME "groupname" // user_variable.cpp
89 : #define SNAPLOGGER_VAR_HOSTBYNAME "hostbyname" // system_variable.cpp
90 : #define SNAPLOGGER_VAR_HOSTNAME "hostname" // system_variable.cpp
91 : #define SNAPLOGGER_VAR_LINE "line" // logger_variable.cpp
92 : #define SNAPLOGGER_VAR_LOCALE "locale" // date_variable.cpp
93 : #define SNAPLOGGER_VAR_MESSAGE "message" // logger_variable.cpp
94 : #define SNAPLOGGER_VAR_PATH "path" // logger_variable.cpp
95 : #define SNAPLOGGER_VAR_PID "pid" // system_variable.cpp
96 : #define SNAPLOGGER_VAR_PROJECT_NAME "project_name" // logger_variable.cpp
97 : #define SNAPLOGGER_VAR_PROGNAME "progname" // logger_variable.cpp
98 : #define SNAPLOGGER_VAR_SEVERITY "severity" // logger_variable.cpp
99 : #define SNAPLOGGER_VAR_TID "tid" // system_variable.cpp
100 : #define SNAPLOGGER_VAR_TIME "time" // date_variable.cpp
101 : #define SNAPLOGGER_VAR_THREADNAME "threadname" // system_variable.cpp
102 : #define SNAPLOGGER_VAR_UID "uid" // user_variable.cpp
103 : #define SNAPLOGGER_VAR_USERNAME "username" // user_variable.cpp
104 : #define SNAPLOGGER_VAR_VERSION "version" // logger_variable.cpp
105 :
106 : // functions
107 : //
108 : #define SNAPLOGGER_VAR_ALIGN "align"
109 : #define SNAPLOGGER_VAR_APPEND "append"
110 : #define SNAPLOGGER_VAR_CAPS "caps"
111 : #define SNAPLOGGER_VAR_ESCAPE "escape"
112 : #define SNAPLOGGER_VAR_EXACT_WIDTH "exact_width"
113 : #define SNAPLOGGER_VAR_LOWER "lower"
114 : #define SNAPLOGGER_VAR_MAX_WIDTH "max_width"
115 : #define SNAPLOGGER_VAR_MIN_WIDTH "min_width"
116 : #define SNAPLOGGER_VAR_PADDING "padding"
117 : #define SNAPLOGGER_VAR_PREPEND "prepend"
118 : #define SNAPLOGGER_VAR_UPPER "upper"
119 :
120 : // parameters
121 : //
122 : #define SNAPLOGGER_VAR_ALIGN_LEFT "left"
123 : #define SNAPLOGGER_VAR_ALIGN_RIGHT "right"
124 :
125 :
126 :
127 163 : class param
128 : {
129 : public:
130 : typedef std::shared_ptr<param> pointer_t;
131 : typedef std::vector<pointer_t> vector_t;
132 :
133 : enum class type_t
134 : {
135 : TYPE_STRING,
136 : TYPE_INTEGER
137 : };
138 :
139 : param(std::string const & name);
140 :
141 : std::string const & get_name() const;
142 :
143 : type_t get_type() const;
144 :
145 : std::string get_value() const;
146 : void set_value(std::string const & value);
147 :
148 : int64_t get_integer() const;
149 : void set_integer(std::int64_t integer);
150 :
151 : private:
152 : std::string const f_name;
153 : type_t f_type = type_t::TYPE_STRING;
154 : std::string f_value = std::string();
155 : std::int64_t f_integer = 0;
156 : };
157 :
158 :
159 : template<typename CharT, typename Traits>
160 : inline std::basic_ostream<CharT, Traits> &
161 : operator << (std::basic_ostream<CharT, Traits> & os, param::pointer_t p)
162 : {
163 : if(p != nullptr)
164 : {
165 : os << p->get_name();
166 : }
167 : else
168 : {
169 : os << "(nullptr)";
170 : }
171 : return os;
172 : }
173 :
174 :
175 : template<typename CharT, typename Traits>
176 : inline std::basic_ostream<CharT, Traits> &
177 : operator << (std::basic_ostream<CharT, Traits> & os, param::type_t t)
178 : {
179 : switch(t)
180 : {
181 : case param::type_t::TYPE_STRING:
182 : os << "string";
183 : break;
184 :
185 : case param::type_t::TYPE_INTEGER:
186 : os << "integer";
187 : break;
188 :
189 : default:
190 : os << "(unknown)";
191 : break;
192 :
193 : }
194 : return os;
195 : }
196 :
197 :
198 :
199 :
200 :
201 220 : class variable
202 : {
203 : public:
204 : typedef std::shared_ptr<variable> pointer_t;
205 : typedef std::vector<pointer_t> vector_t;
206 :
207 : virtual ~variable();
208 :
209 : virtual bool ignore_on_no_repeat() const = 0;
210 : void add_param(param::pointer_t p);
211 : param::vector_t get_params() const;
212 : std::string get_value(message const & msg) const;
213 :
214 : protected:
215 : virtual void process_value(message const & msg, std::string & value) const;
216 :
217 : private:
218 : param::vector_t f_params = param::vector_t();
219 : };
220 :
221 :
222 : class variable_factory
223 : {
224 : public:
225 : typedef std::shared_ptr<variable_factory> pointer_t;
226 :
227 : variable_factory(std::string const & type);
228 : virtual ~variable_factory();
229 :
230 : std::string const & get_type() const;
231 : virtual variable::pointer_t create_variable() = 0;
232 :
233 : private:
234 : std::string const f_type;
235 : };
236 :
237 :
238 : void register_variable_factory(variable_factory::pointer_t factory);
239 : variable::pointer_t get_variable(std::string const & type);
240 :
241 :
242 : #define DEFINE_LOGGER_VARIABLE_IMPL_(type, do_ignore_on_no_repeat) \
243 : class type##_variable \
244 : : public ::snaplogger::variable \
245 : { \
246 : protected: \
247 : virtual bool ignore_on_no_repeat() const override \
248 : { return do_ignore_on_no_repeat; } \
249 : virtual void process_value( \
250 : ::snaplogger::message const & msg \
251 : , std::string & value) const override; \
252 : }; \
253 : class type##_variable_factory final \
254 : : public ::snaplogger::variable_factory \
255 : { \
256 : public: \
257 : type##_variable_factory() \
258 : : variable_factory(#type) \
259 : {} \
260 : virtual ::snaplogger::variable::pointer_t \
261 : create_variable() override final \
262 : { \
263 : return std::make_shared<type##_variable>(); \
264 : } \
265 : }; \
266 : int __attribute__((unused)) \
267 : g_##type##_variable_factory = []() { \
268 : ::snaplogger::register_variable_factory \
269 : (std::make_shared< \
270 : type##_variable_factory>()); \
271 : return 0; \
272 : } (); \
273 : void type##_variable::process_value( \
274 : ::snaplogger::message const & msg \
275 : , std::string & value) const
276 :
277 :
278 : #define DEFINE_LOGGER_VARIABLE(type) \
279 : DEFINE_LOGGER_VARIABLE_IMPL_(type, false)
280 :
281 : #define DEFINE_LOGGER_VARIABLE_IGNORED_ON_NO_REPEAT(type) \
282 : DEFINE_LOGGER_VARIABLE_IMPL_(type, true)
283 :
284 :
285 :
286 :
287 :
288 :
289 93446 : class function_data
290 : {
291 : public:
292 : void set_value(std::string value);
293 : void set_value(std::u32string value);
294 : std::u32string & get_value();
295 : void set_param(std::string const & name, std::string const & value);
296 : void set_param(std::string const & name, std::u32string const & value);
297 : std::u32string get_param(std::string const & name, std::u32string const & default_value);
298 :
299 : private:
300 : std::u32string f_value = std::u32string();
301 : u8u32string_map_t f_params = u8u32string_map_t();
302 : };
303 :
304 :
305 :
306 :
307 : class function
308 : {
309 : public:
310 : typedef std::shared_ptr<function> pointer_t;
311 :
312 : function(std::string const & function_name);
313 : virtual ~function();
314 :
315 : std::string const & get_name() const;
316 :
317 : virtual void apply(
318 : message const & msg
319 : , function_data & data
320 : , param::pointer_t const & p) = 0;
321 :
322 : private:
323 : std::string const f_name;
324 : };
325 :
326 :
327 : void register_function(function::pointer_t func);
328 :
329 :
330 : #define DECLARE_FUNCTION(name) \
331 : class name##_function : public function \
332 : { \
333 : public: \
334 : name##_function() : function(#name) {} \
335 : virtual void apply( \
336 : ::snaplogger::message const & msg \
337 : , ::snaplogger::function_data & d \
338 : , ::snaplogger::param::pointer_t const & p) override; \
339 : }; \
340 : int __attribute__((unused)) g_##name##_function = []() { \
341 : register_function(std::make_shared<name##_function>()); \
342 : return 0; \
343 : } (); \
344 : void name##_function::apply( \
345 : ::snaplogger::message const & msg \
346 : , ::snaplogger::function_data & d \
347 : , ::snaplogger::param::pointer_t const & p)
348 :
349 :
350 :
351 :
352 :
353 : } // snaplogger namespace
354 : // vim: ts=4 sw=4 et
|