135 lines
3.7 KiB
C++
135 lines
3.7 KiB
C++
#include "pch.h"
|
|
#include "log.h"
|
|
#include "app.h"
|
|
|
|
LogRemote LogRemote::I;
|
|
|
|
static size_t data_handler(void *contents, size_t size, size_t nmemb, void *userp)
|
|
{
|
|
auto buffer = reinterpret_cast<std::string*>(userp);
|
|
buffer->append((char*)contents, size * nmemb);
|
|
return size * nmemb;
|
|
}
|
|
|
|
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::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, 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()
|
|
{
|
|
m_running = false;
|
|
m_mq.UnlockGetters();
|
|
if (m_thread.joinable())
|
|
m_thread.join();
|
|
}
|