]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
22 | #pragma once | |
23 | #include <iostream> | |
24 | #include <sstream> | |
25 | #include <syslog.h> | |
26 | ||
27 | /* This file is intended not to be metronome specific, and is simple example of C++2011 | |
28 | variadic templates in action. | |
29 | ||
30 | The goal is rapid easy to use logging to console & syslog. | |
31 | ||
32 | Usage: | |
33 | string address="localhost"; | |
34 | vinfolog("Got TCP connection from %s", remote); | |
35 | infolog("Bound to %s port %d", address, port); | |
36 | warnlog("Query took %d milliseconds", 1232.4); // yes, %d | |
37 | errlog("Unable to bind to %s: %s", ca.toStringWithPort(), strerr(errno)); | |
38 | ||
39 | If bool g_console is true, will log to stdout. Will syslog in any case with LOG_INFO, | |
40 | LOG_WARNING, LOG_ERR respectively. If g_verbose=false, vinfolog is a noop. | |
41 | More generically, dolog(someiostream, "Hello %s", stream) will log to someiostream | |
42 | ||
43 | This will happily print a string to %d! Doesn't do further format processing. | |
44 | */ | |
45 | ||
46 | inline void dolog(std::ostream& os, const char*s) | |
47 | { | |
48 | os<<s; | |
49 | } | |
50 | ||
51 | template<typename T, typename... Args> | |
52 | void dolog(std::ostream& os, const char* s, T value, Args... args) | |
53 | { | |
54 | while (*s) { | |
55 | if (*s == '%') { | |
56 | if (*(s + 1) == '%') { | |
57 | ++s; | |
58 | } | |
59 | else { | |
60 | os << value; | |
61 | s += 2; | |
62 | dolog(os, s, args...); | |
63 | return; | |
64 | } | |
65 | } | |
66 | os << *s++; | |
67 | } | |
68 | } | |
69 | ||
70 | extern bool g_console; | |
71 | extern bool g_verbose; | |
72 | extern bool g_syslog; | |
73 | ||
74 | template<typename... Args> | |
75 | void genlog(int level, const char* s, Args... args) | |
76 | { | |
77 | std::ostringstream str; | |
78 | dolog(str, s, args...); | |
79 | if(g_syslog) | |
80 | syslog(level, "%s", str.str().c_str()); | |
81 | if(g_console) | |
82 | std::cout<<str.str()<<std::endl; | |
83 | } | |
84 | ||
85 | ||
86 | #define vinfolog if(g_verbose)infolog | |
87 | ||
88 | template<typename... Args> | |
89 | void infolog(const char* s, Args... args) | |
90 | { | |
91 | genlog(LOG_INFO, s, args...); | |
92 | } | |
93 | ||
94 | template<typename... Args> | |
95 | void warnlog(const char* s, Args... args) | |
96 | { | |
97 | genlog(LOG_WARNING, s, args...); | |
98 | } | |
99 | ||
100 | template<typename... Args> | |
101 | void errlog(const char* s, Args... args) | |
102 | { | |
103 | genlog(LOG_ERR, s, args...); | |
104 | } | |
105 |