Skip to content

Instantly share code, notes, and snippets.

@dedmen
Created January 19, 2018 07:51
Show Gist options
  • Save dedmen/1bd0f7211834841b13043bf2c5477543 to your computer and use it in GitHub Desktop.
Save dedmen/1bd0f7211834841b13043bf2c5477543 to your computer and use it in GitHub Desktop.
#include "serverLogger.h"
#include <boost/filesystem.hpp>
serverLogger::serverLogger(std::string _logPath, std::string _logPrefix, std::string _logSuffix, bool _instantFlush, bool _withFiltered, bool _logDate) :
filterRegex("String [A-Za-z0-9_]* not found", boost::regex_constants::optimize | boost::regex_constants::no_except | boost::regex_constants::normal),
timestampRegex("[0-9]+:[0-9]+:[0-9]+ ", boost::regex_constants::optimize | boost::regex_constants::no_except | boost::regex_constants::extended),
logPath(_logPath),
logPrefix(_logPrefix),
logSuffix(_logSuffix),
instantFlush (_instantFlush),
withFilteredLog(_withFiltered),
logDate(_logDate) {}
serverLogger::~serverLogger() {
if (logFile)
logFile->close();
}
void serverLogger::newLog() {
auto t = std::time(nullptr);
auto tm = *std::localtime(&t);
char buffer[80];
auto timestampString = std::string(buffer, strftime(buffer, 80, "%d-%m-%Y_%H-%M-%S", &tm)); //OUHHH such a haxor
if (logFile) {
logFile->flush();
logFile->close();
}
//#TODO delete the old log if it was empty
//overwriting the old logFile will delete it... cuz refcounted
logFile = boost::make_shared<std::ofstream>(logPath + "/" + logPrefix + "_" + timestampString + "_" + logSuffix + ".txt");
#ifdef logFiltered
if (withFilteredLog)
logFileFiltered = boost::make_shared<std::ofstream>(logPath + "/" + logPrefix + "_" + timestampString + "_" + logSuffix + "_filt.txt");
#endif
}
void serverLogger::log(std::string msg) {
//printf("CLOG %s\n", msg.c_str());
msg = boost::regex_replace(msg, timestampRegex, "");//removes timestamps from input
#ifdef __GNUCC__
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
//auto t = std::time(nullptr);
auto tm = *std::localtime(&spec.tv_sec);
char buffer[80] = { 0 };
char buffer2[80] = { 0 };
if (logDate)
strftime(buffer, 80, "%d-%m %H:%M:%S", &tm);
else
strftime(buffer, 80, "%H:%M:%S", &tm);
snprintf(buffer2, 89, "%s:%03u ", buffer, spec.tv_nsec / 1000);
auto timestampString = std::string(buffer2); //OUHHH such a haxor
#else
auto timestampString = std::string(); //OUHHH such a haxor
#endif
//Error: Bone slot_backwpnr doesn't exist in skeleton OFP2_ManSkeleton
boost::regex boneExpr("Error: Bone .* doesn't exist in skeleton .*", boost::regex_constants::optimize | boost::regex_constants::no_except | boost::regex_constants::normal);
boost::cmatch what;
bool foundBones = false;
std::vector<std::string> out;
boost::algorithm::split(out, msg, boost::is_any_of("\n"), boost::token_compress_on);
for (std::string &iterator : out) {
if (iterator.length() < 5)
continue;
boost::string_ref ref(iterator); //String refs are faster to remove a char on front index
while (ref.starts_with(' ')) //removes all spaces in beginning
ref = ref.substr(1);
//printf("LOG %s\n", iterator.c_str());
if (withFilteredLog && isFiltered(ref)) {
#ifdef logFiltered
if (logFileFiltered) {
std::string output = timestampString + iterator + "\n";
logFileFiltered->write(output.c_str(), output.size());
if (instantFlush)
logFileFiltered->flush();
}
#endif
//printf("filter %s\n", iterator.c_str());
continue;
}
if (boost::regex_match(ref.data(), what, boneExpr)) {//we need special fuckage for replacing stuff with a single msg
foundBones = true;
continue;
}
//-- Capture Frame saved to file /home/wolf/.local/share/Arma 3/captureFrame-28113-2017-01-22_01-13-50.log --
if (boost::algorithm::contains(ref, "saved to file"))
profLogWritten(ref.to_string());
//Special signal for important messages
if (
boost::algorithm::starts_with(ref, "Conflicting addon") || //Client: Nonnetwork object 79846380.
boost::algorithm::starts_with(ref, "File ") //Attempt to override final function
) {
imporantLineLogged(msg);//prints whole block even if only one line is important but we wan't that for errors
}
//didnt match any of our exclusions so lets write to log
std::string output = timestampString + iterator + "\n";
if (logFile) {
logFile->write(output.c_str(), output.size());
if (instantFlush)
logFile->flush();
}
else
printf("%s\n",(logPrefix + "noLogFileOpen!").c_str());
lineLogged(output);
}
if (foundBones) {
std::string output = timestampString + " '#####BONE ERRRORS#####" + "\n";
logFile->write(output.c_str(), output.size());
lineLogged(output);
imporantLineLogged(output);
}
}
bool serverLogger::isFiltered(const boost::string_ref & line) const {
boost::cmatch what;
return
boost::algorithm::starts_with(line, "Client: Nonnetwork object") || //Client: Nonnetwork object 79846380.
boost::algorithm::starts_with(line, "Client: Object ") || //Client: Object 4:3742 (type Type_93) not found.
boost::algorithm::starts_with(line, "Server: Object ") || //Server: Object 4:3720 not found (message Type_121)
boost::algorithm::starts_with(line, "Client: Remote object ") || //Client: Remote object 4:3753 not found
boost::algorithm::starts_with(line, "Attempt to override final function") || //Attempt to override final function
boost::algorithm::starts_with(line, "Updating base class ") || //Updating base class Turrets->, by z\ace\addons\laser\config.bin/CfgVehicles/Helicopter/Turrets/
boost::algorithm::starts_with(line, "Unsupported language") || //Unsupported language English in stringtable
boost::algorithm::starts_with(line, "Warning Message: ") || //Warning Message: No entry '.weaponLockDelay'.
boost::algorithm::starts_with(line, "Unexpected stringtable format inside") || // Unexpected stringtable format inside <Text ID="STR_EWK_M1151_GYRO"><Key>
boost::algorithm::starts_with(line, "Cannot evaluate") || // Cannot evaluate '' - no file
boost::algorithm::ends_with(line, "listed twice") || //Item STR_PLAYER listed twice
boost::algorithm::starts_with(line, "Error: Object(") || //Error: Object(3 : 10) not found - very rare error
boost::algorithm::starts_with(line, "Server error: Player without identity") || //Server error: Player without identity Kirito-Kun (id 1456133807)
boost::regex_match(line.data(), what, filterRegex) //String STR_CUP_BAF_CFGVEHICLES_FLAGCARRIERBAF0 not found
;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment