]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/logger.cc
Merge pull request #9070 from rgacogne/boost-173
[thirdparty/pdns.git] / pdns / logger.cc
CommitLineData
12c86877 1/*
12471842
PL
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 */
870a0fe4 22#ifdef HAVE_CONFIG_H
a2bfc3ff 23#include "config.h"
870a0fe4 24#endif
69b8131b
RG
25
26#include <mutex>
27
870a0fe4 28#include "logger.hh"
8e203aef 29#include "misc.hh"
a2bfc3ff 30#ifndef RECURSOR
12c86877 31#include "statbag.hh"
a2bfc3ff
BH
32extern StatBag S;
33#endif
10f4eea8 34#include "namespaces.hh"
12c86877 35
ca07bd2c 36thread_local Logger::PerThread Logger::t_perThread;
d1449e4d 37
772dd39c
RG
38Logger& getLogger()
39{
40 /* Since the Logger can be called very early, we need to make sure
41 that the relevant parts are initialized no matter what, which is tricky
42 because we can't easily control the initialization order, especially with
43 built-in backends.
44 t_perThread is thread_local, so it will be initialized when first accessed,
45 but we need to make sure that the object itself is initialized, and making
46 it a function-level static variable achieves that, because it will be
47 initialized the first time we enter this function at the very last.
48 */
49 static Logger log("", LOG_DAEMON);
50 return log;
51}
12c86877 52
c3d0fb44 53void Logger::log(const string &msg, Urgency u) noexcept
12c86877 54{
29c2d86d 55#ifndef RECURSOR
9cfac2e0 56 bool mustAccount(false);
29c2d86d 57#endif
8d755517 58 if(u<=consoleUrgency) {
b18fa400
PL
59 char buffer[50] = "";
60 if (d_timestamps) {
61 struct tm tm;
62 time_t t;
63 time(&t);
d810ebd7 64 localtime_r(&t, &tm);
b18fa400
PL
65 strftime(buffer,sizeof(buffer),"%b %d %H:%M:%S ", &tm);
66 }
67
e908ad87
PL
68 string prefix;
69 if (d_prefixed) {
70 switch(u) {
71 case All:
72 prefix = "[all] ";
73 break;
74 case Alert:
75 prefix = "[ALERT] ";
76 break;
77 case Critical:
78 prefix = "[CRITICAL] ";
79 break;
80 case Error:
81 prefix = "[ERROR] ";
82 break;
83 case Warning:
84 prefix = "[WARNING] ";
85 break;
86 case Notice:
87 prefix = "[NOTICE] ";
88 break;
89 case Info:
90 prefix = "[INFO] ";
91 break;
92 case Debug:
93 prefix = "[DEBUG] ";
94 break;
95 case None:
96 prefix = "[none] ";
97 break;
98 }
99 }
100
69b8131b
RG
101 static std::mutex m;
102 std::lock_guard<std::mutex> l(m); // the C++-2011 spec says we need this, and OSX actually does
e908ad87 103 clog << string(buffer) + prefix + msg <<endl;
29c2d86d 104#ifndef RECURSOR
9cfac2e0 105 mustAccount=true;
29c2d86d 106#endif
12c86877 107 }
b6cfa948 108 if( u <= d_loglevel && !d_disableSyslog ) {
9cfac2e0 109 syslog(u,"%s",msg.c_str());
29c2d86d 110#ifndef RECURSOR
9cfac2e0 111 mustAccount=true;
29c2d86d 112#endif
9cfac2e0
PL
113 }
114
a2bfc3ff 115#ifndef RECURSOR
c3d0fb44
OM
116 if(mustAccount) {
117 try {
118 S.ringAccount("logmessages",msg);
119 }
120 catch (const runtime_error& e) {
121 cerr << e.what() << endl;
122 }
123 }
a2bfc3ff 124#endif
12c86877
BH
125}
126
eefd15f9
BH
127void Logger::setLoglevel( Urgency u )
128{
fe1ce82e 129 d_loglevel = u;
eefd15f9
BH
130}
131
132
12c86877
BH
133void Logger::toConsole(Urgency u)
134{
12c86877
BH
135 consoleUrgency=u;
136}
137
138void Logger::open()
139{
140 if(opened)
141 closelog();
142 openlog(name.c_str(),flags,d_facility);
143 opened=true;
144}
145
146void Logger::setName(const string &_name)
147{
148 name=_name;
149 open();
150}
151
c613b06f
CHB
152Logger::Logger(const string &n, int facility) :
153 name(n), flags(LOG_PID|LOG_NDELAY), d_facility(facility), d_loglevel(Logger::None),
154 consoleUrgency(Error), opened(false), d_disableSyslog(false)
12c86877 155{
12c86877
BH
156 open();
157
158}
159
160Logger& Logger::operator<<(Urgency u)
161{
ca07bd2c 162 getPerThread().d_urgency=u;
12c86877
BH
163 return *this;
164}
165
ca07bd2c 166Logger::PerThread& Logger::getPerThread()
12c86877 167{
ca07bd2c 168 return t_perThread;
d1449e4d 169}
12c86877 170
d1449e4d 171Logger& Logger::operator<<(const string &s)
172{
ca07bd2c
RG
173 PerThread& pt = getPerThread();
174 pt.d_output.append(s);
12c86877
BH
175 return *this;
176}
177
7abbc40f
PD
178Logger& Logger::operator<<(const char *s)
179{
180 *this<<string(s);
181 return *this;
182}
183
12c86877
BH
184Logger& Logger::operator<<(ostream & (&)(ostream &))
185{
ca07bd2c 186 PerThread& pt = getPerThread();
12c86877 187
ca07bd2c
RG
188 log(pt.d_output, pt.d_urgency);
189 pt.d_output.clear();
190 pt.d_urgency=Info;
12c86877
BH
191 return *this;
192}
dd72bfaa
PL
193
194Logger& Logger::operator<<(const DNSName &d)
195{
c348fec2 196 *this<<d.toLogString();
dd72bfaa
PL
197
198 return *this;
199}
ded6b08d
AT
200
201Logger& Logger::operator<<(const ComboAddress &ca)
202{
9b0f144f 203 *this<<ca.toLogString();
ded6b08d
AT
204 return *this;
205}
206