Files
panopainter/engine/log.cpp

134 lines
3.5 KiB
C++

#include "pch.h"
#include "log.h"
#include "app.h"
LogRemote LogRemote::I;
void LogRemote::start()
{
if (m_running || m_error)
return; // already running
m_running = true;
m_thread = std::thread([&] {
#ifdef _WIN32
BT_SetTerminate();
#endif
net_init();
auto session_string = net_request("/start");
m_session = atoi(session_string.c_str());
while (m_running && !m_error)
{
auto m = m_mq.Get();
auto escaped = curl_easy_escape(curl, m.c_str(), (int)m.size());
auto data = std::make_unique<char[]>(m.size() + 64);
int sz = snprintf(data.get(), m.size() + 64, "session=%d&m=%s", m_session, escaped);
curl_free(escaped);
net_request("/log", std::string(data.get(), sz));
}
net_close();
LOG("NET thread loop exit");
});
}
void LogRemote::stop()
{
m_running = false;
m_mq.UnlockGetters();
if (m_thread.joinable())
m_thread.join();
}
void LogRemote::net_init()
{
if (!(curl = curl_easy_init()))
return;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &this->readBuffer);
//curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L);
}
std::string LogRemote::net_request(std::string cmd, std::string data /*= ""*/)
{
readBuffer.clear();
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
auto url = m_url + cmd;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
res = curl_easy_perform(curl);
if (res != CURLcode::CURLE_OK)
{
LOG("NET error, closed");
m_running = false;
m_error = true;
}
return readBuffer;
}
void LogRemote::net_close()
{
if (curl)
curl_easy_cleanup(curl);
curl = nullptr;
m_running = false;
}
void LogRemote::file_init()
{
if (!m_logfile.is_open())
m_logfile.open(App::I.data_path + "/panopainter-log.txt");
}
void LogRemote::file_close()
{
if (!m_logfile.is_open())
m_logfile.close();
}
void LogRemote::log(const char* format, ...)
{
static char buffer[4096];
va_list arglist;
va_start(arglist, format);
int n = vsnprintf(buffer, sizeof(buffer), format, arglist);
va_end(arglist);
m_mq.Post(std::string(buffer, n));
if (m_logfile.is_open())
{
auto line = std::string(buffer, n) + "\n";
m_logfile.write(line.data(), line.size());
m_logfile.flush();
}
}
void LogRemote::log(const wchar_t* format, ...)
{
static wchar_t buffer[4096];
va_list arglist;
va_start(arglist, format);
int n = vswprintf(buffer, sizeof(buffer)/sizeof(wchar_t), format, arglist);
va_end(arglist);
std::wstring string_to_convert(buffer, n);
//setup converter
// using convert_type = std::codecvt_utf8<wchar_t>;
// std::wstring_convert<convert_type, wchar_t> converter;
mbstate_t st = {};
std::string converted;
converted.reserve(string_to_convert.size());
const wchar_t * wptr = string_to_convert.c_str();
std::wcsrtombs((char*)converted.data(), &wptr, converted.capacity(), &st);
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
//std::string converted_str = converter.to_bytes(string_to_convert);
m_mq.Post(std::move(converted));
if (m_logfile.is_open())
{
auto line = converted + "\n";
m_logfile.write(line.data(), line.size());
m_logfile.flush();
}
}
LogRemote::~LogRemote()
{
stop();
}