MangoHud/src/logging.cpp

173 lines
5.0 KiB
C++
Raw Normal View History

2020-06-19 14:28:55 +00:00
#include "logging.h"
#include "overlay.h"
2020-08-15 13:14:55 +00:00
#include "config.h"
2020-06-19 14:28:55 +00:00
#include <sstream>
#include <iomanip>
string os, cpu, gpu, ram, kernel, driver;
bool sysInfoFetched = false;
double fps;
2020-09-02 05:50:56 +00:00
uint64_t frametime;
logData currentLogData = {};
std::unique_ptr<Logger> logger;
2020-06-19 14:28:55 +00:00
string exec(string command) {
char buffer[128];
string result = "";
// Open pipe to file
FILE* pipe = popen(command.c_str(), "r");
if (!pipe) {
return "popen failed!";
}
// read till end of process:
while (!feof(pipe)) {
// use buffer to read and add to result
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
2020-06-24 20:03:49 +00:00
void upload_file(std::string logFile){
2020-06-19 14:28:55 +00:00
std::string command = "curl --include --request POST https://flightlessmango.com/logs -F 'log[game_id]=26506' -F 'log[user_id]=176' -F 'attachment=true' -A 'mangohud' ";
2020-06-24 20:03:49 +00:00
command += " -F 'log[uploads][]=@" + logFile + "'";
2020-06-19 14:28:55 +00:00
command += " | grep Location | cut -c11-";
std::string url = exec(command);
exec("xdg-open " + url);
}
2020-06-24 20:03:49 +00:00
void upload_files(const std::vector<std::string>& logFiles){
2020-06-19 14:28:55 +00:00
std::string command = "curl --include --request POST https://flightlessmango.com/logs -F 'log[game_id]=26506' -F 'log[user_id]=176' -F 'attachment=true' -A 'mangohud' ";
for (auto& file : logFiles)
command += " -F 'log[uploads][]=@" + file + "'";
2020-06-19 14:28:55 +00:00
command += " | grep Location | cut -c11-";
std::string url = exec(command);
exec("xdg-open " + url);
}
void writeFile(string filename){
auto& logArray = logger->get_log_data();
2020-06-24 20:03:49 +00:00
#ifndef NDEBUG
std::cerr << "Writing log file [" << filename << "], " << logArray.size() << " entries\n";
#endif
std::ofstream out(filename, ios::out | ios::app);
2020-06-19 14:28:55 +00:00
out << "os," << "cpu," << "gpu," << "ram," << "kernel," << "driver" << endl;
out << os << "," << cpu << "," << gpu << "," << ram << "," << kernel << "," << driver << endl;
2020-08-21 18:16:00 +00:00
out << "fps," << "frametime," << "cpu_load," << "gpu_load," << "cpu_temp," << "gpu_temp," << "gpu_core_clock," << "gpu_mem_clock," << "gpu_vram_used," << "ram_used," << "elapsed" << endl;
2020-06-19 14:28:55 +00:00
for (size_t i = 0; i < logArray.size(); i++){
out << logArray[i].fps << ",";
2020-08-21 18:16:00 +00:00
out << logArray[i].frametime << ",";
out << logArray[i].cpu_load << ",";
out << logArray[i].gpu_load << ",";
out << logArray[i].cpu_temp << ",";
out << logArray[i].gpu_temp << ",";
out << logArray[i].gpu_core_clock << ",";
out << logArray[i].gpu_mem_clock << ",";
out << logArray[i].gpu_vram_used << ",";
out << logArray[i].ram_used << ",";
2020-09-02 05:50:56 +00:00
out << std::chrono::duration_cast<std::chrono::nanoseconds>(logArray[i].previous).count() << "\n";
}
logger->clear_log_data();
2020-06-19 14:28:55 +00:00
}
string get_log_suffix(){
2020-06-19 14:28:55 +00:00
time_t now_log = time(0);
tm *log_time = localtime(&now_log);
std::ostringstream buffer;
buffer << std::put_time(log_time, "%Y-%m-%d_%H-%M-%S") << ".csv";
string log_name = buffer.str();
return log_name;
2020-06-19 14:28:55 +00:00
}
void logging(void *params_void){
overlay_params *params = reinterpret_cast<overlay_params *>(params_void);
logger->wait_until_data_valid();
while (logger->is_active()){
logger->try_log();
this_thread::sleep_for(chrono::milliseconds(params->log_interval));
}
}
Logger::Logger(overlay_params* in_params)
2020-06-24 20:03:49 +00:00
: m_logging_on(false),
m_values_valid(false),
m_params(in_params)
{
#ifndef NDEBUG
std::cerr << "Logger constructed!\n";
#endif
}
void Logger::start_logging() {
2020-06-24 20:03:49 +00:00
if(m_logging_on) return;
m_values_valid = false;
m_logging_on = true;
m_log_start = Clock::now();
2020-08-15 13:14:55 +00:00
if((not m_params->output_folder.empty()) and (m_params->log_interval != 0)){
2020-06-24 20:03:49 +00:00
std::thread(logging, m_params).detach();
}
}
void Logger::stop_logging() {
2020-06-24 20:03:49 +00:00
if(not m_logging_on) return;
m_logging_on = false;
m_log_end = Clock::now();
2020-08-02 06:25:04 +00:00
std::thread(calculate_benchmark_data, m_params).detach();
2020-08-15 13:14:55 +00:00
if(not m_params->output_folder.empty()) {
m_log_files.emplace_back(m_params->output_folder + "/" + program_name + "_" + get_log_suffix());
2020-06-24 20:03:49 +00:00
std::thread(writeFile, m_log_files.back()).detach();
}
}
void Logger::try_log() {
if(not is_active()) return;
2020-06-24 20:03:49 +00:00
if(not m_values_valid) return;
auto now = Clock::now();
2020-06-24 20:03:49 +00:00
auto elapsedLog = now - m_log_start;
currentLogData.previous = elapsedLog;
currentLogData.fps = fps;
2020-09-02 05:50:26 +00:00
currentLogData.frametime = frametime;
2020-06-24 20:03:49 +00:00
m_log_array.push_back(currentLogData);
2020-06-24 20:03:49 +00:00
if(m_params->log_duration and (elapsedLog >= std::chrono::seconds(m_params->log_duration))){
stop_logging();
2020-06-19 14:28:55 +00:00
}
}
2020-06-19 14:28:55 +00:00
void Logger::wait_until_data_valid() {
2020-06-24 20:03:49 +00:00
std::unique_lock<std::mutex> lck(m_values_valid_mtx);
while(! m_values_valid) m_values_valid_cv.wait(lck);
}
void Logger::notify_data_valid() {
2020-06-24 20:03:49 +00:00
std::unique_lock<std::mutex> lck(m_values_valid_mtx);
m_values_valid = true;
m_values_valid_cv.notify_all();
}
void Logger::upload_last_log() {
if(m_log_files.empty()) return;
std::thread(upload_file, m_log_files.back()).detach();
2020-08-01 23:10:21 +00:00
}
void Logger::upload_last_logs() {
if(m_log_files.empty()) return;
std::thread(upload_files, m_log_files).detach();
2020-11-27 13:17:43 +00:00
}
void autostart_log(int sleep) {
os_time_sleep(sleep * 1000000);
logger->start_logging();
}