log mission logs into separate files

This commit is contained in:
ags
2021-12-11 00:45:18 +00:00
parent b87276cfe3
commit 957dc393bd
7 changed files with 147 additions and 61 deletions

View File

@@ -1,12 +1,18 @@
# CMakeList.txt : CMake project for perun_dll, include source and define # CMakeList.txt : CMake project for perun_dll, include source and define
# project specific logic here. # project specific logic here.
# #
cmake_minimum_required (VERSION 3.8) cmake_minimum_required(VERSION 3.17)
project ("parent") project ("parent")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12.25835)
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
endif()
add_subdirectory(lua-5.1.5) add_subdirectory(lua-5.1.5)
add_subdirectory(perun) add_subdirectory(perun)
add_subdirectory(experimental)

View File

@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.17)
project(experimental)
set(CMAKE_CXX_STANDARD 20)
set (EXPERIMENTAL_SOURCES
"src/main.cpp"
)
add_executable(experimental ${EXPERIMENTAL_SOURCES})
target_link_libraries(
lua-5.1.5
ws2_32
)
target_include_directories (pierog PUBLIC)
#set_target_properties(main PROPERTIES OUTPUT_NAME "perun")

View File

@@ -28,7 +28,7 @@ set (LUA_RUNTIME_SOURCES
"src/lua.h" "src/lua.h"
"src/lualib.h" "src/lualib.h"
"src/lzio.c" "src/lzio.h" "src/lzio.c" "src/lzio.h"
) ../experimental/src/main.cpp)
add_library( lua-5.1.5 ${LUA_RUNTIME_SOURCES} ) add_library( lua-5.1.5 ${LUA_RUNTIME_SOURCES} )

View File

