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 
24 #include <string>
25 #include <ctime>
26 #include <iostream>
27 #include <sstream>
28 #include <syslog.h>
29 
30 #include "namespaces.hh"
31 #include "dnsname.hh"
32 #include "iputils.hh"
33 
34 //! The Logger class can be used to log messages in various ways.
35 class Logger
36 {
37 public:
38   Logger(string , int facility=LOG_DAEMON); //!< pass the identification you wish to appear in the log
39 
40   //! The urgency of a log message
41   enum Urgency {All=32767,Alert=LOG_ALERT, Critical=LOG_CRIT, Error=LOG_ERR, Warning=LOG_WARNING,
42                 Notice=LOG_NOTICE,Info=LOG_INFO, Debug=LOG_DEBUG, None=-1};
43 
44   /** Log a message.
45       \param msg Message you wish to log
46       \param u Urgency of the message you wish to log
47   */
48   void log(const string &msg, Urgency u=Notice) noexcept;
49 
setFacility(int f)50   void setFacility(int f){d_facility=f;open();} //!< Choose logging facility
setFlag(int f)51   void setFlag(int f){flags|=f;open();} //!< set a syslog flag
52   void setName(const string &);
53 
54   //! set lower limit of urgency needed for console display. Messages of this urgency, and higher, will be displayed
55   void toConsole(Urgency);
56   void setLoglevel( Urgency );
57 
disableSyslog(bool d)58   void disableSyslog(bool d) {
59     d_disableSyslog = d;
60   }
61 
setTimestamps(bool t)62   void setTimestamps(bool t) {
63     d_timestamps = t;
64   }
65 
setPrefixed(bool p)66   void setPrefixed(bool p) {
67     d_prefixed = p;
68   }
69 
70   //! Log to a file.
71   void toFile( const string & filename );
72 
resetFlags()73   void resetFlags(){flags=0;open();} //!< zero the flags
74   /** Use this to stream to your log, like this:
75       \code
76       g_log<<"This is an informational message"<<endl; // logged at default loglevel (Info)
77       g_log<<Logger::Warning<<"Out of diskspace"<<endl; // Logged as a warning
78       g_log<<"This is an informational message"<<endl; // logged AGAIN at default loglevel (Info)
79       \endcode
80   */
81   Logger& operator<<(const char *s);
82   Logger& operator<<(const string &s);   //!< log a string
83   Logger& operator<<(const DNSName&);
84   Logger& operator<<(const ComboAddress&); //!< log an address
85   Logger& operator<<(Urgency);    //!< set the urgency, << style
86 
87   // Using const & since otherwise SyncRes:: values induce (illegal) copies
operator <<(const T & i)88   template<typename T> Logger & operator<<(const T & i) {
89 	ostringstream tmp;
90 	tmp<<i;
91 	*this<<tmp.str();
92 	return *this;
93   }
94 
95   Logger& operator<<(std::ostream & (&)(std::ostream &)); //!< this is to recognise the endl, and to commit the log
96 
97 private:
98   struct PerThread
99   {
PerThreadLogger::PerThread100     PerThread() : d_urgency(Info)
101     {}
102     string d_output;
103     Urgency d_urgency;
104   };
105   PerThread& getPerThread();
106   void open();
107 
108   static thread_local PerThread t_perThread;
109   string name;
110   int flags;
111   int d_facility;
112   Urgency d_loglevel;
113   Urgency consoleUrgency;
114   bool opened;
115   bool d_disableSyslog;
116   bool d_timestamps{true};
117   bool d_prefixed{false};
118 };
119 
120 Logger& getLogger();
121 
122 #define g_log getLogger()
123 
124 #ifdef VERBOSELOG
125 #define DLOG(x) x
126 #else
127 #define DLOG(x) ((void)0)
128 #endif
129