LCOV - code coverage report
Current view: top level - snaplogger - variable.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 102 104 98.1 %
Date: 2021-06-01 17:16:42 Functions: 36 43 83.7 %
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             : 
      20             : /** \file
      21             :  * \brief Variables are used to dynamically add parameters to log messages.
      22             :  *
      23             :  * This file declares the base variable class.
      24             :  *
      25             :  * The format defines \em functions which are written as in
      26             :  * `${function-name}`.
      27             :  *
      28             :  * Parameters can be passed to these functions by adding `:<param>`
      29             :  * to those definitions. These are named parameters and their default
      30             :  * value is "present" or not. A specific value can be assignd using
      31             :  * the equal sign as in `:param=<value>`.
      32             :  *
      33             :  * For example, the date function can be called as follow:
      34             :  *
      35             :  * \code
      36             :  *     ${date:year:align=right:exact_width=2}
      37             :  * \endcode
      38             :  *
      39             :  * The `year` parameter is specific to the `date` function. The other
      40             :  * parameters are available whatever the function. This variable asks
      41             :  * to truncate the year to 2 character right aligned (i.e. "18" in
      42             :  * "2018".)
      43             :  *
      44             :  * In C, this would look something like:
      45             :  *
      46             :  * \code
      47             :  *     date(FLAG_YEAR, ALIGN_RIGHT, 2);
      48             :  * \endcode
      49             :  */
      50             : 
      51             : 
      52             : // self
      53             : //
      54             : #include    "snaplogger/variable.h"
      55             : 
      56             : #include    "snaplogger/exception.h"
      57             : #include    "snaplogger/guard.h"
      58             : #include    "snaplogger/private_logger.h"
      59             : 
      60             : 
      61             : // libutf8 lib
      62             : //
      63             : #include    <libutf8/libutf8.h>
      64             : 
      65             : 
      66             : // C++ lib
      67             : //
      68             : #include    <iostream>
      69             : #include    <queue>
      70             : 
      71             : 
      72             : // last include
      73             : //
      74             : #include    <snapdev/poison.h>
      75             : 
      76             : 
      77             : 
      78             : namespace snaplogger
      79             : {
      80             : 
      81             : 
      82             : 
      83             : namespace
      84             : {
      85             : 
      86             : 
      87             : 
      88             : 
      89             : 
      90         425 : DEFINE_LOGGER_VARIABLE(direct)
      91             : {
      92         123 :     snap::NOTUSED(msg);
      93             : 
      94             :     // apply all our parameters as is
      95             :     //
      96         246 :     auto const & params(get_params());
      97         246 :     for(auto p : params)
      98             :     {
      99         123 :         value += p->get_value();
     100             :     }
     101             : 
     102             :     // do NOT apply parameters further, the user has no access to those
     103             :     // anyway; this is the direct text we find in between variables
     104             :     //
     105             :     //variable::process_value(msg, value);
     106         123 : }
     107             : 
     108             : 
     109             : 
     110             : }
     111             : // no name namespace
     112             : 
     113             : 
     114             : 
     115             : //////////////////////////////
     116             : // PARAM
     117             : //
     118             : 
     119         194 : param::param(std::string const & name)
     120         195 :     : f_name(name)
     121             : {
     122         194 :     if(f_name.empty())
     123             :     {
     124           1 :         throw invalid_parameter("a parameter must have a non-empty name.");
     125             :     }
     126         193 : }
     127             : 
     128             : 
     129         137 : std::string const & param::get_name() const
     130             : {
     131         137 :     return f_name;
     132             : }
     133             : 
     134             : 
     135          20 : param::type_t param::get_type() const
     136             : {
     137          20 :     return f_type;
     138             : }
     139             : 
     140             : 
     141         203 : std::string param::get_value() const
     142             : {
     143         203 :     if(f_type != type_t::TYPE_STRING)
     144             :     {
     145             :         // TBD: we may instead want to return the integer as a string
     146             :         //
     147             :         throw invalid_parameter(
     148             :                   "the ${...:"
     149           2 :                 + f_name
     150           3 :                 + "=<value>} parameter must be a valid string (not an integer).");
     151             :     }
     152         202 :     return f_value;
     153             : }
     154             : 
     155             : 
     156         154 : void param::set_value(std::string const & value)
     157             : {
     158         154 :     f_value = value;
     159         154 :     f_type = type_t::TYPE_STRING;
     160         154 : }
     161             : 
     162             : 
     163          27 : int64_t param::get_integer() const
     164             : {
     165          27 :     if(f_type != type_t::TYPE_INTEGER)
     166             :     {
     167             :         // TBD: we may want to check whether the string represents a valid
     168             :         //      integer first and return that if so
     169             :         //
     170             :         throw invalid_parameter(
     171             :                   "the ${...:"
     172           2 :                 + f_name
     173           3 :                 + "=<value>} parameter must be a valid integer.");
     174             :     }
     175          26 :     return f_integer;
     176             : }
     177             : 
     178             : 
     179          30 : void param::set_integer(std::int64_t integer)
     180             : {
     181          30 :     f_integer = integer;
     182          30 :     f_type = type_t::TYPE_INTEGER;
     183          30 : }
     184             : 
     185             : 
     186             : 
     187             : 
     188             : 
     189             : //////////////////////////////
     190             : // VARIABLE
     191             : //
     192             : 
     193         217 : variable::~variable()
     194             : {
     195         217 : }
     196             : 
     197             : 
     198           0 : bool variable::ignore_on_no_repeat() const
     199             : {
     200           0 :     return false;
     201             : }
     202             : 
     203             : 
     204         193 : void variable::add_param(param::pointer_t p)
     205             : {
     206         386 :     guard g;
     207             : 
     208         193 :     f_params.push_back(p);
     209         193 : }
     210             : 
     211             : 
     212         188 : param::vector_t variable::get_params() const
     213             : {
     214         376 :     guard g;
     215             : 
     216         376 :     return f_params;
     217             : }
     218             : 
     219             : 
     220       47392 : std::string variable::get_value(message const & msg) const
     221             : {
     222       94784 :     guard g;
     223             : 
     224       47392 :     std::string value;
     225       47392 :     process_value(msg, value);
     226       94774 :     return value;
     227             : }
     228             : 
     229             : 
     230       47267 : void variable::process_value(message const & msg, std::string & value) const
     231             : {
     232       94534 :     auto l(get_private_logger(msg));
     233             : 
     234             :     {
     235       94534 :         guard g;
     236             : 
     237       47267 :         if(!l->has_functions())
     238             :         {
     239             :             // no functions available, we're done
     240             :             return;     // LCOV_EXCL_LINE
     241             :         }
     242             :     }
     243             : 
     244       94534 :     function_data d;
     245       47267 :     d.set_value(value);
     246             : 
     247       47363 :     for(auto p : f_params)
     248             :     {
     249          96 :         std::string const & name(p->get_name());
     250         192 :         auto func(l->get_function(name));
     251          96 :         if(func != nullptr)
     252             :         {
     253          73 :             func->apply(msg, d, p);
     254             :         }
     255             :         // else -- ignore missing functions
     256             :     }
     257             : 
     258       47262 :     value = libutf8::to_u8string(d.get_value());
     259             : }
     260             : 
     261             : 
     262             : 
     263             : 
     264             : 
     265             : 
     266             : 
     267             : 
     268             : 
     269             : 
     270             : 
     271             : //////////////////////////////
     272             : // VARIABLE FACTORY
     273             : //
     274             : 
     275          61 : variable_factory::variable_factory(std::string const & type)
     276          61 :     : f_type(type)
     277             : {
     278          61 : }
     279             : 
     280             : 
     281          61 : variable_factory::~variable_factory()
     282             : {
     283          61 : }
     284             : 
     285             : 
     286         122 : std::string const & variable_factory::get_type() const
     287             : {
     288         122 :     return f_type;
     289             : }
     290             : 
     291             : 
     292             : 
     293             : 
     294          61 : void register_variable_factory(variable_factory::pointer_t factory)
     295             : {
     296          62 :     get_private_logger()->register_variable_factory(factory);
     297          60 : }
     298             : 
     299             : 
     300             : 
     301         218 : variable::pointer_t get_variable(std::string const & type)
     302             : {
     303         218 :     return get_private_logger()->get_variable(type);
     304             : }
     305             : 
     306             : 
     307             : 
     308             : 
     309             : 
     310             : 
     311             : 
     312             : //////////////////////////////
     313             : // FUNCTION DATA
     314             : //
     315             : 
     316       47267 : void function_data::set_value(std::string value)
     317             : {
     318       47267 :     f_value = libutf8::to_u32string(value);
     319       47267 : }
     320             : 
     321          26 : void function_data::set_value(std::u32string value)
     322             : {
     323          26 :     f_value = value;
     324          26 : }
     325             : 
     326       47321 : std::u32string & function_data::get_value()
     327             : {
     328       47321 :     return f_value;
     329             : }
     330             : 
     331          16 : void function_data::set_param(std::string const & name, std::string const & value)
     332             : {
     333          16 :     f_params[name] = libutf8::to_u32string(value);
     334          16 : }
     335             : 
     336          18 : void function_data::set_param(std::string const & name, std::u32string const & value)
     337             : {
     338          18 :     f_params[name] = value;
     339          18 : }
     340             : 
     341          26 : std::u32string function_data::get_param(std::string const & name, std::u32string const & default_value)
     342             : {
     343          26 :     auto it(f_params.find(name));
     344          26 :     if(it == f_params.end())
     345             :     {
     346           1 :         return default_value;
     347             :     }
     348          25 :     return it->second;
     349             : }
     350             : 
     351             : 
     352             : 
     353             : 
     354             : 
     355             : //////////////////////////////
     356             : // FUNCTION
     357             : //
     358             : 
     359          23 : function::function(std::string const & function_name)
     360          23 :     : f_name(function_name)
     361             : {
     362          23 : }
     363             : 
     364             : 
     365          23 : function::~function()
     366             : {
     367          23 : }
     368             : 
     369             : 
     370          46 : std::string const & function::get_name() const
     371             : {
     372          46 :     return f_name;
     373             : }
     374             : 
     375             : 
     376             : 
     377          23 : void register_function(function::pointer_t func)
     378             : {
     379          46 :     guard g;
     380             : 
     381          24 :     get_private_logger()->register_function(func);
     382          22 : }
     383             : 
     384             : 
     385             : 
     386             : 
     387           6 : } // snaplogger namespace
     388             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13