<commit_before>#include <ctime>
#include <cctype>

#include "core/RoleFactory.h"
#include "EventLogger.h"

static ConfigVariable<std::string> bind_addr("bind", "0.0.0.0:7197");
static ConfigVariable<std::string> output_format("output", "events-%Y%m%d-%H%M%S.csv");

EventLogger::EventLogger(RoleConfig roleconfig) : Role(roleconfig), m_log("eventlogger", "Event Logger")
{
	bind(bind_addr.get_rval(roleconfig));

	m_file_format = output_format.get_rval(roleconfig);
	open_log();
	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log opened upon Event Logger startup.");
	write_log(msg);

	start_receive();
}

void EventLogger::bind(const std::string &addr)
{
	m_log.info() << "Opening UDP socket..." << std::endl;
	std::string str_ip = addr;
	std::string str_port = str_ip.substr(str_ip.find(':', 0)+1, std::string::npos);
	str_ip = str_ip.substr(0, str_ip.find(':', 0));
	udp::resolver resolver(io_service);
	udp::resolver::query query(str_ip, str_port);
	udp::resolver::iterator it = resolver.resolve(query);
	m_socket = new udp::socket(io_service, *it);
}

void EventLogger::open_log()
{
	time_t rawtime;
	time(&rawtime);

	char filename[1024];
	strftime(filename, 1024, m_file_format.c_str(), localtime(&rawtime));
	m_log.debug() << "New log filename: " << filename << std::endl;

	if(m_file)
		m_file->close();

	m_file = new ofstream(filename);

	m_log.info() << "Opened new log." << std::endl;
}

void EventLogger::cycle_log()
{
	open_log();

	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log cycled.");
	write_log(msg);
}

void EventLogger::write_log(const std::vector<std::string> &msg)
{
	time_t rawtime;
	time(&rawtime);

	char timestamp[1024];
	strftime(timestamp, 1024, "\"%Y-%m-%d %H:%M:%S\"", localtime(&rawtime));

	*m_file << timestamp;

	for(auto it = msg.begin(); it != msg.end(); ++it)
	{
		// If the column consists purely of alphanumerics, we can just dump it
		// without quoting it...
		bool alnum = true;
		for(const char *c = it->c_str(); *c; ++c)
		{
			if(!isalnum(*c))
			{
				alnum = false;
				break;
			}
		}
		if(alnum)
		{
			*m_file << ',' << *it;
			continue;<commit_msg>EventLogger: Don't quote just because a column contains '_'.<commit_after>#include <ctime>
#include <cctype>

#include "core/RoleFactory.h"
#include "EventLogger.h"

static ConfigVariable<std::string> bind_addr("bind", "0.0.0.0:7197");
static ConfigVariable<std::string> output_format("output", "events-%Y%m%d-%H%M%S.csv");

EventLogger::EventLogger(RoleConfig roleconfig) : Role(roleconfig), m_log("eventlogger", "Event Logger")
{
	bind(bind_addr.get_rval(roleconfig));

	m_file_format = output_format.get_rval(roleconfig);
	open_log();
	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log opened upon Event Logger startup.");
	write_log(msg);

	start_receive();
}

void EventLogger::bind(const std::string &addr)
{
	m_log.info() << "Opening UDP socket..." << std::endl;
	std::string str_ip = addr;
	std::string str_port = str_ip.substr(str_ip.find(':', 0)+1, std::string::npos);
	str_ip = str_ip.substr(0, str_ip.find(':', 0));
	udp::resolver resolver(io_service);
	udp::resolver::query query(str_ip, str_port);
	udp::resolver::iterator it = resolver.resolve(query);
	m_socket = new udp::socket(io_service, *it);
}

void EventLogger::open_log()
{
	time_t rawtime;
	time(&rawtime);

	char filename[1024];
	strftime(filename, 1024, m_file_format.c_str(), localtime(&rawtime));
	m_log.debug() << "New log filename: " << filename << std::endl;

	if(m_file)
		m_file->close();

	m_file = new ofstream(filename);

	m_log.info() << "Opened new log." << std::endl;
}

void EventLogger::cycle_log()
{
	open_log();

	std::vector<std::string> msg;
	msg.push_back("EventLogger");
	msg.push_back("log_opened");
	msg.push_back("Log cycled.");
	write_log(msg);
}

void EventLogger::write_log(const std::vector<std::string> &msg)
{
	time_t rawtime;
	time(&rawtime);

	char timestamp[1024];
	strftime(timestamp, 1024, "\"%Y-%m-%d %H:%M:%S\"", localtime(&rawtime));

	*m_file << timestamp;

	for(auto it = msg.begin(); it != msg.end(); ++it)
	{
		// If the column consists purely of alphanumerics, we can just dump it
		// without quoting it...
		bool alnum = true;
		for(const char *c = it->c_str(); *c; ++c)
		{
			if(!isalnum(*c) && *c != '_')
			{
				alnum = false;
				break;
			}
		}
		if(alnum)
		{
			*m_file << ',' << *it;
			continue;
{'fraction_non_alphanumeric': 0.19176262178919398, 'fraction_numerical': 0.012400354295837024, 'mean_word_length': 5.398016997167139, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7126855', 'n_tokens_mistral': 1842, 'n_tokens_neox': 1717, 'n_words': 332}