2020-01-10 14:59:03 +03:00
/*
* 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"
2020-01-15 16:17:46 +03:00
# include <time.h>
2020-01-10 14:59:03 +03:00
# include <boost/scope_exit.hpp>
std : : mutex Logger : : s_mutex ;
Logger : : Logger ( )
{
}
Logger : : ~ Logger ( )
{
dump_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 )
{
2020-01-14 13:06:22 +03:00
m_logfile_name = filename ;
2020-01-10 14:59:03 +03:00
}
void Logger : : write_impl ( const char * format , va_list args )
{
2020-01-14 13:06:22 +03:00
FILE * outfile = NULL ;
2020-01-15 16:17:46 +03:00
std : : string datestring = getdatestring ( ) ;
2020-01-14 13:06:22 +03:00
if ( ! m_logfile_name . empty ( ) )
{
outfile = fopen ( m_logfile_name . c_str ( ) , " at " ) ;
}
if ( outfile ! = NULL )
2020-01-10 14:59:03 +03:00
{
2020-01-15 16:17:46 +03:00
fprintf ( outfile , " %s: " , datestring . c_str ( ) ) ;
2020-01-14 13:06:22 +03:00
vfprintf ( outfile , format , args ) ;
2020-01-15 16:17:46 +03:00
fprintf ( outfile , " \n " ) ;
2020-01-10 14:59:03 +03:00
2020-01-14 13:06:22 +03:00
fclose ( outfile ) ;
2020-01-10 14:59:03 +03:00
}
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 ) )
{
2020-01-15 16:17:46 +03:00
m_lines . push_back ( std : : make_pair ( datestring , data ) ) ;
2020-01-10 14:59:03 +03:00
}
}
}
void Logger : : dump_impl ( )
{
2020-01-14 13:06:22 +03:00
FILE * outfile = NULL ;
2020-01-10 14:59:03 +03:00
2020-01-14 13:06:22 +03:00
if ( ! m_logfile_name . empty ( ) )
2020-01-10 14:59:03 +03:00
{
2020-01-14 13:06:22 +03:00
outfile = fopen ( m_logfile_name . c_str ( ) , " at " ) ;
2020-01-10 14:59:03 +03:00
}
2020-01-14 13:06:22 +03:00
for ( auto iter = m_lines . begin ( ) ; iter ! = m_lines . end ( ) ; + + iter )
{
2020-01-15 16:17:46 +03:00
fprintf ( ( outfile ! = NULL ) ? outfile : stderr , " %s: %s \n " , iter - > first . c_str ( ) , iter - > second . c_str ( ) ) ;
2020-01-14 13:06:22 +03:00
}
2020-01-10 14:59:03 +03:00
2020-01-14 13:06:22 +03:00
if ( outfile ! = NULL )
2020-01-10 14:59:03 +03:00
{
2020-01-14 13:06:22 +03:00
fclose ( outfile ) ;
2020-01-10 14:59:03 +03:00
}
2020-01-14 13:06:22 +03:00
else
{
fflush ( stderr ) ;
}
m_lines . clear ( ) ;
2020-01-10 14:59:03 +03:00
}
2020-01-15 16:17:46 +03:00
std : : string Logger : : getdatestring ( ) const
{
std : : string result ;
time_t t = time ( nullptr ) ;
struct tm tm_inst ;
auto tm_ptr = localtime_r ( & t , & tm_inst ) ;
if ( tm_ptr ! = nullptr )
{
char buffer [ 4096 ] ;
auto buffer_res = strftime ( buffer , sizeof ( buffer ) - 1 , " %c %Z " , tm_ptr ) ;
if ( buffer_res > 0 )
{
buffer [ buffer_res ] = 0 ;
result = buffer ;
}
}
return result ;
}