LCOV - code coverage report
Current view: top level - snaplogger - severity.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 101 1.0 %
Date: 2019-08-13 00:35:33 Functions: 2 18 11.1 %
Legend: Lines: hit not hit

          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             : 
      26             : /** \file
      27             :  * \brief Severity levels for your log messages.
      28             :  *
      29             :  * The severity implementation loads the severity configuration file
      30             :  * and generates a set of severity levels that one can attach to
      31             :  * log messages.
      32             :  */
      33             : 
      34             : 
      35             : // self
      36             : //
      37             : #include    "snaplogger/severity.h"
      38             : 
      39             : #include    "snaplogger/exception.h"
      40             : #include    "snaplogger/guard.h"
      41             : #include    "snaplogger/private_logger.h"
      42             : 
      43             : 
      44             : // advgetopt lib
      45             : //
      46             : #include    <advgetopt/advgetopt.h>
      47             : #include    <advgetopt/options.h>
      48             : 
      49             : 
      50             : // C++ lib
      51             : //
      52             : #include    <iostream>
      53             : #include    <map>
      54             : 
      55             : 
      56             : // C lib
      57             : //
      58             : #include    <sys/time.h>
      59             : 
      60             : 
      61             : // last include
      62             : //
      63             : #include    <snapdev/poison.h>
      64             : 
      65             : 
      66             : 
      67             : namespace snaplogger
      68             : {
      69             : 
      70             : 
      71             : 
      72             : namespace
      73             : {
      74             : 
      75             : 
      76             : bool        g_severity_auto_added = false;
      77             : 
      78             : 
      79             : struct system_severity
      80             : {
      81             :     severity_t          f_severity      = severity_t::SEVERITY_ALL;
      82             :     char const *        f_name          = nullptr;
      83             :     char const *        f_alias         = nullptr; // at most 1 alias for system severities
      84             :     char const *        f_description   = nullptr;
      85             :     char const *        f_styles        = nullptr;
      86             : };
      87             : 
      88             : #pragma GCC diagnostic push
      89             : #pragma GCC diagnostic ignored "-Wpedantic"
      90             : constexpr system_severity g_system_severity[] =
      91             : {
      92             :     {
      93             :         .f_severity     = severity_t::SEVERITY_ALL,
      94             :         .f_name         = "all",
      95             :         .f_alias        = nullptr,
      96             :         .f_description  = "everything",
      97             :         .f_styles       = nullptr
      98             :     },
      99             :     {
     100             :         .f_severity     = severity_t::SEVERITY_TRACE,
     101             :         .f_name         = "trace",
     102             :         .f_alias        = nullptr,
     103             :         .f_description  = "trace",
     104             :         .f_styles       = nullptr
     105             :     },
     106             :     {
     107             :         .f_severity     = severity_t::SEVERITY_DEBUG,
     108             :         .f_name         = "debug",
     109             :         .f_alias        = "dbg",
     110             :         .f_description  = "debug",
     111             :         .f_styles       = nullptr
     112             :     },
     113             :     {
     114             :         .f_severity     = severity_t::SEVERITY_NOTICE,
     115             :         .f_name         = "notice",
     116             :         .f_alias        = "note",
     117             :         .f_description  = "notice",
     118             :         .f_styles       = nullptr
     119             :     },
     120             :     {
     121             :         .f_severity     = severity_t::SEVERITY_UNIMPORTANT,
     122             :         .f_name         = "unimportant",
     123             :         .f_alias        = nullptr,
     124             :         .f_description  = "unimportant",
     125             :         .f_styles       = nullptr
     126             :     },
     127             :     {
     128             :         .f_severity     = severity_t::SEVERITY_INFORMATION,
     129             :         .f_name         = "information",
     130             :         .f_alias        = "info",
     131             :         .f_description  = "info",
     132             :         .f_styles       = nullptr
     133             :     },
     134             :     {
     135             :         .f_severity     = severity_t::SEVERITY_IMPORTANT,
     136             :         .f_name         = "important",
     137             :         .f_alias        = "significant",
     138             :         .f_description  = "important",
     139             :         .f_styles       = "green"
     140             :     },
     141             :     {
     142             :         .f_severity     = severity_t::SEVERITY_MINOR,
     143             :         .f_name         = "minor",
     144             :         .f_alias        = nullptr,
     145             :         .f_description  = "minor",
     146             :         .f_styles       = "green"
     147             :     },
     148             :     {
     149             :         .f_severity     = severity_t::SEVERITY_DEPRECATED,
     150             :         .f_name         = "deprecated",
     151             :         .f_alias        = nullptr,
     152             :         .f_description  = "deprecated",
     153             :         .f_styles       = "orange"
     154             :     },
     155             :     {
     156             :         .f_severity     = severity_t::SEVERITY_WARNING,
     157             :         .f_name         = "warning",
     158             :         .f_alias        = "warn",
     159             :         .f_description  = "warn",
     160             :         .f_styles       = "orange"
     161             :     },
     162             :     {
     163             :         .f_severity     = severity_t::SEVERITY_MAJOR,
     164             :         .f_name         = "major",
     165             :         .f_alias        = "paramount",
     166             :         .f_description  = "major",
     167             :         .f_styles       = "orange"
     168             :     },
     169             :     {
     170             :         .f_severity     = severity_t::SEVERITY_RECOVERABLE_ERROR,
     171             :         .f_name         = "recoverable-error",
     172             :         .f_alias        = "recoverable",
     173             :         .f_description  = "recoverable error",
     174             :         .f_styles       = "red"
     175             :     },
     176             :     {
     177             :         .f_severity     = severity_t::SEVERITY_ERROR,
     178             :         .f_name         = "error",
     179             :         .f_alias        = "err",
     180             :         .f_description  = "error",
     181             :         .f_styles       = "red"
     182             :     },
     183             :     {
     184             :         .f_severity     = severity_t::SEVERITY_CRITICAL,
     185             :         .f_name         = "critical",
     186             :         .f_alias        = nullptr,
     187             :         .f_description  = "crit",
     188             :         .f_styles       = "red"
     189             :     },
     190             :     {
     191             :         .f_severity     = severity_t::SEVERITY_ALERT,
     192             :         .f_name         = "alert",
     193             :         .f_alias        = nullptr,
     194             :         .f_description  = "alert",
     195             :         .f_styles       = "red"
     196             :     },
     197             :     {
     198             :         .f_severity     = severity_t::SEVERITY_EMERGENCY,
     199             :         .f_name         = "emergency",
     200             :         .f_alias        = "emerg",
     201             :         .f_description  = "emerg",
     202             :         .f_styles       = "red"
     203             :     },
     204             :     {
     205             :         .f_severity     = severity_t::SEVERITY_FATAL,
     206             :         .f_name         = "fatal",
     207             :         .f_alias        = nullptr,
     208             :         .f_description  = "fatal",
     209             :         .f_styles       = "red"
     210             :     },
     211             :     {
     212             :         .f_severity     = severity_t::SEVERITY_OFF,
     213             :         .f_name         = "off",
     214             :         .f_alias        = nullptr,
     215             :         .f_description  = "off",
     216             :         .f_styles       = nullptr
     217             :     }
     218             : };
     219             : 
     220             : 
     221             : 
     222             : 
     223             : advgetopt::options_environment g_config_option =
     224             : {
     225             :     .f_project_name = "logger",
     226             :     .f_options = nullptr,
     227             :     .f_options_files_directory = "/etc/snapwebsites/logger",
     228             :     .f_environment_variable_name = nullptr,
     229             :     .f_configuration_files = nullptr,
     230             :     .f_configuration_filename = "severity.ini",
     231             :     .f_configuration_directories = nullptr,
     232             :     .f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS
     233             : 
     234             :     //.f_help_header = nullptr,
     235             :     //.f_help_footer = nullptr,
     236             :     //.f_version = nullptr,
     237             :     //.f_license = nullptr,
     238             :     //.f_copyright = nullptr,
     239             :     //.f_build_date = UTC_BUILD_DATE,
     240             :     //.f_build_time = UTC_BUILD_TIME,
     241             :     //.f_groups = nullptr
     242             : };
     243             : #pragma GCC diagnostic pop
     244             : 
     245             : 
     246             : 
     247           0 : void auto_add_severities()
     248             : {
     249           0 :     guard g;
     250             : 
     251           0 :     if(g_severity_auto_added)
     252             :     {
     253           0 :         return;
     254             :     }
     255           0 :     g_severity_auto_added = true;
     256             : 
     257           0 :     private_logger::pointer_t l(get_private_logger());
     258             : 
     259           0 :     for(auto ss : g_system_severity)
     260             :     {
     261           0 :         severity::pointer_t sev(std::make_shared<severity>(ss.f_severity, ss.f_name, true));
     262           0 :         if(ss.f_alias != nullptr)
     263             :         {
     264             :             // at this time we have one at the most here
     265             :             //
     266           0 :             sev->add_alias(ss.f_alias);
     267             :         }
     268           0 :         sev->set_description(ss.f_description);
     269           0 :         if(ss.f_styles != nullptr)
     270             :         {
     271           0 :             sev->set_styles(ss.f_styles);
     272             :         }
     273             : 
     274           0 :         l->add_severity(sev);
     275             :     }
     276             : 
     277             :     // load user editable parameters
     278             :     //
     279           0 :     advgetopt::getopt::pointer_t config(std::make_shared<advgetopt::getopt>(g_config_option));
     280           0 :     config->parse_configuration_files();
     281           0 :     advgetopt::option_info::map_by_name_t options(config->get_options());
     282           0 :     for(auto o : options)
     283             :     {
     284           0 :         std::string const name(o.second->get_name());
     285           0 :         std::string const basename(o.second->get_basename());
     286           0 :         if(name == basename)
     287             :         {
     288             :             // we found a section name, this is the name of a severity,
     289             :             // gather the info and create the new severity
     290             :             //
     291           0 :             severity::pointer_t sev(get_severity(name));
     292           0 :             if(sev != nullptr)
     293             :             {
     294             :                 // it already exists...
     295             :                 //
     296           0 :                 if(sev->is_system())
     297             :                 {
     298           0 :                     std::string const severity_field(name + "::severity");
     299           0 :                     if(config->is_defined(severity_field))
     300             :                     {
     301           0 :                         long const level(o.second->get_long());
     302           0 :                         if(level < 0 || level > 255)
     303             :                         {
     304           0 :                             throw invalid_severity("severity level must be between 0 and 255.");
     305             :                         }
     306           0 :                         if(static_cast<severity_t>(level) != sev->get_severity())
     307             :                         {
     308           0 :                             throw invalid_severity("severity level of a system entry cannot be changed.");
     309             :                         }
     310             :                     }
     311             :                 }
     312             :                 else
     313             :                 {
     314             :                     throw duplicate_error("we found two severity levels named \""
     315           0 :                                          + name
     316           0 :                                          + "\" in your severity.ini file.");
     317             :                 }
     318             :             }
     319             :             else
     320             :             {
     321           0 :                 std::string const severity_field(name + "::severity");
     322           0 :                 if(!config->is_defined(severity_field))
     323             :                 {
     324           0 :                     throw invalid_severity("severity level must be defined for non-system severity entries.");
     325             :                 }
     326           0 :                 long const level(config->get_long(severity_field));
     327           0 :                 if(level < 0 || level > 255)
     328             :                 {
     329             :                     throw invalid_severity("severity level must be between 0 and 255, "
     330           0 :                                          + std::to_string(level)
     331           0 :                                          + " is not valid.");
     332             :                 }
     333             : 
     334           0 :                 sev = get_severity(static_cast<severity_t>(level));
     335           0 :                 if(sev != nullptr)
     336             :                 {
     337             :                     throw duplicate_error("there is another severity with level "
     338           0 :                                          + std::to_string(level)
     339           0 :                                          + ", try using aliases=... instead.");
     340             :                 }
     341             : 
     342           0 :                 sev = std::make_shared<severity>(static_cast<severity_t>(level), name);
     343           0 :                 l->add_severity(sev);
     344             :             }
     345             : 
     346           0 :             std::string const aliases_field(name + "::aliases");
     347           0 :             if(config->is_defined(aliases_field))
     348             :             {
     349           0 :                 std::string const aliases(config->get_string(aliases_field));
     350           0 :                 advgetopt::string_list_t names;
     351           0 :                 advgetopt::split_string(aliases, names, {","});
     352           0 :                 for(auto n : names)
     353             :                 {
     354           0 :                     sev->add_alias(n);
     355             :                 }
     356             :             }
     357             : 
     358           0 :             std::string const description_field(name + "::description");
     359           0 :             if(config->is_defined(description_field))
     360             :             {
     361           0 :                 sev->set_description(config->get_string(description_field));
     362             :             }
     363             : 
     364           0 :             std::string const styles_field(name + "::styles");
     365           0 :             if(config->is_defined(styles_field))
     366             :             {
     367           0 :                 sev->set_styles(config->get_string(styles_field));
     368             :             }
     369             :         }
     370             :     }
     371             : }
     372             : 
     373             : 
     374             : 
     375             : }
     376             : // no name namespace
     377             : 
     378             : 
     379             : 
     380             : 
     381           0 : severity::severity(severity_t sev, std::string const & name, bool system)
     382             :     : f_severity(sev)
     383           0 :     , f_names(string_vector_t({name}))
     384           0 :     , f_system(system)
     385             : {
     386           0 : }
     387             : 
     388             : 
     389           0 : severity_t severity::get_severity() const
     390             : {
     391           0 :     return f_severity;
     392             : }
     393             : 
     394             : 
     395           0 : bool severity::is_system() const
     396             : {
     397           0 :     return f_system;
     398             : }
     399             : 
     400             : 
     401           0 : std::string severity::get_name() const
     402             : {
     403           0 :     return f_names[0];
     404             : }
     405             : 
     406             : 
     407           0 : void severity::add_alias(std::string const & name)
     408             : {
     409           0 :     f_names.push_back(name);
     410           0 : }
     411             : 
     412             : 
     413           0 : string_vector_t severity::get_all_names() const
     414             : {
     415           0 :     return f_names;
     416             : }
     417             : 
     418             : 
     419           0 : void severity::set_description(std::string const & description)
     420             : {
     421           0 :     f_description = description;
     422           0 : }
     423             : 
     424             : 
     425           0 : std::string severity::get_description() const
     426             : {
     427           0 :     return f_description;
     428             : }
     429             : 
     430             : 
     431           0 : void severity::set_styles(std::string const & color)
     432             : {
     433           0 :     f_styles = color;
     434           0 : }
     435             : 
     436             : 
     437           0 : std::string severity::get_styles() const
     438             : {
     439           0 :     return f_styles;
     440             : }
     441             : 
     442             : 
     443             : 
     444             : 
     445             : 
     446           0 : void add_severity(severity::pointer_t sev)
     447             : {
     448           0 :     auto_add_severities();
     449           0 :     get_private_logger()->add_severity(sev);
     450           0 : }
     451             : 
     452             : 
     453           0 : severity::pointer_t get_severity(std::string const & name)
     454             : {
     455           0 :     auto_add_severities();
     456           0 :     return get_private_logger()->get_severity(name);
     457             : }
     458             : 
     459             : 
     460           0 : severity::pointer_t get_severity(message const & msg, std::string const & name)
     461             : {
     462           0 :     auto_add_severities();
     463           0 :     return get_private_logger(msg)->get_severity(name);
     464             : }
     465             : 
     466             : 
     467           0 : severity::pointer_t get_severity(severity_t sev)
     468             : {
     469           0 :     auto_add_severities();
     470           0 :     return get_private_logger()->get_severity(sev);
     471             : }
     472             : 
     473             : 
     474           0 : severity::pointer_t get_severity(message const & msg, severity_t sev)
     475             : {
     476           0 :     auto_add_severities();
     477           0 :     return get_private_logger(msg)->get_severity(sev);
     478             : }
     479             : 
     480             : 
     481             : 
     482           6 : } // snaplogger namespace
     483             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.12