/* * This is an auditd plugin for sending auditd data * to clickhouse DB. * Copyright (C) 2020 Aleksei Nikiforov * * 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 . * */ #include "logging.hpp" #include 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 lock(s_mutex); instance().open_impl(filename); } void Logger::write(const char *format, ...) { std::lock_guard lock(s_mutex); va_list args; va_start(args, format); instance().write_impl(format, args); va_end(args); } void Logger::dump() { std::lock_guard 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; } }