1f6411b6ac
LoggerSyslog copied quite a bit of code from LoggerStdout. Moved that code into the LoggerBase. That avoids code duplication and allows LoggerSyslog to benefit from improvements made recently in that code (prefix in each line). As it was before, LoggerSyslog did not handle line breaks inside the printed text. syslog() showed them as #012. Now each line is passed to syslog() separately, with a proper prefix. The level in the syslog() also seemed to be wrong earlier. It needs to be based on the log level of the current message, not on the threshold set for logging in the logger.
102 lines
2.9 KiB
C++
102 lines
2.9 KiB
C++
/*
|
|
* Copyright (C) 2012 Intel Corporation
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) version 3.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301 USA
|
|
*/
|
|
|
|
#include <syncevo/LogSyslog.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <syslog.h>
|
|
|
|
#include <boost/bind.hpp>
|
|
|
|
#include <syncevo/declarations.h>
|
|
using namespace std;
|
|
SE_BEGIN_CXX
|
|
|
|
LoggerSyslog::LoggerSyslog(const std::string &processName)
|
|
: m_processName(processName)
|
|
{
|
|
openlog(m_processName.c_str(), LOG_CONS | LOG_NDELAY | LOG_PID, LOG_USER);
|
|
LoggerBase::pushLogger(this);
|
|
}
|
|
|
|
LoggerSyslog::~LoggerSyslog()
|
|
{
|
|
closelog();
|
|
LoggerBase::popLogger();
|
|
}
|
|
|
|
static void printToSyslog(int sysloglevel, std::string &chunk, size_t expectedTotal)
|
|
{
|
|
if (!expectedTotal) {
|
|
// Might contain line breaks in the middle, split it.
|
|
size_t pos = 0;
|
|
while(true) {
|
|
size_t next = chunk.find('\n', pos);
|
|
if (next == chunk.npos) {
|
|
// Line break is guaranteed to be last character,
|
|
// so we have printed everything now.
|
|
return;
|
|
}
|
|
chunk[next] = 0;
|
|
syslog(sysloglevel, "%s", chunk.c_str() + pos);
|
|
pos = next + 1;
|
|
}
|
|
} else {
|
|
// Single line. We can print the trailing line break.
|
|
syslog(sysloglevel, "%s", chunk.c_str());
|
|
}
|
|
}
|
|
|
|
void LoggerSyslog::messagev(Level level,
|
|
const char *prefix,
|
|
const char *file,
|
|
int line,
|
|
const char *function,
|
|
const char *format,
|
|
va_list args)
|
|
{
|
|
|
|
if (level <= getLevel()) {
|
|
formatLines(level, getLevel(),
|
|
"", // process name is set when opening the syslog
|
|
prefix,
|
|
format, args,
|
|
boost::bind(printToSyslog, getSyslogLevel(level), _1, _2));
|
|
}
|
|
}
|
|
|
|
int LoggerSyslog::getSyslogLevel(Level level)
|
|
{
|
|
switch (level) {
|
|
case ERROR:
|
|
return LOG_ERR;
|
|
case WARNING:
|
|
return LOG_WARNING;
|
|
case SHOW:
|
|
return LOG_NOTICE;
|
|
case INFO:
|
|
case DEV:
|
|
return LOG_INFO;
|
|
case DEBUG:
|
|
default:
|
|
return LOG_DEBUG;
|
|
}
|
|
}
|
|
|
|
SE_END_CXX
|