]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/server/src/log
update
[l4.git] / l4 / pkg / plr / server / src / log
1 // vim: ft=cpp
2 #pragma once
3
4 /*
5  * log --
6  *
7  *     Logging. Main ideas from http://www.drdobbs.com/cpp/201804215
8  *
9  * (c) 2011-2012 Björn Döbel <doebel@os.inf.tu-dresden.de>,
10  *     economic rights: Technische Universität Dresden (Germany)
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  */
15
16 #include <iostream>
17 #include <iomanip>
18 #include <sstream>
19 #include <sys/time.h>
20 #include <cstdio>
21 #include <cstdarg>
22 #include <cstring>
23
24 namespace Romain {
25
26
27 template <typename T>
28 void dump_mem(T const * ptr, unsigned count, unsigned brk = 10)
29 {
30         for (unsigned i = 0; i < count; ++i) {
31                 unsigned char const *base = reinterpret_cast<unsigned char const*>(ptr) + i;
32                 printf("%02x", *base);
33                 if (i % brk == brk-1 || count-1 == i) {
34                         printf("\n");
35                 } else {
36                         printf(" ");
37                 }
38         }
39 }
40
41
42 /*
43  * Log class.
44  */
45 class Log
46 {
47         public:
48
49                 enum LogLevel { ERROR, WARN, INFO, DEBUG };
50
51                 enum LogFlags {
52                         None       = 0x0,
53                         Anything   = 0x1,
54                         Emulator   = 0x2,
55                         Memory     = 0x4,
56                         Manager    = 0x8,
57                         Faults     = 0x10,
58                         Redundancy = 0x20,
59                         Loader     = 0x40,
60                         Swifi      = 0x80,
61                         Gdb        = 0x100,
62                         All        = 0xFFFFFFFF,
63                 };
64
65                 static LogLevel    maxLog;
66                 static bool        withtime;
67                 static l4_umword_t logFlags;
68
69                 Log() { }
70                 
71                 std::ostringstream& get(LogLevel lvl = INFO)
72                 {
73                         if (Log::withtime) {
74                                 struct timeval tv;
75                                 gettimeofday(&tv, 0);
76                                 _oss << tv.tv_sec << ":" << std::setw(3) << tv.tv_usec / 1000;
77                         }
78                         _oss << " " << std::setw(5) << Log::LogLevelToString(lvl) << " ";
79                         return _oss;
80                 }
81
82                 static char const* LogLevelToString(LogLevel l)
83                 {
84                         switch (l) {
85                                 case ERROR: return "ERR";
86                                 case WARN:  return "WARN";
87                                 case DEBUG: return "DBG";
88                                 case INFO:  return "INFO";
89                                 default: return "unknown?";
90                         }
91                 }
92                 
93                 virtual ~Log()
94                 {
95                         std::cout << _oss.str() << "\n";
96                         fflush(stdout);
97                 }
98
99         protected:
100                 std::ostringstream _oss;
101
102         private:
103                 Log(const Log&) { }
104                 Log& operator=(const Log&) { return *this; }
105 };
106
107
108 /*
109  * Wrapper to map L4Re dbg interface to the log facility.
110  */
111 class Dbg
112 {
113         enum { bufsize = 60 };
114
115         public:
116                 int cprintf(char const *fmt, ...) const
117                 {
118                         static char buf[bufsize];
119                         va_list arg;
120                         va_start(arg, fmt);
121                         int ret = vsnprintf(buf, bufsize, fmt, arg);
122                         va_end(arg);
123
124                         if (buf[strlen(buf)-1] == '\n')
125                                 buf[strlen(buf)-1] = 0;
126                         Romain::Log().get(Romain::Log::DEBUG) << buf;
127
128                         return ret;
129                 }
130
131
132                 int printf(char const *fmt, ...) const
133                 {
134                         static char buf[bufsize];
135                         va_list arg;
136                         va_start(arg, fmt);
137                         int ret = vsnprintf(buf, bufsize, fmt, arg);
138                         va_end(arg);
139
140                         if (buf[strlen(buf)-1] == '\n')
141                                 buf[strlen(buf)-1] = 0;
142                         Romain::Log().get(Romain::Log::DEBUG) << buf;
143
144                         return ret;
145                 }
146 };
147
148 }
149
150 /*
151  * Dirty trick from http://www.drdobbs.com/cpp/201804215
152  *
153  * Must keep this ordering and *not* have a ; at the and of the
154  * last line
155  */
156 #define LOG(lvl, flags) \
157         if (!((lvl <= Romain::Log::maxLog) || (Romain::Log::logFlags & flags))) \
158                 ; \
159         else \
160                 Romain::Log().get(lvl) << std::setw(15) << __func__ << "\033[0m "
161
162 #define INFO()       LOG(Romain::Log::INFO, Romain::Log::All)
163 #define DEBUG()      LOG(Romain::Log::DEBUG, Romain::Log::All)
164 #define DEBUGf(flag) LOG(Romain::Log::DEBUG, flag)
165 #define WARN()       LOG(Romain::Log::WARN, Romain::Log::All)
166 #define ERROR()      LOG(Romain::Log::ERROR, Romain::Log::All)