utility.h: Change Buffer's interface to be more compatible with SharedBuffer's interf...
[oweals/minetest.git] / src / log.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
14
15 You should have received a copy of the GNU 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 "threads.h"
26 #include "debug.h"
27 #include "gettime.h"
28
29 std::list<ILogOutput*> log_outputs[LMT_NUM_VALUES];
30 std::map<threadid_t, std::string> log_threadnames;
31
32 void log_add_output(ILogOutput *out, enum LogMessageLevel lev)
33 {
34         log_outputs[lev].push_back(out);
35 }
36
37 void log_add_output_maxlev(ILogOutput *out, enum LogMessageLevel lev)
38 {
39         for(int i=0; i<=lev; i++)
40                 log_outputs[i].push_back(out);
41 }
42
43 void log_add_output_all_levs(ILogOutput *out)
44 {
45         for(int i=0; i<LMT_NUM_VALUES; i++)
46                 log_outputs[i].push_back(out);
47 }
48
49 void log_register_thread(const std::string &name)
50 {
51         threadid_t id = get_current_thread_id();
52         log_threadnames[id] = name;
53 }
54
55 static std::string get_lev_string(enum LogMessageLevel lev)
56 {
57         switch(lev){
58         case LMT_ERROR:
59                 return "ERROR";
60         case LMT_ACTION:
61                 return "ACTION";
62         case LMT_INFO:
63                 return "INFO";
64         case LMT_VERBOSE:
65                 return "VERBOSE";
66         case LMT_NUM_VALUES:
67                 break;
68         }
69         return "(unknown level)";
70 }
71
72 void log_printline(enum LogMessageLevel lev, const std::string &text)
73 {
74         std::string threadname = "(unknown thread)";
75         std::map<threadid_t, std::string>::const_iterator i;
76         i = log_threadnames.find(get_current_thread_id());
77         if(i != log_threadnames.end())
78                 threadname = i->second;
79         std::string levelname = get_lev_string(lev);
80         std::ostringstream os(std::ios_base::binary);
81         os<<getTimestamp()<<": "<<levelname<<"["<<threadname<<"]: "<<text;
82         for(std::list<ILogOutput*>::iterator i = log_outputs[lev].begin();
83                         i != log_outputs[lev].end(); i++){
84                 ILogOutput *out = *i;
85                 out->printLog(os.str());
86                 out->printLog(lev, text);
87         }
88 }
89
90 class Logbuf : public std::streambuf
91 {
92 public:
93         Logbuf(enum LogMessageLevel lev):
94                 m_lev(lev)
95         {
96         }
97
98         ~Logbuf()
99         {
100         }
101
102         int overflow(int c)
103         {
104                 bufchar(c);
105                 return c;
106         }
107         std::streamsize xsputn(const char *s, std::streamsize n)
108         {
109                 for(int i=0; i<n; i++)
110                         bufchar(s[i]);
111                 return n;
112         }
113
114         void printbuf()
115         {
116                 log_printline(m_lev, m_buf);
117         }
118
119         void bufchar(char c)
120         {
121                 if(c == '\n' || c == '\r'){
122                         if(m_buf != "")
123                                 printbuf();
124                         m_buf = "";
125                         return;
126                 }
127                 m_buf += c;
128         }
129         
130 private:
131         enum LogMessageLevel m_lev;
132         std::string m_buf;
133 };
134
135 Logbuf errorbuf(LMT_ERROR);
136 Logbuf actionbuf(LMT_ACTION);
137 Logbuf infobuf(LMT_INFO);
138 Logbuf verbosebuf(LMT_VERBOSE);
139 std::ostream errorstream(&errorbuf);
140 std::ostream actionstream(&actionbuf);
141 std::ostream infostream(&infobuf);
142 std::ostream verbosestream(&verbosebuf);
143
144