auditd-plugin-clickhouse/logging.cpp

130 lines
2.3 KiB
C++
Raw Normal View History

/*
* 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;
}
}