LCOV - code coverage report
Current view: top level - snaplogger - options.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 107 233 45.9 %
Date: 2022-07-01 22:43:09 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2013-2022  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 Handle logger specific command line and other options.
      22             :  *
      23             :  * The logger supports a few options to override configuration files
      24             :  * and tweak settings from the command line. Since the user is in
      25             :  * control of the environment variable, we do not offer that option
      26             :  * here.
      27             :  */
      28             : 
      29             : 
      30             : // self
      31             : //
      32             : #include    "snaplogger/options.h"
      33             : 
      34             : #include    "snaplogger/private_logger.h"
      35             : #include    "snaplogger/map_diagnostic.h"
      36             : #include    "snaplogger/version.h"
      37             : 
      38             : 
      39             : // boost lib
      40             : //
      41             : #include    <boost/algorithm/string/replace.hpp>
      42             : 
      43             : 
      44             : // advgetopt lib
      45             : //
      46             : #include    <advgetopt/exception.h>
      47             : 
      48             : 
      49             : // cppthread lib
      50             : //
      51             : #include    <cppthread/log.h>
      52             : 
      53             : 
      54             : // last include
      55             : //
      56             : #include    <snapdev/poison.h>
      57             : 
      58             : 
      59             : 
      60             : namespace snaplogger
      61             : {
      62             : 
      63             : 
      64             : namespace
      65             : {
      66             : 
      67             : 
      68             : 
      69             : /** \brief The command line options that the logger adds.
      70             :  *
      71             :  * This variable holds the list of options that the logger adds when you
      72             :  * call the add_logger_options() function. These allows us to have the
      73             :  * same command line options in all the tools we develop with the snaplogger.
      74             :  *
      75             :  * The options are:
      76             :  *
      77             :  * * no-log
      78             :  * * log-file
      79             :  * * log-config
      80             :  * * syslog
      81             :  * * console
      82             :  * * logger-show-banner
      83             :  * * logger-hide-banner
      84             :  * * log-config-path
      85             :  * * debug
      86             :  * * trace
      87             :  * * list-severities
      88             :  * * log-severity
      89             :  * * force-severity
      90             :  * * log-component
      91             :  * * logger-version
      92             :  * * logger-configuration-filenames
      93             :  * * logger-plugin-paths
      94             :  */
      95             : advgetopt::option const g_options[] =
      96             : {
      97             :     // PLUGINS
      98             :     //
      99             :     advgetopt::define_option(
     100             :           advgetopt::Name("logger-plugin-paths")
     101             :         , advgetopt::Flags(advgetopt::all_flags<
     102             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     103             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     104             :         , advgetopt::Help("one or more paths separated by colons (:) to snaplogger plugins.")
     105             :     ),
     106             : 
     107             :     // DIRECT SELECT
     108             :     //
     109             :     advgetopt::define_option(
     110             :           advgetopt::Name("no-log")
     111             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     112             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     113             :         , advgetopt::Help("do not log anything.")
     114             :     ),
     115             :     advgetopt::define_option(
     116             :           advgetopt::Name("log-file")
     117             :         , advgetopt::Flags(advgetopt::command_flags<
     118             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     119             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     120             :         , advgetopt::Help("log data to this specific log files")
     121             :     ),
     122             :     advgetopt::define_option(
     123             :           advgetopt::Name("log-config")
     124             :         , advgetopt::Flags(advgetopt::command_flags<
     125             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     126             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     127             :         , advgetopt::Help("only load this specific configuration file.")
     128             :     ),
     129             :     advgetopt::define_option(
     130             :           advgetopt::Name("syslog")
     131             :         , advgetopt::Flags(advgetopt::command_flags<
     132             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     133             :         , advgetopt::Help("send the logs to syslog only, the argument, if specified, is the name to use as the identity.")
     134             :     ),
     135             :     advgetopt::define_option(
     136             :           advgetopt::Name("console")
     137             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     138             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     139             :         , advgetopt::Help("print the logs out to the console.")
     140             :     ),
     141             :     advgetopt::define_option(
     142             :           advgetopt::Name("logger-show-banner")
     143             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     144             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     145             :         , advgetopt::Help("show a banner on startup with the tool name and version.")
     146             :     ),
     147             :     advgetopt::define_option(
     148             :           advgetopt::Name("logger-hide-banner")
     149             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     150             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     151             :         , advgetopt::Help("do not show the banner (--logger-show-banner has priority if specified).")
     152             :     ),
     153             : 
     154             :     // ALTERNATIVE CONFIG FILES
     155             :     //
     156             :     advgetopt::define_option(
     157             :           advgetopt::Name("log-config-path")
     158             :         , advgetopt::Flags(advgetopt::all_flags<
     159             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     160             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     161             :         , advgetopt::Help("the path to the configuration folders.")
     162             :     ),
     163             : 
     164             :     // SEVERITY
     165             :     //
     166             :     advgetopt::define_option(
     167             :           advgetopt::Name("debug")
     168             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     169             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     170             :         , advgetopt::Help("change the logger severity level of each appender to DEBUG.")
     171             :     ),
     172             :     advgetopt::define_option(
     173             :           advgetopt::Name("trace")
     174             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     175             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     176             :         , advgetopt::Help("change the logger severity level of each appender to TRACE.")
     177             :     ),
     178             :     advgetopt::define_option(
     179             :           advgetopt::Name("log-severity")
     180             :         , advgetopt::Flags(advgetopt::command_flags<
     181             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     182             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     183             :         , advgetopt::Help("reduce the severity level of each appender to the specified level unless it is already lower.")
     184             :     ),
     185             :     advgetopt::define_option(
     186             :           advgetopt::Name("force-severity")
     187             :         , advgetopt::Flags(advgetopt::command_flags<
     188             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     189             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     190             :         , advgetopt::Help("change the logger severity level of each appender to the specified level.")
     191             :     ),
     192             : 
     193             :     // FILTERS
     194             :     //
     195             :     advgetopt::define_option(
     196             :           advgetopt::Name("log-component")
     197             :         , advgetopt::Flags(advgetopt::command_flags<
     198             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     199             :                     , advgetopt::GETOPT_FLAG_MULTIPLE
     200             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     201             :         , advgetopt::Help("filter logs by component, use ! in front of a name to prevent those logs.")
     202             :     ),
     203             : 
     204             :     // LIBEXCEPT EXTENSION
     205             :     //
     206             :     advgetopt::define_option(
     207             :           advgetopt::Name("except-stack-collect")
     208             :         , advgetopt::Flags(advgetopt::command_flags<
     209             :                       advgetopt::GETOPT_FLAG_GROUP_OPTIONS
     210             :                     , advgetopt::GETOPT_FLAG_REQUIRED>())
     211             :         , advgetopt::DefaultValue("yes")
     212             :         , advgetopt::Help("what to collect from the stack on an exception: no, yes or simple, complete.")
     213             :     ),
     214             : 
     215             :     // COMMANDS
     216             :     //
     217             :     advgetopt::define_option(
     218             :           advgetopt::Name("list-appenders")
     219             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     220             :                       advgetopt::GETOPT_FLAG_GROUP_COMMANDS>())
     221             :         , advgetopt::Help("show the list of available log appenders.")
     222             :     ),
     223             :     advgetopt::define_option(
     224             :           advgetopt::Name("list-severities")
     225             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     226             :                       advgetopt::GETOPT_FLAG_GROUP_COMMANDS>())
     227             :         , advgetopt::Help("show the list of available log severities.")
     228             :     ),
     229             :     advgetopt::define_option(
     230             :           advgetopt::Name("logger-version")
     231             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     232             :                       advgetopt::GETOPT_FLAG_GROUP_COMMANDS>())
     233             :         , advgetopt::Help("show the version of the logger library.")
     234             :     ),
     235             :     advgetopt::define_option(
     236             :           advgetopt::Name("logger-configuration-filenames")
     237             :         , advgetopt::Flags(advgetopt::standalone_command_flags<
     238             :                       advgetopt::GETOPT_FLAG_GROUP_COMMANDS>())
     239             :         , advgetopt::Help("show the list of configuration filenames that would be loaded with the current options.")
     240             :     ),
     241             : 
     242             :     // END
     243             :     //
     244             :     advgetopt::end_options()
     245             : };
     246             : 
     247             : 
     248             : 
     249             : 
     250             : }
     251             : // no name namespace
     252             : 
     253             : 
     254             : /** \brief Add the logger command line options.
     255             :  *
     256             :  * This function automatically adds the logger specific command line options
     257             :  * to the \p opts object.
     258             :  *
     259             :  * The options allow for some logger specific tweaking in all your
     260             :  * applications without having to do that on a per application basis.
     261             :  * It also makes use of some command line options which you should not
     262             :  * overload.
     263             :  *
     264             :  * On top of the command line option additions, the function automatically
     265             :  * adds up to four new diagnostics:
     266             :  *
     267             :  * * DIAG_KEY_VERSION -- the version of the tool
     268             :  * * DIAG_KEY_BUILD_DATE -- the build date of the tool
     269             :  * * DIAG_KEY_BUILD_TIME -- the build time of the tool
     270             :  * * DIAG_KEY_PROJECT_NAME -- the name of the project
     271             :  *
     272             :  * The project name is always added. The other parameters are added only
     273             :  * if found in the \p opts environment variables.
     274             :  *
     275             :  * \param[in,out] opts  The options to tweak with the logger options.
     276             :  */
     277           1 : void add_logger_options(advgetopt::getopt & opts)
     278             : {
     279           1 :     auto env(opts.get_options_environment());
     280           1 :     if(env.f_version != nullptr)
     281             :     {
     282           1 :         set_diagnostic(DIAG_KEY_VERSION, env.f_version);
     283             :     }
     284           1 :     if(env.f_build_date != nullptr)
     285             :     {
     286           1 :         set_diagnostic(DIAG_KEY_BUILD_DATE, env.f_build_date);
     287             :     }
     288           1 :     if(env.f_build_time != nullptr)
     289             :     {
     290           1 :         set_diagnostic(DIAG_KEY_BUILD_TIME, env.f_build_time);
     291             :     }
     292           1 :     set_diagnostic(DIAG_KEY_PROJECT_NAME, opts.get_project_name());
     293             : 
     294           1 :     opts.parse_options_info(g_options, true);
     295           1 : }
     296             : 
     297             : 
     298             : 
     299             : 
     300             : /** \brief Process the logger options.
     301             :  *
     302             :  * This function is expected to be called before you move forward with
     303             :  * the other work you want to do in your tool. It allows for processing
     304             :  * any and all the logger command line options.
     305             :  *
     306             :  * To use this command, you first want to call the add_logger_options()
     307             :  * function, process the arguments, and finally call this function as
     308             :  * follow:
     309             :  *
     310             :  * \code
     311             :  *     my_app::my_app(int argc, char * argv[])
     312             :  *         : f_opt(g_options_environment)
     313             :  *     {
     314             :  *         snaplogger::add_logger_options(f_opt);
     315             :  *         f_opt.finish_parsing(argc, argv);
     316             :  *         if(!snaplogger::process_logger_options(f_opt, "/etc/my-app/logger"))
     317             :  *         {
     318             :  *             // exit on any error
     319             :  *             throw advgetopt::getopt_exit("logger options generated an error.", 0);
     320             :  *         }
     321             :  *
     322             :  *         ...
     323             :  *     }
     324             :  * \endcode
     325             :  *
     326             :  * \exception advgetopt::getopt_exit
     327             :  * Some commands emit this exception which means that the process is done.
     328             :  * It is expected to quickly and silently exit after catching this
     329             :  * exception.
     330             :  *
     331             :  * \todo
     332             :  * See whether we can change the cppthread::log to a SNAP_LOG_... when
     333             :  * sending errors.
     334             :  *
     335             :  * \param[in] opts  The option definitions and values.
     336             :  * \param[in] config_path  A path where the logger configuration files are
     337             :  * to be searched. The logger also searches under `/usr/share/snaplogger/etc`
     338             :  * prior and `~/.config/<tool-name>/logger` after.
     339             :  * \param[in] out  The output stream to use in case the command is to generate
     340             :  * output to the user. Defaults to `std::cout`.
     341             :  * \param[in] show_banner  Whether to show the banner. For CLI and GUI tools,
     342             :  * you may want to hide this banner. For daemons, it is customary to leave
     343             :  * the banner as it just goes to a log file.
     344             :  *
     345             :  * \return true of success, false when an error occurs. You are expected to
     346             :  * stop your process immediately when this function returns false, but this
     347             :  * is not mandatory.
     348             :  */
     349           1 : bool process_logger_options(advgetopt::getopt & opts
     350             :                           , std::string const & config_path
     351             :                           , std::basic_ostream<char> & out
     352             :                           , bool show_banner)
     353             : {
     354           1 :     constexpr int const OPTION_NO_LOG           = 0x001;
     355           1 :     constexpr int const OPTION_LOG_FILE         = 0x002;
     356           1 :     constexpr int const OPTION_LOG_CONFIG       = 0x004;
     357           1 :     constexpr int const OPTION_SYSLOG           = 0x008;
     358           1 :     constexpr int const OPTION_CONSOLE          = 0x010;
     359             : 
     360           1 :     constexpr int const OPTION_TRACE_SEVERITY   = 0x020;
     361           1 :     constexpr int const OPTION_DEBUG_SEVERITY   = 0x040;
     362           1 :     constexpr int const OPTION_LOG_SEVERITY     = 0x080;
     363           1 :     constexpr int const OPTION_FORCE_SEVERITY   = 0x100;
     364             : 
     365           1 :     bool result(true);
     366             : 
     367           1 :     set_diagnostic(DIAG_KEY_PROGNAME, opts.get_program_name());
     368             : 
     369             :     // DYNAMIC INITIALIZATION
     370             :     //
     371           2 :     std::string plugin_paths(logger::default_plugin_paths());
     372           1 :     if(opts.is_defined("logger-plugin-paths"))
     373             :     {
     374           0 :         plugin_paths = opts.get_string("logger-plugin-paths");
     375             :     }
     376           1 :     logger::get_instance()->load_plugins(plugin_paths);
     377             : 
     378             :     // COMMANDS
     379             :     //
     380           1 :     if(opts.is_defined("logger-version"))
     381             :     {
     382           0 :         out << snaplogger::get_version_string() << std::endl;
     383           0 :         throw advgetopt::getopt_exit("--logger-version command processed.", 0);
     384             :     }
     385           1 :     if(opts.is_defined("list-appenders"))
     386             :     {
     387           0 :         out << "List of available appenders:\n";
     388           0 :         appender_factory_t const list(get_private_logger()->appender_factory_list());
     389           0 :         for(auto const & it : list)
     390             :         {
     391           0 :             out << " . " << it.first << " (" << it.second->get_type() << ")\n";
     392             :         }
     393           0 :         out << std::endl;
     394           0 :         throw advgetopt::getopt_exit("--list-appenders command processed.", 0);
     395             :     }
     396           1 :     if(opts.is_defined("list-severities"))
     397             :     {
     398           0 :         out << "List of the snaplogger known severities:\n";
     399             : 
     400           0 :         severity_by_severity_t const list(get_severities_by_severity());
     401           0 :         for(auto const & it : list)
     402             :         {
     403           0 :             string_vector_t const names(it.second->get_all_names());
     404           0 :             char const * sep = " . ";
     405           0 :             for(auto const & s : names)
     406             :             {
     407           0 :                 out << sep << s;
     408           0 :                 sep = ", ";
     409             :             }
     410             : 
     411           0 :             out << " [" << static_cast<int>(it.first);
     412           0 :             if(it.second->is_system())
     413             :             {
     414           0 :                 out << "/system";
     415             :             }
     416           0 :             if(!it.second->get_styles().empty())
     417             :             {
     418           0 :                 out << "/styles";
     419             :             }
     420           0 :             out << ']';
     421             : 
     422             :             //std::string const d(it.second->get_description());
     423             :             //if(!d.empty())
     424             :             //{
     425             :             //    out << " -- " << d;
     426             :             //}
     427             : 
     428           0 :             out << '\n';
     429             :         }
     430           0 :         out << std::endl;
     431           0 :         throw advgetopt::getopt_exit("--list-severities command processed.", 0);
     432             :     }
     433             : 
     434             :     // LOG CONFIG
     435             :     //
     436           1 :     int log_config(0);
     437           1 :     if(opts.is_defined("no-log"))
     438             :     {
     439           0 :         log_config |= OPTION_NO_LOG;
     440             :     }
     441           1 :     if(opts.is_defined("log-file"))
     442             :     {
     443           0 :         log_config |= OPTION_LOG_FILE;
     444             :     }
     445           1 :     if(opts.is_defined("log-config"))
     446             :     {
     447           0 :         log_config |= OPTION_LOG_CONFIG;
     448             :     }
     449           1 :     if(opts.is_defined("syslog"))
     450             :     {
     451           0 :         log_config |= OPTION_SYSLOG;
     452             :     }
     453           1 :     if(opts.is_defined("console"))
     454             :     {
     455           0 :         log_config |= OPTION_CONSOLE;
     456             :     }
     457           1 :     if(opts.is_defined("logger-show-banner"))
     458             :     {
     459           0 :         show_banner = true;
     460             :     }
     461           1 :     else if(opts.is_defined("logger-hide-banner"))
     462             :     {
     463           0 :         show_banner = false;
     464             :     }
     465             : 
     466           1 :     bool const show_logger_configuration_files(opts.is_defined("logger-configuration-filenames"));
     467           1 :     switch(log_config)
     468             :     {
     469           1 :     case 0:
     470             :         // defaults apply as normal
     471             : 
     472             :         {
     473           1 :             advgetopt::options_environment opt_env;
     474             : 
     475           2 :             std::string user_config("~/.config/");
     476           1 :             user_config += opts.get_project_name();
     477           1 :             user_config += "/logger";
     478           1 :             char const * config_dirs[] =
     479             :             {
     480             :                   "/usr/share/snaplogger/etc"
     481           1 :                 , config_path.c_str()
     482           1 :                 , user_config.c_str()
     483             :                 , nullptr
     484           2 :             };
     485             : 
     486           1 :             if(opts.is_defined("log-config-path"))
     487             :             {
     488           0 :                 config_dirs[0] = opts.get_string("log-config-path").c_str();
     489             :             }
     490             : 
     491           2 :             std::string const keep_project_name(opts.get_project_name());
     492           1 :             opt_env.f_project_name = keep_project_name.c_str();
     493           2 :             std::string const keep_group_name(opts.get_group_name());
     494           1 :             opt_env.f_group_name = keep_group_name.c_str();
     495           1 :             opt_env.f_environment_variable_name = "SNAPLOGGER";
     496             :             //opt_env.f_configuration_files = nullptr;
     497           1 :             opt_env.f_configuration_filename = "snaplogger.conf";
     498           1 :             opt_env.f_configuration_directories = config_dirs;
     499           1 :             opt_env.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
     500             : 
     501           2 :             advgetopt::getopt system_opts(opt_env);
     502             : 
     503           1 :             if(show_logger_configuration_files)
     504             :             {
     505           0 :                 advgetopt::string_list_t list(system_opts.get_configuration_filenames(false, false));
     506           0 :                 out << "Logger common configuration filenames:" << std::endl;
     507           0 :                 for(auto n : list)
     508             :                 {
     509           0 :                     out << " . " << n << "\n";
     510             :                 }
     511             :             }
     512             : 
     513             :             // load the system configuration file first
     514             :             //
     515           1 :             system_opts.parse_configuration_files();
     516           1 :             if(opts.get_program_fullname().empty())
     517             :             {
     518             :                 // process environment variable now if no user filename
     519             :                 // is going to be loaded
     520             :                 //
     521           0 :                 system_opts.parse_environment_variable();
     522             :             }
     523           1 :             logger::get_instance()->set_config(system_opts);
     524             : 
     525           1 :             if(!opts.get_program_fullname().empty())
     526             :             {
     527             :                 // if we have a valid program name (non-empty) then try
     528             :                 // to load these configuration files
     529             :                 //
     530           2 :                 std::string filename(opts.get_program_name());
     531           1 :                 boost::replace_all(filename, "_", "-");
     532           1 :                 filename += ".conf";
     533           1 :                 opt_env.f_configuration_filename = filename.c_str();
     534           2 :                 advgetopt::getopt config_opts(opt_env);
     535             : 
     536           1 :                 if(show_logger_configuration_files)
     537             :                 {
     538           0 :                     advgetopt::string_list_t list(config_opts.get_configuration_filenames(false, false));
     539           0 :                     out << "Logger application configuration filenames:" << std::endl;
     540           0 :                     for(auto n : list)
     541             :                     {
     542           0 :                         out << " . " << n << "\n";
     543             :                     }
     544             :                 }
     545             : 
     546           1 :                 config_opts.parse_configuration_files();
     547           1 :                 config_opts.parse_environment_variable();
     548           1 :                 logger::get_instance()->set_config(config_opts);
     549           1 :             }
     550             :         }
     551           1 :         break;
     552             : 
     553           0 :     case OPTION_NO_LOG:
     554             :         // do nothing
     555           0 :         break;
     556             : 
     557           0 :     case OPTION_LOG_FILE:
     558           0 :         configure_file(opts.get_string("log-file"));
     559           0 :         break;
     560             : 
     561           0 :     case OPTION_LOG_CONFIG:
     562           0 :         configure_config(opts.get_string("log-config"));
     563           0 :         break;
     564             : 
     565           0 :     case OPTION_SYSLOG:
     566           0 :         configure_syslog(opts.get_string("syslog"));
     567           0 :         break;
     568             : 
     569           0 :     case OPTION_CONSOLE:
     570           0 :         configure_console();
     571           0 :         break;
     572             : 
     573           0 :     default:
     574           0 :         cppthread::log << cppthread::log_level_t::error
     575           0 :                        << "only one of --no-log, --log-file, --log-config, --syslog, --console can be used on your command line."
     576           0 :                        << cppthread::end;
     577           0 :         result = false;
     578           0 :         break;
     579             : 
     580             :     }
     581             : 
     582           1 :     if(show_logger_configuration_files)
     583             :     {
     584           0 :         if(log_config != 0)
     585             :         {
     586           0 :             if(log_config == OPTION_LOG_CONFIG)
     587             :             {
     588           0 :                 out << "Logger application configuration filename:" << std::endl
     589           0 :                     << " . " << opts.get_string("log-config") << std::endl;
     590             :             }
     591             :             else
     592             :             {
     593           0 :                 out << "No logger application configuration filenames available with the current command line options." << std::endl;
     594             :             }
     595             :         }
     596           0 :         throw advgetopt::getopt_exit("--logger-configuration-filenames command processed.", 0);
     597             :     }
     598             : 
     599             :     // SEVERITY
     600             :     //
     601           1 :     int severity_selection(0);
     602           1 :     if(opts.is_defined("trace"))
     603             :     {
     604           0 :         severity_selection |= OPTION_TRACE_SEVERITY;
     605             :     }
     606           1 :     if(opts.is_defined("debug"))
     607             :     {
     608           0 :         severity_selection |= OPTION_DEBUG_SEVERITY;
     609             :     }
     610           1 :     if(opts.is_defined("log-severity"))
     611             :     {
     612           1 :         severity_selection |= OPTION_LOG_SEVERITY;
     613             :     }
     614           1 :     if(opts.is_defined("force-severity"))
     615             :     {
     616           0 :         severity_selection |= OPTION_FORCE_SEVERITY;
     617             :     }
     618             : 
     619           1 :     switch(severity_selection)
     620             :     {
     621           0 :     case 0:
     622             :         // keep as is
     623           0 :         break;
     624             : 
     625           0 :     case OPTION_TRACE_SEVERITY:
     626           0 :         logger::get_instance()->reduce_severity(severity_t::SEVERITY_TRACE);
     627           0 :         configure_console(true);
     628           0 :         break;
     629             : 
     630           0 :     case OPTION_DEBUG_SEVERITY:
     631           0 :         logger::get_instance()->reduce_severity(severity_t::SEVERITY_DEBUG);
     632           0 :         configure_console(true);
     633           0 :         break;
     634             : 
     635           1 :     case OPTION_LOG_SEVERITY:
     636             :         {
     637           2 :             std::string const severity_name(opts.get_string("log-severity"));
     638           2 :             severity::pointer_t sev(get_severity(severity_name));
     639           1 :             if(sev == nullptr)
     640             :             {
     641           0 :                 cppthread::log << cppthread::log_level_t::error
     642           0 :                                << "unknown severity level \""
     643           0 :                                << severity_name
     644           0 :                                << "\"; please check your spelling."
     645           0 :                                << cppthread::end;
     646           0 :                 result = false;
     647             :             }
     648             :             else
     649             :             {
     650           1 :                 logger::get_instance()->reduce_severity(sev->get_severity());
     651           1 :             }
     652             :         }
     653           1 :         break;
     654             : 
     655           0 :     case OPTION_FORCE_SEVERITY:
     656             :         {
     657           0 :             std::string const severity_name(opts.get_string("force-severity"));
     658           0 :             severity::pointer_t sev(get_severity(severity_name));
     659           0 :             if(sev == nullptr)
     660             :             {
     661           0 :                 cppthread::log << cppthread::log_level_t::error
     662           0 :                                << "unknown severity level \""
     663           0 :                                << severity_name
     664           0 :                                << "\"; please check your spelling against the --list-severities."
     665           0 :                                << cppthread::end;
     666           0 :                 result = false;
     667             :             }
     668             :             else
     669             :             {
     670           0 :                 logger::get_instance()->set_severity(sev->get_severity());
     671           0 :             }
     672             :         }
     673           0 :         break;
     674             : 
     675           0 :     default:
     676           0 :         cppthread::log << cppthread::log_level_t::error
     677           0 :                        << "only one of --debug, --log-severity, --force-severity can be used on your command line."
     678           0 :                        << cppthread::end;
     679           0 :         return false;
     680             : 
     681             :     }
     682             : 
     683             :     // FILTERS
     684             :     //
     685           1 :     if(opts.is_defined("log-component"))
     686             :     {
     687           0 :         size_t const max(opts.size("log-component"));
     688           0 :         for(size_t idx(0); idx < max; ++idx)
     689             :         {
     690           0 :             std::string log_component(opts.get_string("log-component", idx));
     691           0 :             if(!log_component.empty())
     692             :             {
     693           0 :                 if(log_component[0] == '!')
     694             :                 {
     695           0 :                     log_component = log_component.substr(1);
     696           0 :                     if(!log_component.empty())
     697             :                     {
     698           0 :                         component::pointer_t comp(get_component(log_component));
     699           0 :                         logger::get_instance()->add_component_to_ignore(comp);
     700             :                     }
     701             :                 }
     702             :                 else
     703             :                 {
     704           0 :                     component::pointer_t comp(get_component(log_component));
     705           0 :                     logger::get_instance()->add_component_to_include(comp);
     706             :                 }
     707             :             }
     708             :         }
     709             :     }
     710             : 
     711             :     // LIBEXCEPT EXTENSION
     712             :     //
     713             :     {
     714             :         // used in conjunction with SNAP_LOG_SEND_WITH_STACK_TRACE(e)
     715             :         // the default is "yes" (see libexcept/exception.cpp)
     716             :         //
     717           2 :         std::string const & collect(opts.get_string("except-stack-collect"));
     718           1 :         if(collect == "no")
     719             :         {
     720             :             // stack trace will be empty
     721             :             //
     722           0 :             libexcept::set_collect_stack(libexcept::collect_stack_t::COLLECT_STACK_NO);
     723             :         }
     724           1 :         else if(collect == "yes" || collect == "simple")
     725             :         {
     726             :             // names are not demangled and line numbers are not searched
     727             :             //
     728           1 :             libexcept::set_collect_stack(libexcept::collect_stack_t::COLLECT_STACK_YES);
     729             :         }
     730           0 :         else if(collect == "complete")
     731             :         {
     732             :             // frames include demangled names with line numbers
     733             :             //
     734           0 :             libexcept::set_collect_stack(libexcept::collect_stack_t::COLLECT_STACK_COMPLETE);
     735             :         }
     736             :         else
     737             :         {
     738           0 :             cppthread::log << cppthread::log_level_t::error
     739           0 :                            << "unknown type of stack collection \""
     740           0 :                            << collect
     741           0 :                            << "\"; try one of: \"no\", \"yes\", \"simple\", or \"complete\"."
     742           0 :                            << cppthread::end;
     743           0 :             return false;
     744             :         }
     745             :     }
     746             : 
     747           1 :     if(show_banner)
     748             :     {
     749           5 :         SNAP_LOG_INFO
     750           2 :                 << section(g_normal_component)
     751           2 :                 << section(g_self_component)
     752           2 :                 << section(g_banner_component)
     753             :                 << "--------------------------------------------------"
     754             :                 << SNAP_LOG_SEND;
     755           7 :         SNAP_LOG_INFO
     756           2 :                 << section(g_normal_component)
     757           2 :                 << section(g_self_component)
     758           2 :                 << section(g_banner_component)
     759           2 :                 << opts.get_project_name()
     760             :                 << " v"
     761           1 :                 << opts.get_options_environment().f_version
     762             :                 << " started."
     763             :                 << SNAP_LOG_SEND;
     764             :     }
     765             : 
     766           1 :     return result;
     767             : }
     768             : 
     769             : 
     770           6 : } // snaplogger namespace
     771             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13