LCOV - code coverage report
Current view: top level - snaplogger - variable.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 3 100.0 %
Date: 2021-08-20 16:41:45 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2013-2021  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         204 : 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         229 : 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       93982 : 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

Generated by: LCOV version 1.13