]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/logger.cc
0e3c54c8b0776fbe4fe8fb77ed2c20c7791a522d
[thirdparty/pdns.git] / pdns / logger.cc
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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include "logger.hh"
26 #include "misc.hh"
27 #ifndef RECURSOR
28 #include "statbag.hh"
29 extern StatBag S;
30 #endif
31 #include "lock.hh"
32 #include "namespaces.hh"
33
34 pthread_once_t Logger::s_once;
35 pthread_key_t Logger::g_loggerKey;
36
37 Logger g_log("", LOG_DAEMON);
38
39 void Logger::log(const string &msg, Urgency u)
40 {
41 #ifndef RECURSOR
42 bool mustAccount(false);
43 #endif
44 if(u<=consoleUrgency) {
45 char buffer[50] = "";
46 if (d_timestamps) {
47 struct tm tm;
48 time_t t;
49 time(&t);
50 tm=*localtime(&t);
51 strftime(buffer,sizeof(buffer),"%b %d %H:%M:%S ", &tm);
52 }
53
54 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
55 Lock l(&m); // the C++-2011 spec says we need this, and OSX actually does
56 clog << string(buffer) + msg <<endl;
57 #ifndef RECURSOR
58 mustAccount=true;
59 #endif
60 }
61 if( u <= d_loglevel && !d_disableSyslog ) {
62 syslog(u,"%s",msg.c_str());
63 #ifndef RECURSOR
64 mustAccount=true;
65 #endif
66 }
67
68 #ifndef RECURSOR
69 if(mustAccount)
70 S.ringAccount("logmessages",msg);
71 #endif
72 }
73
74 void Logger::setLoglevel( Urgency u )
75 {
76 d_loglevel = u;
77 }
78
79
80 void Logger::toConsole(Urgency u)
81 {
82 consoleUrgency=u;
83 }
84
85 void Logger::open()
86 {
87 if(opened)
88 closelog();
89 openlog(name.c_str(),flags,d_facility);
90 opened=true;
91 }
92
93 void Logger::setName(const string &_name)
94 {
95 name=_name;
96 open();
97 }
98
99 void Logger::initKey()
100 {
101 if(pthread_key_create(&g_loggerKey, perThreadDestructor))
102 unixDie("Creating thread key for logger");
103 }
104
105 Logger::Logger(const string &n, int facility) :
106 name(n), flags(LOG_PID|LOG_NDELAY), d_facility(facility), d_loglevel(Logger::None),
107 consoleUrgency(Error), opened(false), d_disableSyslog(false)
108 {
109 if(pthread_once(&s_once, initKey))
110 unixDie("Creating thread key for logger");
111
112 open();
113
114 }
115
116 Logger& Logger::operator<<(Urgency u)
117 {
118 getPerThread()->d_urgency=u;
119 return *this;
120 }
121
122 void Logger::perThreadDestructor(void* buf)
123 {
124 PerThread* pt = (PerThread*) buf;
125 delete pt;
126 }
127
128 Logger::PerThread* Logger::getPerThread()
129 {
130 void *buf=pthread_getspecific(g_loggerKey);
131 PerThread* ret;
132 if(buf)
133 ret = (PerThread*) buf;
134 else {
135 ret = new PerThread();
136 pthread_setspecific(g_loggerKey, (void*)ret);
137 }
138 return ret;
139 }
140
141 Logger& Logger::operator<<(const string &s)
142 {
143 PerThread* pt =getPerThread();
144 pt->d_output.append(s);
145 return *this;
146 }
147
148 Logger& Logger::operator<<(const char *s)
149 {
150 *this<<string(s);
151 return *this;
152 }
153
154 Logger& Logger::operator<<(int i)
155 {
156 ostringstream tmp;
157 tmp<<i;
158
159 *this<<tmp.str();
160
161 return *this;
162 }
163
164 Logger& Logger::operator<<(double i)
165 {
166 ostringstream tmp;
167 tmp<<i;
168 *this<<tmp.str();
169 return *this;
170 }
171
172 Logger& Logger::operator<<(unsigned int i)
173 {
174 ostringstream tmp;
175 tmp<<i;
176
177 *this<<tmp.str();
178
179 return *this;
180 }
181
182 Logger& Logger::operator<<(unsigned long i)
183 {
184 ostringstream tmp;
185 tmp<<i;
186
187 *this<<tmp.str();
188
189 return *this;
190 }
191
192 Logger& Logger::operator<<(unsigned long long i)
193 {
194 ostringstream tmp;
195 tmp<<i;
196
197 *this<<tmp.str();
198
199 return *this;
200 }
201
202 Logger& Logger::operator<<(long i)
203 {
204 ostringstream tmp;
205 tmp<<i;
206
207 *this<<tmp.str();
208
209 return *this;
210 }
211
212 Logger& Logger::operator<<(ostream & (&)(ostream &))
213 {
214 PerThread* pt =getPerThread();
215
216 log(pt->d_output, pt->d_urgency);
217 pt->d_output.clear();
218 pt->d_urgency=Info;
219 return *this;
220 }
221
222 Logger& Logger::operator<<(const DNSName &d)
223 {
224 *this<<d.toLogString();
225
226 return *this;
227 }
228
229 Logger& Logger::operator<<(const ComboAddress &ca)
230 {
231 *this<<ca.toString();
232 return *this;
233 }
234