blob: b05e7fde5ea18da402b5937b456795afa28b6187 [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2009, 2010 Free Software Foundation, Inc.
3* Copyright 2010 Kestrel Signal Processing, Inc.
kurtis.heimerl5a872472013-05-31 21:47:25 +00004* Copyright 2011, 2012 Range Networks, Inc.
dburgess82c46ff2011-10-07 02:40:51 +00005*
6*
7* This software is distributed under the terms of the GNU Affero Public License.
8* See the COPYING file in the main directory for details.
9*
10* This use of this software may be subject to additional restrictions.
11* See the LEGAL file in the main directory for details.
12
13 This program is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Affero General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Affero General Public License for more details.
22
23 You should have received a copy of the GNU Affero General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26*/
27
28#include <string.h>
29#include <cstdio>
30#include <fstream>
31#include <string>
kurtis.heimerl00913d72012-12-16 06:08:18 +000032#include <stdarg.h>
Alexander Chemeris4793f462017-03-17 18:35:48 -070033#include <sys/time.h> // For gettimeofday
dburgess82c46ff2011-10-07 02:40:51 +000034
dburgess82c46ff2011-10-07 02:40:51 +000035#include "Logger.h"
kurtis.heimerl5a872472013-05-31 21:47:25 +000036#include "Threads.h" // pat added
dburgess82c46ff2011-10-07 02:40:51 +000037
dburgess82c46ff2011-10-07 02:40:51 +000038using namespace std;
39
Alexander Chemerisa8cf2082015-07-30 20:04:18 -040040// Switches to enable/disable logging targets
Alexander Chemerisa8cf2082015-07-30 20:04:18 -040041bool gLogToConsole = true;
Alexander Chemerisa8cf2082015-07-30 20:04:18 -040042Mutex gLogToLock;
43
Pau Espin Pedrolf3837d22018-01-09 14:49:33 +010044// Global log level threshold:
45int config_log_level;
dburgess82c46ff2011-10-07 02:40:51 +000046
dburgess82c46ff2011-10-07 02:40:51 +000047/** Names of the logging levels. */
48const char *levelNames[] = {
49 "EMERG", "ALERT", "CRIT", "ERR", "WARNING", "NOTICE", "INFO", "DEBUG"
50};
51int numLevels = 8;
52
53
kurtis.heimerl5a872472013-05-31 21:47:25 +000054int levelStringToInt(const string& name)
dburgess82c46ff2011-10-07 02:40:51 +000055{
56 // Reverse search, since the numerically larger levels are more common.
57 for (int i=numLevels-1; i>=0; i--) {
58 if (name == levelNames[i]) return i;
59 }
kurtis.heimerl5a872472013-05-31 21:47:25 +000060
61 // Common substitutions.
62 if (name=="INFORMATION") return 6;
63 if (name=="WARN") return 4;
64 if (name=="ERROR") return 3;
65 if (name=="CRITICAL") return 2;
66 if (name=="EMERGENCY") return 0;
67
68 // Unknown level.
69 return -1;
70}
71
Alexander Chemeris4793f462017-03-17 18:35:48 -070072static std::string format(const char *fmt, ...)
73{
74 va_list ap;
75 char buf[300];
76 va_start(ap,fmt);
77 int n = vsnprintf(buf,300,fmt,ap);
78 va_end(ap);
79 if (n >= (300-4)) { strcpy(&buf[(300-4)],"..."); }
80 return std::string(buf);
81}
82
83const std::string timestr()
84{
85 struct timeval tv;
86 struct tm tm;
87 gettimeofday(&tv,NULL);
88 localtime_r(&tv.tv_sec,&tm);
89 unsigned tenths = tv.tv_usec / 100000; // Rounding down is ok.
90 return format(" %02d:%02d:%02d.%1d",tm.tm_hour,tm.tm_min,tm.tm_sec,tenths);
91}
92
93std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
94{
95 return os << ss.str();
96}
dburgess82c46ff2011-10-07 02:40:51 +000097
dburgess82c46ff2011-10-07 02:40:51 +000098Log::~Log()
99{
100 // Anything at or above LOG_CRIT is an "alarm".
Alexander Chemeriscc6f79b2015-03-01 10:30:12 +0100101 if (mPriority <= LOG_ERR) {
dburgess82c46ff2011-10-07 02:40:51 +0000102 cerr << mStream.str() << endl;
103 }
Alexander Chemeris57219202015-05-24 13:20:44 -0400104 // Log to file and console
Pau Espin Pedrol01aff882018-02-20 17:56:59 +0100105 if (gLogToConsole) {
kurtis.heimerl5a872472013-05-31 21:47:25 +0000106 int mlen = mStream.str().size();
107 int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
Alexander Chemeris909ffbf2015-06-04 00:09:29 -0400108 ScopedLock lock(gLogToLock);
kurtis.heimerl5a872472013-05-31 21:47:25 +0000109 if (gLogToConsole) {
110 // The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
111 // so just use std::cout.
112 std::cout << mStream.str();
113 if (neednl) std::cout<<"\n";
114 }
kurtis.heimerl5a872472013-05-31 21:47:25 +0000115 }
dburgess82c46ff2011-10-07 02:40:51 +0000116}
117
dburgess82c46ff2011-10-07 02:40:51 +0000118ostringstream& Log::get()
119{
120 assert(mPriority<numLevels);
121 mStream << levelNames[mPriority] << ' ';
122 return mStream;
123}
124
125
126
Pau Espin Pedrol11d50d92018-02-20 17:52:28 +0100127void gLogInit(const char* level, char *fn)
dburgess82c46ff2011-10-07 02:40:51 +0000128{
kurtis.heimerl5a872472013-05-31 21:47:25 +0000129 // Set the level if one has been specified.
Pau Espin Pedrolf3837d22018-01-09 14:49:33 +0100130 if (level)
131 config_log_level = levelStringToInt(level);
dburgess82c46ff2011-10-07 02:40:51 +0000132}
133
dburgess82c46ff2011-10-07 02:40:51 +0000134// vim: ts=4 sw=4