Files
FEX-Emu--FEX/External/FEXCore/Source/Utils/Telemetry.cpp
T
Ryan Houdek c6c94570b4 Implements support for offline *only* telemetry
This information is only ever going to be offline. Will be useful for multiple reasons.

1) Searching for split lock usage in applications, which can be a programming bug.
  a) This isn't visible on AMD systems and on Intel is a fairly new linux feature
2) Having more information about when an application breaks.
3) Useful for some minor profiling for devs looking for statistical data
2021-08-06 22:40:19 -07:00

62 lines
1.9 KiB
C++

#include "Common/Paths.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Utils/Telemetry.h>
#include <array>
#include <filesystem>
#include <fstream>
namespace FEXCore::Telemetry {
#ifndef FEX_DISABLE_TELEMETRY
static std::array<Value, FEXCore::Telemetry::TelemetryType::TYPE_LAST> TelemetryValues = {{ }};
const std::array<std::string, FEXCore::Telemetry::TelemetryType::TYPE_LAST> TelemetryNames {
"64byte Split Locks",
"16Byte Split atomics",
"VEX instructions (AVX)",
"EVEX instructions (AVX512)",
};
void Initialize() {
auto DataDirectory = Config::GetDataDirectory();
DataDirectory += "Telemetry/";
// Ensure the folder structure is created for our configuration
std::error_code ec{};
if (!std::filesystem::exists(DataDirectory, ec) &&
!std::filesystem::create_directories(DataDirectory, ec)) {
LogMan::Msg::I("Couldn't create telemetry Folder");
}
}
void Shutdown(std::filesystem::path &ApplicationName) {
auto DataDirectory = Config::GetDataDirectory();
DataDirectory += "Telemetry/" + ApplicationName.string() + ".telem";
std::error_code ec{};
if (std::filesystem::exists(DataDirectory, ec)) {
// If the file exists, retain a single backup
auto Backup = DataDirectory + ".1";
std::filesystem::copy_file(DataDirectory, Backup, std::filesystem::copy_options::overwrite_existing, ec);
}
std::fstream fs(DataDirectory, std::ios_base::out | std::ios_base::trunc);
if (fs.is_open()) {
for (size_t i = 0; i < TelemetryType::TYPE_LAST; ++i) {
auto &Name = TelemetryNames.at(i);
auto &Data = TelemetryValues.at(i);
fs << Name << ": " << *Data << std::endl;
}
fs.flush();
fs.close();
}
}
Value &GetObject(TelemetryType Type) {
return TelemetryValues.at(Type);
}
#endif
}