]> granicus.if.org Git - icinga2/blob - lib/base/logger.cpp
Change copyright header for 2018
[icinga2] / lib / base / logger.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "base/logger.hpp"
21 #include "base/logger.tcpp"
22 #include "base/application.hpp"
23 #include "base/streamlogger.hpp"
24 #include "base/configtype.hpp"
25 #include "base/utility.hpp"
26 #include "base/objectlock.hpp"
27 #include "base/context.hpp"
28 #include "base/scriptglobal.hpp"
29 #include <iostream>
30
31 using namespace icinga;
32
33 REGISTER_TYPE(Logger);
34
35 std::set<Logger::Ptr> Logger::m_Loggers;
36 boost::mutex Logger::m_Mutex;
37 bool Logger::m_ConsoleLogEnabled = true;
38 bool Logger::m_TimestampEnabled = true;
39 LogSeverity Logger::m_ConsoleLogSeverity = LogInformation;
40
41 INITIALIZE_ONCE([]() {
42         ScriptGlobal::Set("LogDebug", LogDebug);
43         ScriptGlobal::Set("LogNotice", LogNotice);
44         ScriptGlobal::Set("LogInformation", LogInformation);
45         ScriptGlobal::Set("LogWarning", LogWarning);
46         ScriptGlobal::Set("LogCritical", LogCritical);
47 });
48
49 /**
50  * Constructor for the Logger class.
51  */
52 void Logger::Start(bool runtimeCreated)
53 {
54         ObjectImpl<Logger>::Start(runtimeCreated);
55
56         boost::mutex::scoped_lock lock(m_Mutex);
57         m_Loggers.insert(this);
58 }
59
60 void Logger::Stop(bool runtimeRemoved)
61 {
62         {
63                 boost::mutex::scoped_lock lock(m_Mutex);
64                 m_Loggers.erase(this);
65         }
66
67         ObjectImpl<Logger>::Stop(runtimeRemoved);
68 }
69
70 std::set<Logger::Ptr> Logger::GetLoggers(void)
71 {
72         boost::mutex::scoped_lock lock(m_Mutex);
73         return m_Loggers;
74 }
75
76 /**
77  * Writes a message to the application's log.
78  *
79  * @param severity The message severity.
80  * @param facility The log facility.
81  * @param message The message.
82  */
83 void icinga::IcingaLog(LogSeverity severity, const String& facility,
84         const String& message)
85 {
86         LogEntry entry;
87         entry.Timestamp = Utility::GetTime();
88         entry.Severity = severity;
89         entry.Facility = facility;
90         entry.Message = message;
91
92         if (severity >= LogWarning) {
93                 ContextTrace context;
94
95                 if (context.GetLength() > 0) {
96                         std::ostringstream trace;
97                         trace << context;
98                         entry.Message += "\nContext:" + trace.str();
99                 }
100         }
101
102         for (const Logger::Ptr& logger : Logger::GetLoggers()) {
103                 ObjectLock llock(logger);
104
105                 if (!logger->IsActive())
106                         continue;
107
108                 if (entry.Severity >= logger->GetMinSeverity())
109                         logger->ProcessLogEntry(entry);
110         }
111
112         if (Logger::IsConsoleLogEnabled() && entry.Severity >= Logger::GetConsoleLogSeverity())
113                 StreamLogger::ProcessLogEntry(std::cout, entry);
114 }
115
116 /**
117  * Retrieves the minimum severity for this logger.
118  *
119  * @returns The minimum severity.
120  */
121 LogSeverity Logger::GetMinSeverity(void) const
122 {
123         String severity = GetSeverity();
124         if (severity.IsEmpty())
125                 return LogInformation;
126         else {
127                 LogSeverity ls = LogInformation;
128
129                 try {
130                         ls = Logger::StringToSeverity(severity);
131                 } catch (const std::exception&) { /* use the default level */ }
132
133                 return ls;
134         }
135 }
136
137 /**
138  * Converts a severity enum value to a string.
139  *
140  * @param severity The severity value.
141  */
142 String Logger::SeverityToString(LogSeverity severity)
143 {
144         switch (severity) {
145                 case LogDebug:
146                         return "debug";
147                 case LogNotice:
148                         return "notice";
149                 case LogInformation:
150                         return "information";
151                 case LogWarning:
152                         return "warning";
153                 case LogCritical:
154                         return "critical";
155                 default:
156                         BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid severity."));
157         }
158 }
159
160 /**
161  * Converts a string to a severity enum value.
162  *
163  * @param severity The severity.
164  */
165 LogSeverity Logger::StringToSeverity(const String& severity)
166 {
167         if (severity == "debug")
168                 return LogDebug;
169         else if (severity == "notice")
170                 return LogNotice;
171         else if (severity == "information")
172                 return LogInformation;
173         else if (severity == "warning")
174                 return LogWarning;
175         else if (severity == "critical")
176                 return LogCritical;
177         else
178                 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid severity: " + severity));
179 }
180
181 void Logger::DisableConsoleLog(void)
182 {
183         m_ConsoleLogEnabled = false;
184 }
185
186 void Logger::EnableConsoleLog(void)
187 {
188         m_ConsoleLogEnabled = true;
189 }
190
191 bool Logger::IsConsoleLogEnabled(void)
192 {
193         return m_ConsoleLogEnabled;
194 }
195
196 void Logger::SetConsoleLogSeverity(LogSeverity logSeverity)
197 {
198         m_ConsoleLogSeverity = logSeverity;
199 }
200
201 LogSeverity Logger::GetConsoleLogSeverity(void)
202 {
203         return m_ConsoleLogSeverity;
204 }
205
206 void Logger::DisableTimestamp(bool disable)
207 {
208         m_TimestampEnabled = !disable;
209 }
210
211 bool Logger::IsTimestampEnabled(void)
212 {
213         return m_TimestampEnabled;
214 }
215
216 void Logger::ValidateSeverity(const String& value, const ValidationUtils& utils)
217 {
218         ObjectImpl<Logger>::ValidateSeverity(value, utils);
219
220         try {
221                 StringToSeverity(value);
222         } catch (...) {
223                 BOOST_THROW_EXCEPTION(ValidationError(this, { "severity" }, "Invalid severity specified: " + value));
224         }
225 }