LCOV - code coverage report
Current view: top level - snaplogger - message.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 19 28 67.9 %
Date: 2021-05-29 11:58:38 Functions: 8 9 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013-2021  Made to Order Software Corp.  All Rights Reserved
       3             :  *
       4             :  * https://snapwebsites.org/project/snaplogger
       5             :  * contact@m2osw.com
       6             :  *
       7             :  * This program is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 2 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * This program is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License along
      18             :  * with this program; if not, write to the Free Software Foundation, Inc.,
      19             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      20             :  */
      21             : #pragma once
      22             : 
      23             : /** \file
      24             :  * \brief Handle the message generator.
      25             :  *
      26             :  * This file declares the base message class which is derived from an
      27             :  * std::stringstram. This allows you to use our logger with `<<`
      28             :  * to send anything that the `<<` operator understands to the logs.
      29             :  */
      30             : 
      31             : 
      32             : // self
      33             : //
      34             : #include    "snaplogger/component.h"
      35             : #include    "snaplogger/environment.h"
      36             : #include    "snaplogger/severity.h"
      37             : 
      38             : 
      39             : // C++ lib
      40             : //
      41             : #include    <sstream>
      42             : #include    <streambuf>
      43             : 
      44             : 
      45             : // C lib
      46             : //
      47             : #include    <sys/time.h>
      48             : 
      49             : 
      50             : 
      51             : namespace snaplogger
      52             : {
      53             : 
      54             : 
      55             : class logger;
      56             : 
      57             : 
      58             : 
      59      140346 : class null_buffer
      60             :     : public std::streambuf
      61             : {
      62             : public:
      63             :     typedef std::unique_ptr<null_buffer>    pointer_t;
      64             : 
      65             :     virtual int         overflow(int c) override;
      66             : };
      67             : 
      68             : 
      69             : // the message class is final because the destructor does tricks which
      70             : // would not work right if derived further
      71             : //
      72             : // also we do not offer a shared pointer because we expect the message
      73             : // object to be created and immediately destroyed from the stack
      74             : //
      75             : class message final
      76             :     : public std::basic_stringstream<char>
      77             : {
      78             : public:
      79             :     typedef std::shared_ptr<message>            pointer_t;
      80             :     typedef std::map<std::string, std::string>  field_map_t;
      81             : 
      82             :                                 message(
      83             :                                           severity_t sev = default_severity()
      84             :                                         , char const * file = nullptr
      85             :                                         , char const * func = nullptr
      86             :                                         , int line = -1);
      87             :                                 message(std::basic_stringstream<char> const & m, message const & msg);
      88             :                                 message(message const & rhs) = delete;
      89             :     virtual                     ~message();
      90             : 
      91             :     message &                   operator = (message const & rhs) = delete;
      92             : 
      93             :     static severity_t           default_severity();
      94             : 
      95             :     void                        set_severity(severity_t severity);
      96             :     void                        set_filename(std::string const & filename);
      97             :     void                        set_function(std::string const & funcname);
      98             :     void                        set_line(int line);
      99             :     void                        set_recursive_message(bool state) const;
     100             :     bool                        can_add_component(component::pointer_t c) const;
     101             :     void                        add_component(component::pointer_t c);
     102             :     void                        add_field(std::string const & name, std::string const & value);
     103             : 
     104             :     std::shared_ptr<logger>     get_logger() const;
     105             :     severity_t                  get_severity() const;
     106             :     void                        set_precise_time();
     107             :     timespec const &            get_timestamp() const;
     108             :     std::string const &         get_filename() const;
     109             :     std::string const &         get_function() const;
     110             :     int                         get_line() const;
     111             :     bool                        get_recursive_message() const;
     112             :     bool                        has_component(component::pointer_t c) const;
     113             :     component::set_t const &    get_components() const;
     114             :     environment::pointer_t      get_environment() const;
     115             :     std::string                 get_message() const;
     116             :     std::string                 get_field(std::string const & name) const;
     117             :     field_map_t                 get_fields() const;
     118             : 
     119             : private:
     120             :     std::shared_ptr<logger>     f_logger = std::shared_ptr<logger>(); // make sure it does not go away under our feet
     121             :     timespec                    f_timestamp = timespec();
     122             :     severity_t                  f_severity = severity_t::SEVERITY_INFORMATION;
     123             :     std::string                 f_filename = std::string();
     124             :     std::string                 f_funcname = std::string();
     125             :     int                         f_line = 0;
     126             :     mutable bool                f_recursive_message = false;
     127             :     environment::pointer_t      f_environment = environment::pointer_t();
     128             :     component::set_t            f_components = component::set_t();
     129             :     field_map_t                 f_fields = field_map_t();
     130             :     null_buffer::pointer_t      f_null = null_buffer::pointer_t();
     131             :     std::streambuf *            f_saved_buffer = nullptr;
     132             :     bool                        f_copy = false;
     133             : };
     134             : 
     135             : 
     136             : template<typename CharT, typename Traits>
     137             : inline std::basic_ostream<CharT, Traits> &
     138           0 : operator << (std::basic_ostream<CharT, Traits> & os, section_ptr sec)
     139             : {
     140           0 :     message * m(dynamic_cast<message *>(&os));
     141           0 :     if(m == nullptr)
     142             :     {
     143           0 :         os << "(section:"
     144           0 :            << sec.f_component->get_name()
     145           0 :            << ")";
     146             :     }
     147             :     else
     148             :     {
     149           0 :         m->add_component(sec.f_component);
     150             :     }
     151           0 :     return os;
     152             : }
     153             : 
     154             : 
     155             : template<typename CharT, typename Traits>
     156             : inline std::basic_ostream<CharT, Traits> &
     157           5 : secure(std::basic_ostream<CharT, Traits> & os)
     158             : {
     159           5 :     message * m(dynamic_cast<message *>(&os));
     160           5 :     if(m == nullptr)
     161             :     {
     162           1 :         os << "(section:secure)";
     163             :     }
     164             :     else
     165             :     {
     166           4 :         m->add_component(g_secure_component);
     167             :     }
     168           5 :     return os;
     169             : }
     170             : 
     171             : 
     172             : template<typename CharT, typename Traits>
     173             : inline std::basic_ostream<CharT, Traits> &
     174           1 : precise_time(std::basic_ostream<CharT, Traits> & os)
     175             : {
     176           1 :     message * m(dynamic_cast<message *>(&os));
     177           1 :     if(m == nullptr)
     178             :     {
     179           0 :         m->set_precise_time();
     180             :     }
     181           1 :     return os;
     182             : }
     183             : 
     184             : 
     185             : 
     186           3 : struct field_t
     187             : {
     188             :     std::string             f_name;
     189             :     std::string             f_value;
     190             : };
     191             : 
     192           3 : inline field_t field(std::string const & name, std::string const & value)
     193             : {
     194           3 :     return { name, value };
     195             : }
     196             : 
     197             : template<typename CharT, typename Traits>
     198             : inline std::basic_ostream<CharT, Traits> &
     199           3 : operator << (std::basic_ostream<CharT, Traits> & os, field_t const & f)
     200             : {
     201           3 :     message * m(dynamic_cast<message *>(&os));
     202           3 :     if(m != nullptr)
     203             :     {
     204           3 :         m->add_field(f.f_name, f.f_value);
     205             :     }
     206           3 :     return os;
     207             : }
     208             : 
     209             : 
     210             : 
     211             : void send_message(std::basic_ostream<char> & msg);
     212             : 
     213             : 
     214             : // TODO: with C++20, change the __FILE__, __LINE__, __func__ with
     215             : //       std::location::current()
     216             : //
     217             : #define SNAP_LOG_FATAL              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_FATAL,             __FILE__, __func__, __LINE__)
     218             : #define SNAP_LOG_EMERG              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_EMERGENCY,         __FILE__, __func__, __LINE__)
     219             : #define SNAP_LOG_EMERGENCY          ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_EMERGENCY,         __FILE__, __func__, __LINE__)
     220             : #define SNAP_LOG_ALERT              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_ALERT,             __FILE__, __func__, __LINE__)
     221             : #define SNAP_LOG_CRIT               ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_CRITICAL,          __FILE__, __func__, __LINE__)
     222             : #define SNAP_LOG_CRITICAL           ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_CRITICAL,          __FILE__, __func__, __LINE__)
     223             : #define SNAP_LOG_ERR                ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_ERROR,             __FILE__, __func__, __LINE__)
     224             : #define SNAP_LOG_ERROR              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_ERROR,             __FILE__, __func__, __LINE__)
     225             : #define SNAP_LOG_RECOVERABLE_ERROR  ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_RECOVERABLE_ERROR, __FILE__, __func__, __LINE__)
     226             : #define SNAP_LOG_MAJOR              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_MAJOR,             __FILE__, __func__, __LINE__)
     227             : #define SNAP_LOG_WARN               ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_WARNING,           __FILE__, __func__, __LINE__)
     228             : #define SNAP_LOG_WARNING            ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_WARNING,           __FILE__, __func__, __LINE__)
     229             : #define SNAP_LOG_DEPRECATED         ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_DEPRECATED,        __FILE__, __func__, __LINE__)
     230             : #define SNAP_LOG_MINOR              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_MINOR,             __FILE__, __func__, __LINE__)
     231             : #define SNAP_LOG_IMPORTANT          ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_IMPORTANT,         __FILE__, __func__, __LINE__)
     232             : #define SNAP_LOG_INFO               ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_INFORMATION,       __FILE__, __func__, __LINE__)
     233             : #define SNAP_LOG_INFORMATION        ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_INFORMATION,       __FILE__, __func__, __LINE__)
     234             : #define SNAP_LOG_VERBOSE            ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_VERBOSE,           __FILE__, __func__, __LINE__)
     235             : #define SNAP_LOG_UNIMPORTANT        ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_UNIMPORTANT,       __FILE__, __func__, __LINE__)
     236             : #define SNAP_LOG_NOTICE             ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_NOTICE,            __FILE__, __func__, __LINE__)
     237             : #define SNAP_LOG_DEBUG              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_DEBUG,             __FILE__, __func__, __LINE__)
     238             : #define SNAP_LOG_TRACE              ::snaplogger::send_message((::snaplogger::message(::snaplogger::severity_t::SEVERITY_TRACE,             __FILE__, __func__, __LINE__)
     239             : 
     240             : #define SNAP_LOG_DEFAULT            ::snaplogger::send_message((::snaplogger::message(::snaplogger::message::default_severity(),            __FILE__, __func__, __LINE__)
     241             : 
     242             : #define SNAP_LOG_FIELD(name, value) ::snaplogger::field((name), (value))
     243             : 
     244             : // The (( are in the opening macros
     245             : //
     246             : #define SNAP_LOG_SEND               ""))
     247             : #define SNAP_LOG_SEND_SECURELY      ::snaplogger::secure))
     248             : 
     249             : 
     250             : 
     251             : } // snaplogger namespace
     252             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13