LCOV - code coverage report
Current view: top level - snaplogger - message.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 102 89.2 %
Date: 2021-05-29 11:58:38 Functions: 27 34 79.4 %
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             : 
      22             : /** \file
      23             :  * \brief Appenders are used to append data to somewhere.
      24             :  *
      25             :  * This file declares the base appender class.
      26             :  */
      27             : 
      28             : // self
      29             : // 
      30             : #include    "snaplogger/message.h"
      31             : 
      32             : #include    "snaplogger/exception.h"
      33             : #include    "snaplogger/logger.h"
      34             : 
      35             : 
      36             : // C++ lib
      37             : //
      38             : #include    <iostream>
      39             : 
      40             : 
      41             : // C lib
      42             : //
      43             : #include    <sys/time.h>
      44             : 
      45             : 
      46             : // last include
      47             : //
      48             : #include    <snapdev/poison.h>
      49             : 
      50             : 
      51             : 
      52             : namespace snaplogger
      53             : {
      54             : 
      55             : 
      56     1064273 : int null_buffer::overflow(int c)
      57             : {
      58     1064273 :     return c;
      59             : }
      60             : 
      61             : 
      62             : 
      63             : 
      64             : 
      65       91736 : message::message(
      66             :           severity_t sev
      67             :         , char const * file
      68             :         , char const * func
      69       91736 :         , int line)
      70             :     : f_logger(logger::get_instance())
      71             :     , f_severity(sev)
      72             :     , f_filename(file == nullptr ? std::string() : std::string(file))
      73             :     , f_funcname(func == nullptr ? std::string() : std::string(func))
      74             :     , f_line(line)
      75       91736 :     , f_environment(create_environment())
      76             : {
      77       91736 :     clock_gettime(CLOCK_REALTIME_COARSE, &f_timestamp);
      78             : 
      79      183472 :     if(f_severity < f_logger->get_lowest_severity()
      80       91736 :     || f_severity == severity_t::SEVERITY_OFF)
      81             :     {
      82       46782 :         f_null.reset(new null_buffer);
      83       46782 :         std::ostream & ref = *this;
      84       46782 :         f_saved_buffer = ref.rdbuf(f_null.get());
      85             :     }
      86       91736 : }
      87             : 
      88             : 
      89           2 : message::message(std::basic_stringstream<char> const & m, message const & msg)
      90             :     : f_logger(msg.f_logger)
      91             :     , f_timestamp(msg.f_timestamp)
      92           2 :     , f_severity(msg.f_severity)
      93             :     , f_filename(msg.f_filename)
      94             :     , f_funcname(msg.f_funcname)
      95           2 :     , f_line(msg.f_line)
      96           2 :     , f_recursive_message(msg.f_recursive_message)
      97             :     , f_environment(msg.f_environment)
      98             :     , f_components(msg.f_components)
      99             :     , f_fields(msg.f_fields)
     100             :     , f_null(null_buffer::pointer_t())
     101             :     , f_saved_buffer(nullptr)
     102           8 :     , f_copy(true)
     103             : {
     104           2 :     *this << m.rdbuf();
     105           2 : }
     106             : 
     107             : 
     108      183476 : message::~message()
     109             : {
     110       91738 :     if(f_saved_buffer != nullptr)
     111             :     {
     112       46782 :         std::ostream & ref = *this;
     113       46782 :         ref.rdbuf(f_saved_buffer);
     114             :     }
     115       91738 : }
     116             : 
     117             : 
     118           0 : severity_t message::default_severity()
     119             : {
     120           0 :     return logger::get_instance()->get_default_severity();
     121             : }
     122             : 
     123             : 
     124       26147 : void message::set_severity(severity_t severity)
     125             : {
     126       26147 :     f_severity = severity;
     127       26147 : }
     128             : 
     129             : 
     130           1 : void message::set_filename(std::string const & filename)
     131             : {
     132           1 :     f_filename = filename;
     133           1 : }
     134             : 
     135             : 
     136           1 : void message::set_function(std::string const & funcname)
     137             : {
     138           1 :     f_funcname = funcname;
     139           1 : }
     140             : 
     141             : 
     142           1 : void message::set_line(int line)
     143             : {
     144           1 :     f_line = line;
     145           1 : }
     146             : 
     147             : 
     148          34 : void message::set_recursive_message(bool state) const
     149             : {
     150          34 :     f_recursive_message = state;
     151          34 : }
     152             : 
     153             : 
     154           8 : bool message::can_add_component(component::pointer_t c) const
     155             : {
     156           8 :     if(c != nullptr)
     157             :     {
     158           8 :         return !c->is_mutually_exclusive(f_components);
     159             :     }
     160             : 
     161           0 :     return false;
     162             : }
     163             : 
     164             : 
     165           8 : void message::add_component(component::pointer_t c)
     166             : {
     167           8 :     if(c != nullptr)
     168             :     {
     169           8 :         if(!can_add_component(c))
     170             :         {
     171             :             throw duplicate_error(
     172             :                   "component \""
     173           0 :                 + c->get_name()
     174           0 :                 + "\" cannot be added to this message as it is mutually exclusive with one or more of the other components that were added to this message.");
     175             :         }
     176             : 
     177           8 :         f_components.insert(c);
     178             :     }
     179           8 : }
     180             : 
     181             : 
     182           3 : void message::add_field(std::string const & name, std::string const & value)
     183             : {
     184           3 :     if(!name.empty())
     185             :     {
     186           3 :         f_fields[name] = value;
     187             :     }
     188           3 : }
     189             : 
     190             : 
     191       45882 : std::shared_ptr<logger> message::get_logger() const
     192             : {
     193       45882 :     return f_logger;
     194             : }
     195             : 
     196             : 
     197      183491 : severity_t message::get_severity() const
     198             : {
     199      183491 :     return f_severity;
     200             : }
     201             : 
     202             : 
     203           0 : void message::set_precise_time()
     204             : {
     205           0 :     clock_gettime(CLOCK_REALTIME, &f_timestamp);
     206           0 : }
     207             : 
     208             : 
     209           4 : timespec const & message::get_timestamp() const
     210             : {
     211           4 :     return f_timestamp;
     212             : }
     213             : 
     214             : 
     215           2 : std::string const & message::get_filename() const
     216             : {
     217           2 :     return f_filename;
     218             : }
     219             : 
     220             : 
     221           2 : std::string const & message::get_function() const
     222             : {
     223           2 :     return f_funcname;
     224             : }
     225             : 
     226             : 
     227           2 : int message::get_line() const
     228             : {
     229           2 :     return f_line;
     230             : }
     231             : 
     232             : 
     233       45719 : bool message::get_recursive_message() const
     234             : {
     235       45719 :     return f_recursive_message;
     236             : }
     237             : 
     238             : 
     239           0 : bool message::has_component(component::pointer_t c) const
     240             : {
     241           0 :     return f_components.find(c) != f_components.end();
     242             : }
     243             : 
     244             : 
     245      137459 : component::set_t const & message::get_components() const
     246             : {
     247      137459 :     return f_components;
     248             : }
     249             : 
     250             : 
     251          29 : environment::pointer_t message::get_environment() const
     252             : {
     253          29 :     return f_environment;
     254             : }
     255             : 
     256             : 
     257       45717 : std::string message::get_message() const
     258             : {
     259       45717 :     std::string s(str());
     260             : 
     261       91434 :     if(!s.empty()
     262       45717 :     && s.back() == '\n')
     263             :     {
     264           4 :         s.pop_back();
     265             :     }
     266             : 
     267       91434 :     if(!s.empty()
     268       45717 :     && s.back() == '\r')
     269             :     {
     270           2 :         s.pop_back();
     271             :     }
     272             : 
     273       45717 :     return s;
     274             : }
     275             : 
     276             : 
     277           1 : std::string message::get_field(std::string const & name) const
     278             : {
     279           1 :     auto it(f_fields.find(name));
     280           1 :     if(it == f_fields.end())
     281             :     {
     282           0 :         return std::string();
     283             :     }
     284           1 :     return it->second;
     285             : }
     286             : 
     287             : 
     288           1 : message::field_map_t message::get_fields() const
     289             : {
     290           1 :     return f_fields;
     291             : }
     292             : 
     293             : 
     294       91729 : void send_message(std::basic_ostream<char> & out)
     295             : {
     296       91729 :     message * msg(dynamic_cast<message *>(&out));
     297       91729 :     if(msg == nullptr)
     298             :     {
     299           1 :         throw not_a_message("the 'out' parameter to the send_message() function is expected to be a snaplogger::message object.");
     300             :     }
     301             : 
     302       91728 :     logger::get_instance()->log_message(*msg);
     303       91728 : }
     304             : 
     305             : 
     306             : 
     307             : 
     308           6 : } // snaplogger namespace
     309             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13