]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dolog.hh
dnsdist: add --log-timestamps flag
[thirdparty/pdns.git] / pdns / dolog.hh
CommitLineData
12471842
PL
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 */
64e4ebb4 22#pragma once
23#include <iostream>
24#include <sstream>
927df82c 25#include "config.h"
6f4d5e75 26#if !defined(RECURSOR)
64e4ebb4 27#include <syslog.h>
6f4d5e75
O
28#else
29#include "logger.hh"
30#endif // RECURSOR
31
64e4ebb4 32
33/* This file is intended not to be metronome specific, and is simple example of C++2011
34 variadic templates in action.
35
36 The goal is rapid easy to use logging to console & syslog.
37
38 Usage:
39 string address="localhost";
fb7f8ec3 40 vinfolog("Got TCP connection from %s", remote);
64e4ebb4 41 infolog("Bound to %s port %d", address, port);
42 warnlog("Query took %d milliseconds", 1232.4); // yes, %d
43 errlog("Unable to bind to %s: %s", ca.toStringWithPort(), strerr(errno));
44
9c9b4998 45 Will log to stdout. Will syslog in any case with LOG_INFO,
fb7f8ec3 46 LOG_WARNING, LOG_ERR respectively. If g_verbose=false, vinfolog is a noop.
64e4ebb4 47 More generically, dolog(someiostream, "Hello %s", stream) will log to someiostream
48
49 This will happily print a string to %d! Doesn't do further format processing.
50*/
51
6f4d5e75 52#if !defined(RECURSOR)
64e4ebb4 53inline void dolog(std::ostream& os, const char*s)
54{
55 os<<s;
56}
57
58template<typename T, typename... Args>
59void dolog(std::ostream& os, const char* s, T value, Args... args)
60{
61 while (*s) {
62 if (*s == '%') {
63 if (*(s + 1) == '%') {
64 ++s;
65 }
66 else {
67 os << value;
68 s += 2;
6f4d5e75 69 dolog(os, s, args...);
64e4ebb4 70 return;
71 }
72 }
73 os << *s++;
6f4d5e75 74 }
64e4ebb4 75}
76
64e4ebb4 77extern bool g_verbose;
bbfaaa6f 78extern bool g_syslog;
927df82c
PD
79#ifdef DNSDIST
80extern bool g_logtimestamps;
81#endif
64e4ebb4 82
0ca6a67f
RG
83inline void setSyslogFacility(int facility)
84{
85 /* we always call openlog() right away at startup */
86 closelog();
87 openlog("dnsdist", LOG_PID|LOG_NDELAY, facility);
88}
89
64e4ebb4 90template<typename... Args>
91void genlog(int level, const char* s, Args... args)
92{
93 std::ostringstream str;
94 dolog(str, s, args...);
927df82c 95
bbfaaa6f
PL
96 if(g_syslog)
97 syslog(level, "%s", str.str().c_str());
927df82c
PD
98
99#ifdef DNSDIST
100 if (g_logtimestamps) {
101 char buffer[50] = "";
102 struct tm tm;
103 time_t t;
104 time(&t);
105 localtime_r(&t, &tm);
106 strftime(buffer, sizeof(buffer), "%b %d %H:%M:%S ", &tm);
107 std::cout<<buffer;
108 }
109#endif
110
9c9b4998 111 std::cout<<str.str()<<std::endl;
64e4ebb4 112}
113
b2ad6825 114
115#define vinfolog if(g_verbose)infolog
116
64e4ebb4 117template<typename... Args>
118void infolog(const char* s, Args... args)
119{
fb7f8ec3 120 genlog(LOG_INFO, s, args...);
64e4ebb4 121}
122
123template<typename... Args>
124void warnlog(const char* s, Args... args)
125{
126 genlog(LOG_WARNING, s, args...);
127}
128
129template<typename... Args>
130void errlog(const char* s, Args... args)
131{
132 genlog(LOG_ERR, s, args...);
133}
b2ad6825 134
6f4d5e75
O
135
136#else // RECURSOR
137
138#define g_verbose 0
139
140inline void dolog(Logger::Urgency u, const char* s)
141{
142 g_log << u << s << std::endl;
143}
144
50111728
O
145inline void dolog(const char* s)
146{
147 g_log << s << std::endl;
148}
149
6f4d5e75
O
150template<typename T, typename... Args>
151void dolog(Logger::Urgency u, const char* s, T value, Args... args)
152{
153 g_log << u;
154 while (*s) {
155 if (*s == '%') {
156 if (*(s + 1) == '%') {
157 ++s;
158 }
159 else {
160 g_log << value;
161 s += 2;
50111728 162 dolog(s, args...);
6f4d5e75
O
163 return;
164 }
165 }
166 g_log << *s++;
167 }
168}
169
170#define vinfolog if(g_verbose)infolog
171
172template<typename... Args>
173void infolog(const char* s, Args... args)
174{
175 dolog(Logger::Info, s, args...);
176}
177
178template<typename... Args>
179void warnlog(const char* s, Args... args)
180{
181 dolog(Logger::Warning, s, args...);
182}
183
184template<typename... Args>
185void errlog(const char* s, Args... args)
186{
187 dolog(Logger::Error, s, args...);
188}
189
190#endif
191