130 lines
2.3 KiB
C++
130 lines
2.3 KiB
C++
|
/*
|
||
|
* This is an auditd plugin for sending auditd data
|
||
|
* to clickhouse DB.
|
||
|
* Copyright (C) 2020 Aleksei Nikiforov <darktemplar@basealt.ru>
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program 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 General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "logging.hpp"
|
||
|
|
||
|
#include <boost/scope_exit.hpp>
|
||
|
|
||
|
std::mutex Logger::s_mutex;
|
||
|
|
||
|
Logger::Logger()
|
||
|
: m_logfile(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Logger::~Logger()
|
||
|
{
|
||
|
dump_impl();
|
||
|
close_impl();
|
||
|
}
|
||
|
|
||
|
Logger& Logger::instance()
|
||
|
{
|
||
|
static Logger s_instance;
|
||
|
return s_instance;
|
||
|
}
|
||
|
|
||
|
void Logger::open(const char *filename)
|
||
|
{
|
||
|
std::lock_guard<std::mutex> lock(s_mutex);
|
||
|
instance().open_impl(filename);
|
||
|
}
|
||
|
|
||
|
void Logger::write(const char *format, ...)
|
||
|
{
|
||
|
std::lock_guard<std::mutex> lock(s_mutex);
|
||
|
|
||
|
va_list args;
|
||
|
|
||
|
va_start(args, format);
|
||
|
instance().write_impl(format, args);
|
||
|
va_end(args);
|
||
|
}
|
||
|
|
||
|
void Logger::dump()
|
||
|
{
|
||
|
std::lock_guard<std::mutex> lock(s_mutex);
|
||
|
instance().dump_impl();
|
||
|
}
|
||
|
|
||
|
void Logger::open_impl(const char *filename)
|
||
|
{
|
||
|
close_impl();
|
||
|
|
||
|
FILE *f = fopen(filename, "at");
|
||
|
if (f)
|
||
|
{
|
||
|
m_logfile = f;
|
||
|
dump_impl();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Logger::write_impl(const char *format, va_list args)
|
||
|
{
|
||
|
if (m_logfile)
|
||
|
{
|
||
|
vfprintf(m_logfile, format, args);
|
||
|
|
||
|
fflush(m_logfile);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// save logged data for later use
|
||
|
char *data = NULL;
|
||
|
|
||
|
BOOST_SCOPE_EXIT(&data)
|
||
|
{
|
||
|
if (data != NULL)
|
||
|
{
|
||
|
free(data);
|
||
|
}
|
||
|
} BOOST_SCOPE_EXIT_END;
|
||
|
|
||
|
int result = vasprintf(&data, format, args);
|
||
|
|
||
|
if ((result >= 0) && (data != NULL))
|
||
|
{
|
||
|
m_lines.push_back(data);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Logger::dump_impl()
|
||
|
{
|
||
|
FILE *outfile = m_logfile ? m_logfile : stderr;
|
||
|
|
||
|
for (auto iter = m_lines.begin(); iter != m_lines.end(); ++iter)
|
||
|
{
|
||
|
fwrite(iter->c_str(), 1, iter->length(), outfile);
|
||
|
}
|
||
|
|
||
|
fflush(outfile);
|
||
|
m_lines.clear();
|
||
|
}
|
||
|
|
||
|
void Logger::close_impl()
|
||
|
{
|
||
|
if (m_logfile)
|
||
|
{
|
||
|
fclose(m_logfile);
|
||
|
m_logfile = NULL;
|
||
|
}
|
||
|
}
|