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