@@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.17) cmake_minimum_required(VERSION 3.17)
project(perun) project(pierog)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set (PERUN_DLL_SOURCES set (PIEROG_DLL_SOURCES
"src/library.h" "src/library.h"
"src/library.cpp" "src/library.cpp"
"src/Connection.h" "src/Connection.h"
@@ -11,13 +11,12 @@ set (PERUN_DLL_SOURCES
) )
include (GenerateExportHeader) include (GenerateExportHeader)
add_library(perun SHARED ${PERUN_DLL_SOURCES}) add_library(pierog SHARED ${PIEROG_DLL_SOURCES})
target_link_libraries( target_link_libraries(
perun pierog
lua-5.1.5 lua-5.1.5
ws2_32 ws2_32
) )
target_include_directories (perun PUBLIC) target_include_directories (pierog PUBLIC)
#set_target_properties(main PROPERTIES OUTPUT_NAME "perun")

View File

@@ -1,30 +1,25 @@
#include "Connection.h" #include "Connection.h"
SocketWrapper::SocketWrapper(std::string name): outputFile(name, std::ofstream::app) { #include <utility>
tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); #include <filesystem>
SocketWrapper::SocketWrapper(std::string logPath,
std::string host,
const int port): path(std::move(logPath)), tcpHost(std::move(host)), tcpPort(port){
this->tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
startNewRecording();
} }
SocketWrapper::~SocketWrapper() { SocketWrapper::~SocketWrapper() {
} }
int SocketWrapper::getAndResetReconnected() {
int result = this->flagReconnected;
this->flagReconnected = 0;
return result;
}
int SocketWrapper::getFlagConnected() {
return this->connectionState;
}
void SocketWrapper::tcpConnect() { void SocketWrapper::tcpConnect() {
// Create socket address object from TCP port and host // Create socket address object from TCP port and host
SOCKADDR_IN socketAddress; SOCKADDR_IN socketAddress;
socketAddress.sin_family = AF_INET; socketAddress.sin_family = AF_INET;
socketAddress.sin_port = htons(u_short(this->tcpPort)); socketAddress.sin_port = htons(u_short(this->tcpPort));
socketAddress.sin_addr.s_addr = *((unsigned long*)gethostbyname(this->tcpHost->c_str())->h_addr); socketAddress.sin_addr.s_addr = *((unsigned long*)gethostbyname(this->tcpHost.c_str())->h_addr);
if (connect(tcpSocket, (sockaddr*)&socketAddress, sizeof(SOCKADDR_IN)) == 0) { if (connect(tcpSocket, (sockaddr*)&socketAddress, sizeof(SOCKADDR_IN)) == 0) {
this->connectionState = CONNECTED; this->connectionState = CONNECTED;
@@ -32,33 +27,54 @@ void SocketWrapper::tcpConnect() {
} }
} }
void SocketWrapper::createConnection(std::string* host, const int* port) { void SocketWrapper::startNewRecording() {
if(outputFile != nullptr && outputFile->is_open() && outputFile->good()) {
outputFile->flush();
outputFile->close();
delete outputFile;
}
auto const now = std::chrono::system_clock::now();
auto const gmt = std::chrono::locate_zone("Etc/GMT");
auto const filename = std::format("pierog.{:%FT_%H%M%S}.log", std::chrono::zoned_time{gmt, floor<std::chrono::milliseconds>(now)});
std::filesystem::path dir(this->path);
std::filesystem::path file(filename);
auto fullPath = (dir / file).string();
outputFile = new std::ofstream(fullPath, std::ofstream::app | std::ios::out);
// clean the network buffer if nothing was ever sent
if(sentCounter > 0) {
mutexLock.lock();
dataBuffer.clear();
sendQueue.clear();
mutexLock.unlock();
}
}
void SocketWrapper::createConnection() {
// TCP connection - ConnectTo // TCP connection - ConnectTo
this->tcpHost = host;
this->tcpPort = *port;
tcpConnect(); tcpConnect();
// Create new thread
std::thread thread_object([this]() { std::thread thread_object([this]() {
// TCP sending loop
bool nothingToSend = false; bool nothingToSend = false;
while (true) { while (shouldRun) {
if (connectionState == CONNECTED && mutexLock.try_lock()) { if (connectionState == CONNECTED && mutexLock.try_lock()) {
if (sendQueue.empty()) { if (sendQueue.empty()) {
nothingToSend = true; nothingToSend = true;
} else { } else {
// Payload in queue // Payload in queue
auto payload = sendQueue.front(); auto payload = sendQueue.front();
outputFile.write(payload->c_str(), payload->length());
outputFile.flush();
int bytesSent = send(tcpSocket, payload->c_str(), payload->length(), 0); int bytesSent = send(tcpSocket, payload->c_str(), payload->length(), 0);
if (bytesSent == payload->length()) { if (bytesSent == payload->length()) {
// All payload was sent // All payload was sent
sendQueue.pop_front(); sendQueue.pop_front();
delete payload; delete payload;
sentCounter += bytesSent;
} else { } else {
// Remaining paylad // Remaining paylad
if (bytesSent > 0) { if (bytesSent > 0) {
@@ -67,6 +83,7 @@ void SocketWrapper::createConnection(std::string* host, const int* port) {
sendQueue.pop_front(); sendQueue.pop_front();
sendQueue.push_front(&shortened); sendQueue.push_front(&shortened);
delete payload; delete payload;
sentCounter += bytesSent;
} else { } else {
// Payload was not sent - handle error // Payload was not sent - handle error
switch (WSAGetLastError()) { switch (WSAGetLastError()) {
@@ -110,16 +127,38 @@ void SocketWrapper::disconnect() {
} }
void SocketWrapper::enqueueForSending(std::string* payload) { void SocketWrapper::enqueueForSending(std::string* payload) {
if(outputFile == nullptr) {
startNewRecording();
}
if(outputFile != nullptr) {
outputFile->write(payload->c_str(), payload->length());
if(payload->length() > 50) {
outputFile->flush();
}
}
if (mutexLock.try_lock()) { if (mutexLock.try_lock()) {
while (!dataBuffer.empty()) { while (!dataBuffer.empty()) {
// Shift buffer to queue // Shift buffer to queue
sendQueue.push_back(dataBuffer.front()); sendQueue.push_back(dataBuffer.front());
dataBuffer.pop(); dataBuffer.pop_front();
} }
sendQueue.push_back(payload); sendQueue.push_back(payload);
mutexLock.unlock(); mutexLock.unlock();
} }
else { else {
dataBuffer.push(payload); dataBuffer.push_back(payload);
} }
}
int SocketWrapper::getAndResetReconnected() {
int result = this->flagReconnected;
this->flagReconnected = 0;
return result;
}
int SocketWrapper::getFlagConnected() {
return this->connectionState;
} }

View File

@@ -17,32 +17,36 @@ enum enumConnectionState {
class SocketWrapper { class SocketWrapper {
public: public:
SocketWrapper(std::string name); SocketWrapper(std::string logPath,
~SocketWrapper(); std::string host,
const int port);
~SocketWrapper();
void disconnect(); void disconnect();
void createConnection(std::string* host, const int* port); void createConnection();
void startNewRecording();
void enqueueForSending(std::string* payload); void enqueueForSending(std::string* payload);
int getAndResetReconnected(); int getAndResetReconnected();
int getFlagConnected(); int getFlagConnected();
private: private:
// SocketWrapper(const SocketWrapper&);
// SocketWrapper& operator=(const SocketWrapper&);
SOCKET tcpSocket; SOCKET tcpSocket;
std::string* tcpHost; const std::string path;
int tcpPort; const std::string tcpHost = "localhost";
const int tcpPort = 0;
int flagReconnected = 0; int flagReconnected = 0;
volatile enumConnectionState connectionState = DISCONNECTED; volatile enumConnectionState connectionState = DISCONNECTED;
std::atomic<long long> sentCounter;
std::atomic<boolean> shouldRun = true;
std::queue<std::string*> dataBuffer; std::deque<std::string*> dataBuffer;
std::deque<std::string*> sendQueue; std::deque<std::string*> sendQueue;
std::mutex mutexLock; std::mutex mutexLock;
std::ofstream outputFile; std::ofstream * outputFile = nullptr;
void reconnect(); void reconnect();
void tcpConnect(); void tcpConnect();

View File

@@ -1,7 +1,13 @@
#include "library.h" #include "library.h"
#include <format>
#include <filesystem>
static SocketWrapper * tcpConnection = nullptr; static SocketWrapper * tcpConnection = nullptr;
static std::string *startingDelimiter = nullptr;
static std::string *endingDelimiter = nullptr;
static std::string lastObservedHash = std::string("");
/* this method exists for comments */ /* this method exists for comments */
static int valuesToReturn(int input) { static int valuesToReturn(int input) {
return input; return input;
@@ -10,13 +16,14 @@ static int valuesToReturn(int input) {
static int appStartHook(lua_State* luaState) { static int appStartHook(lua_State* luaState) {
// Starting the app - prepare // Starting the app - prepare
if(tcpConnection == nullptr) { if(tcpConnection == nullptr) {
auto nowMillis = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
auto millis = nowMillis.time_since_epoch().count();
char buffer[50]; int i = 1;
sprintf_s(buffer, "c:/temp/perun.%llu.log", millis); const std::string path = std::string(lua_tolstring(luaState, i++, 0));
const std::string host = std::string(lua_tolstring(luaState, i++, 0));
const int port = (int) lua_tointeger(luaState, i++);
tcpConnection = new SocketWrapper(std::string(buffer)); tcpConnection = new SocketWrapper(path, host, port);
tcpConnection->createConnection();
} }
lua_pushinteger(luaState, 1); // First return value: confirmation that app was started lua_pushinteger(luaState, 1); // First return value: confirmation that app was started
@@ -34,14 +41,20 @@ static int appEndHook(lua_State* luaState) {
return valuesToReturn(0); return valuesToReturn(0);
} }
static int tcpConnect(lua_State* luaState) { static int setDelimiters(lua_State* luaState) {
// Connect to the TCP socket startingDelimiter = new std::string(lua_tolstring(luaState, 1, 0));
endingDelimiter = new std::string(lua_tolstring(luaState, 2, 0));
if(tcpConnection != nullptr) { return valuesToReturn(0);
auto *host = new std::string(lua_tolstring(luaState, 1, 0)); }
const int *port = new int(lua_tointeger(luaState, 2));
tcpConnection->createConnection(host, port); static int markMissionStart(lua_State* luaState) {
std::string missionHash = std::string(lua_tolstring(luaState, 1, 0));
if(tcpConnection != nullptr && missionHash ==lastObservedHash) {
tcpConnection->startNewRecording();
lastObservedHash = missionHash;
} }
return valuesToReturn(0); return valuesToReturn(0);
@@ -51,7 +64,13 @@ static int tcpSend(lua_State* luaState) {
// Send frame over TCP socket // Send frame over TCP socket
if(tcpConnection != nullptr) { if(tcpConnection != nullptr) {
if(startingDelimiter != nullptr) {
tcpConnection->enqueueForSending(new std::string(*startingDelimiter));
}
tcpConnection->enqueueForSending(new std::string(lua_tolstring(luaState, 1, 0))); tcpConnection->enqueueForSending(new std::string(lua_tolstring(luaState, 1, 0)));
if(endingDelimiter != nullptr) {
tcpConnection->enqueueForSending(new std::string(*endingDelimiter));
}
lua_pushinteger(luaState, lua_pushinteger(luaState,
tcpConnection->getFlagConnected()); // First return value: information if there is TCP connection tcpConnection->getFlagConnected()); // First return value: information if there is TCP connection
@@ -65,17 +84,18 @@ static int tcpSend(lua_State* luaState) {
return valuesToReturn(2); return valuesToReturn(2);
} }
extern "C" int __declspec(dllexport) luaopen_perun(lua_State * L) { extern "C" int __declspec(dllexport) luaopen_pierog(lua_State * L) {
static const luaL_Reg Map[] = { static const luaL_Reg Map[] = {
{"StartOfApp", appStartHook}, // Called at the begining of the session {"StartOfApp", appStartHook}, // Called at the begining of the session
{"EndOfApp", appEndHook }, // Called at the end of the session out of LuaExportStop {"EndOfApp", appEndHook }, // Called at the end of the session out of LuaExportStop
{"tcpSend", tcpSend}, // Called to send data from lua over TCP {"tcpSend", tcpSend}, // Called to send data from lua over TCP
{"tcpConnect", tcpConnect}, // Create connection {"delimiters", setDelimiters },
{"markMissionStart", markMissionStart },
{ NULL, NULL } { NULL, NULL }
}; };
// Register the list of functions for lua // Register the list of functions for lua
luaL_register(L, "perun", Map); luaL_register(L, "pierog", Map);
return 1; return 1;
} }