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