LCOV - code coverage report
Current view: top level - src - log.cpp (source / functions) Hit Total Coverage
Test: report Lines: 84 96 87.5 %
Date: 2015-07-11 18:23:49 Functions: 17 19 89.5 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "log.h"
      21             : 
      22             : #include <map>
      23             : #include <list>
      24             : #include <sstream>
      25             : #include <algorithm>
      26             : #include "threads.h"
      27             : #include "jthread/jmutexautolock.h"
      28             : #include "debug.h"
      29             : #include "gettime.h"
      30             : #include "porting.h"
      31             : #include "config.h"
      32             : 
      33             : // Connection
      34             : std::ostream *dout_con_ptr = &dummyout;
      35             : std::ostream *derr_con_ptr = &verbosestream;
      36             : 
      37             : // Server
      38             : std::ostream *dout_server_ptr = &infostream;
      39             : std::ostream *derr_server_ptr = &errorstream;
      40             : 
      41             : #ifndef SERVER
      42             : // Client
      43             : std::ostream *dout_client_ptr = &infostream;
      44             : std::ostream *derr_client_ptr = &errorstream;
      45             : #endif
      46             : 
      47             : #ifdef __ANDROID__
      48             : unsigned int android_log_level_mapping[] = {
      49             :                 /* LMT_ERROR */   ANDROID_LOG_ERROR,
      50             :                 /* LMT_ACTION */  ANDROID_LOG_WARN,
      51             :                 /* LMT_INFO */    ANDROID_LOG_INFO,
      52             :                 /* LMT_VERBOSE */ ANDROID_LOG_VERBOSE
      53             :         };
      54             : #endif
      55             : 
      56           2 : std::vector<ILogOutput*> log_outputs[LMT_NUM_VALUES];
      57           1 : std::map<threadid_t, std::string> log_threadnames;
      58           1 : JMutex                            log_threadnamemutex;
      59             : 
      60           1 : void log_add_output(ILogOutput *out, enum LogMessageLevel lev)
      61             : {
      62           1 :         log_outputs[lev].push_back(out);
      63           1 : }
      64             : 
      65           2 : void log_add_output_maxlev(ILogOutput *out, enum LogMessageLevel lev)
      66             : {
      67           6 :         for(int i=0; i<=lev; i++)
      68           4 :                 log_outputs[i].push_back(out);
      69           2 : }
      70             : 
      71           1 : void log_add_output_all_levs(ILogOutput *out)
      72             : {
      73           5 :         for(int i=0; i<LMT_NUM_VALUES; i++)
      74           4 :                 log_outputs[i].push_back(out);
      75           1 : }
      76             : 
      77           2 : void log_remove_output(ILogOutput *out)
      78             : {
      79          10 :         for(int i=0; i<LMT_NUM_VALUES; i++){
      80             :                 std::vector<ILogOutput*>::iterator it =
      81           8 :                                 std::find(log_outputs[i].begin(), log_outputs[i].end(), out);
      82           8 :                 if(it != log_outputs[i].end())
      83           5 :                         log_outputs[i].erase(it);
      84             :         }
      85           2 : }
      86             : 
      87           0 : void log_set_lev_silence(enum LogMessageLevel lev, bool silence)
      88             : {
      89           0 :         JMutexAutoLock lock(log_threadnamemutex);
      90             : 
      91           0 :         for (std::vector<ILogOutput *>::iterator it = log_outputs[lev].begin();
      92           0 :                         it != log_outputs[lev].end(); ++it) {
      93           0 :                 ILogOutput *out = *it;
      94           0 :                 out->silence = silence;
      95             :         }
      96           0 : }
      97             : 
      98           9 : void log_register_thread(const std::string &name)
      99             : {
     100           9 :         threadid_t id = get_current_thread_id();
     101          18 :         JMutexAutoLock lock(log_threadnamemutex);
     102             : 
     103           9 :         log_threadnames[id] = name;
     104           9 : }
     105             : 
     106           4 : void log_deregister_thread()
     107             : {
     108           4 :         threadid_t id = get_current_thread_id();
     109           8 :         JMutexAutoLock lock(log_threadnamemutex);
     110             : 
     111           4 :         log_threadnames.erase(id);
     112           4 : }
     113             : 
     114       47502 : static std::string get_lev_string(enum LogMessageLevel lev)
     115             : {
     116       47502 :         switch(lev){
     117             :         case LMT_ERROR:
     118           0 :                 return "ERROR";
     119             :         case LMT_ACTION:
     120           0 :                 return "ACTION";
     121             :         case LMT_INFO:
     122       29410 :                 return "INFO";
     123             :         case LMT_VERBOSE:
     124       18092 :                 return "VERBOSE";
     125             :         case LMT_NUM_VALUES:
     126           0 :                 break;
     127             :         }
     128           0 :         return "(unknown level)";
     129             : }
     130             : 
     131       47502 : void log_printline(enum LogMessageLevel lev, const std::string &text)
     132             : {
     133       95004 :         JMutexAutoLock lock(log_threadnamemutex);
     134       95004 :         std::string threadname = "(unknown thread)";
     135       47502 :         std::map<threadid_t, std::string>::const_iterator i;
     136       47502 :         i = log_threadnames.find(get_current_thread_id());
     137       47502 :         if(i != log_threadnames.end())
     138       47502 :                 threadname = i->second;
     139       95004 :         std::string levelname = get_lev_string(lev);
     140       95004 :         std::ostringstream os(std::ios_base::binary);
     141       47502 :         os << getTimestamp() << ": " << levelname << "["<<threadname<<"]: " << text;
     142             : 
     143      142524 :         for(std::vector<ILogOutput*>::iterator i = log_outputs[lev].begin();
     144       95016 :                         i != log_outputs[lev].end(); i++) {
     145           6 :                 ILogOutput *out = *i;
     146           6 :                 if (out->silence)
     147           0 :                         continue;
     148             : 
     149           6 :                 out->printLog(os.str());
     150           6 :                 out->printLog(os.str(), lev);
     151           6 :                 out->printLog(lev, text);
     152             :         }
     153       47502 : }
     154             : 
     155             : class Logbuf : public std::streambuf
     156             : {
     157             : public:
     158           4 :         Logbuf(enum LogMessageLevel lev):
     159           4 :                 m_lev(lev)
     160             :         {
     161           4 :         }
     162             : 
     163           4 :         ~Logbuf()
     164           4 :         {
     165           4 :         }
     166             : 
     167       47498 :         int overflow(int c)
     168             :         {
     169       47498 :                 bufchar(c);
     170       47498 :                 return c;
     171             :         }
     172      186287 :         std::streamsize xsputn(const char *s, std::streamsize n)
     173             :         {
     174     3899554 :                 for(int i=0; i<n; i++)
     175     3713267 :                         bufchar(s[i]);
     176      186287 :                 return n;
     177             :         }
     178             : 
     179       47498 :         void printbuf()
     180             :         {
     181       47498 :                 log_printline(m_lev, m_buf);
     182             : #ifdef __ANDROID__
     183             :                 __android_log_print(android_log_level_mapping[m_lev], PROJECT_NAME, "%s", m_buf.c_str());
     184             : #endif
     185       47498 :         }
     186             : 
     187     3760765 :         void bufchar(char c)
     188             :         {
     189     3760765 :                 if(c == '\n' || c == '\r'){
     190       47498 :                         if(m_buf != "")
     191       47498 :                                 printbuf();
     192       47498 :                         m_buf = "";
     193       47498 :                         return;
     194             :                 }
     195     3713267 :                 m_buf += c;
     196             :         }
     197             : 
     198             : private:
     199             :         enum LogMessageLevel m_lev;
     200             :         std::string m_buf;
     201             : };
     202             : 
     203           1 : Logbuf errorbuf(LMT_ERROR);
     204           1 : Logbuf actionbuf(LMT_ACTION);
     205           1 : Logbuf infobuf(LMT_INFO);
     206           1 : Logbuf verbosebuf(LMT_VERBOSE);
     207           1 : std::ostream errorstream(&errorbuf);
     208           1 : std::ostream actionstream(&actionbuf);
     209           1 : std::ostream infostream(&infobuf);
     210           1 : std::ostream verbosestream(&verbosebuf);
     211             : 
     212           3 : bool log_trace_level_enabled = false;
     213             : 

Generated by: LCOV version 1.11