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 : #pragma once
26 :
27 : /** \file
28 : * \brief Variables are used to dynamically add parameters to log messages.
29 : *
30 : * This file declares the base variable class.
31 : *
32 : * The format defines \em functions which are written as in
33 : * `${function-name}`.
34 : *
35 : * Parameters can be passed to these functions by adding `:<param>`
36 : * to those definitions. These are named parameters and their default
37 : * value is "present" or not. A specific value can be assignd using
38 : * the equal sign as in `:param=<value>`.
39 : *
40 : * For example, the date function can be called as follow:
41 : *
42 : * \code
43 : * ${date:year:align=right:exact_width=2}
44 : * \endcode
45 : *
46 : * The `year` parameter is specific to the `date` function. The other
47 : * parameters are available whatever the function. This variable asks
48 : * to truncate the year to 2 character right aligned (i.e. "18" in
49 : * "2018".)
50 : *
51 : * In C++, this would look something like:
52 : *
53 : * \code
54 : * date(FLAG_YEAR, ALIGN_RIGHT, 2);
55 : * \endcode
56 : */
57 :
58 :
59 : // self
60 : //
61 : #include "snaplogger/message.h"
62 :
63 :
64 : // libutf8 lib
65 : //
66 : #include <libutf8/libutf8.h>
67 :
68 :
69 : // C++
70 : //
71 : #include <vector>
72 :
73 :
74 :
75 : namespace snaplogger
76 : {
77 :
78 : // variables
79 : //
80 : #define SNAPLOGGER_VAR_BASENAME "basename"
81 : #define SNAPLOGGER_VAR_DATE "date"
82 : #define SNAPLOGGER_VAR_DIAGNOSTIC "diagnostic"
83 : #define SNAPLOGGER_VAR_DOMAINNAME "domainname"
84 : #define SNAPLOGGER_VAR_ENV "env"
85 : #define SNAPLOGGER_VAR_FILENAME "filename"
86 : #define SNAPLOGGER_VAR_FUNCTION "function"
87 : #define SNAPLOGGER_VAR_GID "gid"
88 : #define SNAPLOGGER_VAR_GROUPNAME "groupname"
89 : #define SNAPLOGGER_VAR_HOSTBYNAME "hostbyname"
90 : #define SNAPLOGGER_VAR_HOSTNAME "hostname"
91 : #define SNAPLOGGER_VAR_LINE "line"
92 : #define SNAPLOGGER_VAR_LOCALE "locale"
93 : #define SNAPLOGGER_VAR_MESSAGE "message"
94 : #define SNAPLOGGER_VAR_PATH "path"
95 : #define SNAPLOGGER_VAR_PID "pid"
96 : #define SNAPLOGGER_VAR_PROGNAME "progname"
97 : #define SNAPLOGGER_VAR_SEVERITY "severity"
98 : #define SNAPLOGGER_VAR_TID "tid"
99 : #define SNAPLOGGER_VAR_TIME "time"
100 : #define SNAPLOGGER_VAR_THREADNAME "threadname"
101 : #define SNAPLOGGER_VAR_UID "uid"
102 : #define SNAPLOGGER_VAR_USERNAME "username"
103 : #define SNAPLOGGER_VAR_VERSION "version"
104 :
105 : // functions
106 : //
107 : #define SNAPLOGGER_VAR_ALIGN "align"
108 : #define SNAPLOGGER_VAR_APPEND "append"
109 : #define SNAPLOGGER_VAR_CAPS "caps"
110 : #define SNAPLOGGER_VAR_ESCAPE "escape"
111 : #define SNAPLOGGER_VAR_EXACT_WIDTH "exact_width"
112 : #define SNAPLOGGER_VAR_LOWER "lower"
113 : #define SNAPLOGGER_VAR_MAX_WIDTH "max_width"
114 : #define SNAPLOGGER_VAR_MIN_WIDTH "min_width"
115 : #define SNAPLOGGER_VAR_PADDING "padding"
116 : #define SNAPLOGGER_VAR_PREPEND "prepend"
117 : #define SNAPLOGGER_VAR_UPPER "upper"
118 :
119 : // parameters
120 : //
121 : #define SNAPLOGGER_VAR_ALIGN_LEFT "left"
122 : #define SNAPLOGGER_VAR_ALIGN_RIGHT "right"
123 :
124 :
125 :
126 12 : class param
127 : {
128 : public:
129 : typedef std::shared_ptr<param> pointer_t;
130 : typedef std::vector<pointer_t> vector_t;
131 :
132 : enum class type_t
133 : {
134 : TYPE_STRING,
135 : TYPE_INTEGER
136 : };
137 :
138 : param(std::string const & name);
139 :
140 : std::string const & get_name() const;
141 :
142 : type_t get_type() const;
143 :
144 : std::string get_value() const;
145 : void set_value(std::string const & value);
146 :
147 : int64_t get_integer() const;
148 : void set_integer(std::int64_t integer);
149 :
150 : private:
151 : std::string const f_name;
152 : type_t f_type = type_t::TYPE_STRING;
153 : std::string f_value = std::string();
154 : std::int64_t f_integer = 0;
155 : };
156 :
157 :
158 23 : class variable
159 : {
160 : public:
161 : typedef std::shared_ptr<variable> pointer_t;
162 : typedef std::vector<pointer_t> vector_t;
163 :
164 : virtual ~variable();
165 :
166 : void add_param(param::pointer_t p);
167 : param::vector_t get_params() const;
168 : std::string get_value(message const & msg) const;
169 :
170 : protected:
171 : virtual void process_value(message const & msg, std::string & value) const;
172 :
173 : private:
174 : param::vector_t f_params = param::vector_t();
175 : };
176 :
177 :
178 : class variable_factory
179 : {
180 : public:
181 : typedef std::shared_ptr<variable_factory> pointer_t;
182 :
183 : variable_factory(std::string const & type);
184 : virtual ~variable_factory();
185 :
186 : std::string const & get_type() const;
187 : virtual variable::pointer_t create_variable() = 0;
188 :
189 : private:
190 : std::string const f_type;
191 : };
192 :
193 :
194 : void register_variable_factory(variable_factory::pointer_t factory);
195 : variable::pointer_t get_variable(std::string const & type);
196 :
197 :
198 : #define DEFINE_LOGGER_VARIABLE(type) \
199 : class type##_variable \
200 : : public ::snaplogger::variable \
201 : { \
202 : protected: \
203 : virtual void process_value( \
204 : ::snaplogger::message const & msg \
205 : , std::string & value) const override; \
206 : }; \
207 : class type##_variable_factory final \
208 : : public ::snaplogger::variable_factory \
209 : { \
210 : public: \
211 : type##_variable_factory() \
212 : : variable_factory(#type) \
213 : {} \
214 : virtual ::snaplogger::variable::pointer_t \
215 : create_variable() override final \
216 : { \
217 : return std::make_shared<type##_variable>(); \
218 : } \
219 : }; \
220 : int __attribute__((unused)) \
221 : g_##type##_variable_factory = []() { \
222 : ::snaplogger::register_variable_factory \
223 : (std::make_shared< \
224 : type##_variable_factory>()); \
225 : return 0; \
226 : } (); \
227 : void type##_variable::process_value( \
228 : ::snaplogger::message const & msg \
229 : , std::string & value) const
230 :
231 :
232 :
233 :
234 :
235 :
236 :
237 :
238 :
239 65800 : class function_data
240 : {
241 : public:
242 32900 : void set_value(std::string value)
243 : {
244 32900 : f_value = libutf8::to_u32string(value);
245 32900 : }
246 :
247 0 : void set_value(std::u32string value)
248 : {
249 0 : f_value = value;
250 0 : }
251 :
252 32900 : std::u32string & get_value()
253 : {
254 32900 : return f_value;
255 : }
256 :
257 : void set_param(std::string const & name, std::string const & value)
258 : {
259 : f_params[name] = libutf8::to_u32string(value);
260 : }
261 :
262 0 : void set_param(std::string const & name, std::u32string const & value)
263 : {
264 0 : f_params[name] = value;
265 0 : }
266 :
267 0 : std::u32string get_param(std::string const & name, std::u32string const & default_value)
268 : {
269 0 : auto it(f_params.find(name));
270 0 : if(it == f_params.end())
271 : {
272 0 : return default_value;
273 : }
274 0 : return it->second;
275 : }
276 :
277 : private:
278 : std::u32string f_value = std::u32string();
279 : u8u32string_map_t f_params = u8u32string_map_t();
280 : };
281 :
282 :
283 :
284 :
285 : class function
286 : {
287 : public:
288 : typedef std::shared_ptr<function> pointer_t;
289 :
290 : function(std::string const & function_name);
291 : virtual ~function();
292 :
293 : std::string const & get_name() const;
294 :
295 : virtual void apply(
296 : message const & msg
297 : , function_data & data
298 : , param::pointer_t const & p) = 0;
299 :
300 : private:
301 : std::string const f_name;
302 : };
303 :
304 :
305 : void register_function(function::pointer_t func);
306 :
307 :
308 : #define DECLARE_FUNCTION(name) \
309 : class name##_function : public function \
310 : { \
311 : public: \
312 : name##_function() : function(#name) {} \
313 : virtual void apply( \
314 : ::snaplogger::message const & msg \
315 : , ::snaplogger::function_data & d \
316 : , ::snaplogger::param::pointer_t const & p) override; \
317 : }; \
318 : int __attribute__((unused)) g_##name##_function = []() { \
319 : register_function(std::make_shared<name##_function>()); \
320 : return 0; \
321 : } (); \
322 : void name##_function::apply( \
323 : ::snaplogger::message const & msg \
324 : , ::snaplogger::function_data & d \
325 : , ::snaplogger::param::pointer_t const & p)
326 :
327 :
328 :
329 :
330 :
331 : } // snaplogger namespace
332 : // vim: ts=4 sw=4 et
|