Merge pull request #2823 from bunnei/telemetry-data

telemetry: Log performance, configuration, and system data.
master
bunnei 2017-07-18 08:04:49 +07:00 committed by GitHub
commit 35eee446c7
5 changed files with 96 additions and 18 deletions

@ -168,6 +168,16 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
} }
void System::Shutdown() { void System::Shutdown() {
// Log last frame performance stats
auto perf_results = GetAndResetPerfStats();
Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
perf_results.emulation_speed * 100.0);
Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_Framerate",
perf_results.game_fps);
Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_Frametime",
perf_results.frametime * 1000.0);
// Shutdown emulation session
GDBStub::Shutdown(); GDBStub::Shutdown();
AudioCore::Shutdown(); AudioCore::Shutdown();
VideoCore::Shutdown(); VideoCore::Shutdown();

@ -342,9 +342,11 @@ ResultStatus AppLoader_NCCH::Load() {
if (result != ResultStatus::Success) if (result != ResultStatus::Success)
return result; return result;
LOG_INFO(Loader, "Program ID: %016" PRIX64, ncch_header.program_id); std::string program_id{Common::StringFromFormat("%016" PRIX64, ncch_header.program_id)};
Core::Telemetry().AddField(Telemetry::FieldType::Session, "ProgramId", ncch_header.program_id); LOG_INFO(Loader, "Program ID: %s", program_id.c_str());
Core::Telemetry().AddField(Telemetry::FieldType::Session, "ProgramId", program_id);
is_loaded = true; // Set state to loaded is_loaded = true; // Set state to loaded

@ -4,7 +4,10 @@
#include <cstring> #include <cstring>
#include "common/assert.h"
#include "common/scm_rev.h" #include "common/scm_rev.h"
#include "common/x64/cpu_detect.h"
#include "core/settings.h"
#include "core/telemetry_session.h" #include "core/telemetry_session.h"
#ifdef ENABLE_WEB_SERVICE #ifdef ENABLE_WEB_SERVICE
@ -13,6 +16,18 @@
namespace Core { namespace Core {
static const char* CpuVendorToStr(Common::CPUVendor vendor) {
switch (vendor) {
case Common::CPUVendor::INTEL:
return "Intel";
case Common::CPUVendor::AMD:
return "Amd";
case Common::CPUVendor::OTHER:
return "Other";
}
UNREACHABLE();
}
TelemetrySession::TelemetrySession() { TelemetrySession::TelemetrySession() {
#ifdef ENABLE_WEB_SERVICE #ifdef ENABLE_WEB_SERVICE
backend = std::make_unique<WebService::TelemetryJson>(); backend = std::make_unique<WebService::TelemetryJson>();
@ -20,22 +35,63 @@ TelemetrySession::TelemetrySession() {
backend = std::make_unique<Telemetry::NullVisitor>(); backend = std::make_unique<Telemetry::NullVisitor>();
#endif #endif
// Log one-time session start information // Log one-time session start information
const auto duration{std::chrono::steady_clock::now().time_since_epoch()}; const s64 init_time{std::chrono::duration_cast<std::chrono::milliseconds>(
const auto start_time{std::chrono::duration_cast<std::chrono::microseconds>(duration).count()}; std::chrono::system_clock::now().time_since_epoch())
AddField(Telemetry::FieldType::Session, "StartTime", start_time); .count()};
AddField(Telemetry::FieldType::Session, "Init_Time", init_time);
// Log one-time application information // Log application information
const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr};
AddField(Telemetry::FieldType::App, "GitIsDirty", is_git_dirty); AddField(Telemetry::FieldType::App, "Git_IsDirty", is_git_dirty);
AddField(Telemetry::FieldType::App, "GitBranch", Common::g_scm_branch); AddField(Telemetry::FieldType::App, "Git_Branch", Common::g_scm_branch);
AddField(Telemetry::FieldType::App, "GitRevision", Common::g_scm_rev); AddField(Telemetry::FieldType::App, "Git_Revision", Common::g_scm_rev);
// Log user system information
AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
AddField(Telemetry::FieldType::UserSystem, "CPU_BrandString",
Common::GetCPUCaps().brand_string);
AddField(Telemetry::FieldType::UserSystem, "CPU_Vendor",
CpuVendorToStr(Common::GetCPUCaps().vendor));
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_BMI1", Common::GetCPUCaps().bmi1);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_BMI2", Common::GetCPUCaps().bmi2);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_FMA", Common::GetCPUCaps().fma);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_FMA4", Common::GetCPUCaps().fma4);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE", Common::GetCPUCaps().sse);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE2", Common::GetCPUCaps().sse2);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE3", Common::GetCPUCaps().sse3);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSSE3",
Common::GetCPUCaps().ssse3);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE41",
Common::GetCPUCaps().sse4_1);
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42",
Common::GetCPUCaps().sse4_2);
// Log user configuration information
AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching",
Settings::values.enable_audio_stretching);
AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit);
AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",
Settings::values.resolution_factor);
AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit",
Settings::values.toggle_framelimit);
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer",
Settings::values.use_hw_renderer);
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseShaderJit",
Settings::values.use_shader_jit);
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseVsync", Settings::values.use_vsync);
AddField(Telemetry::FieldType::UserConfig, "System_IsNew3ds", Settings::values.is_new_3ds);
AddField(Telemetry::FieldType::UserConfig, "System_RegionValue", Settings::values.region_value);
} }
TelemetrySession::~TelemetrySession() { TelemetrySession::~TelemetrySession() {
// Log one-time session end information // Log one-time session end information
const auto duration{std::chrono::steady_clock::now().time_since_epoch()}; const s64 shutdown_time{std::chrono::duration_cast<std::chrono::milliseconds>(
const auto end_time{std::chrono::duration_cast<std::chrono::microseconds>(duration).count()}; std::chrono::system_clock::now().time_since_epoch())
AddField(Telemetry::FieldType::Session, "EndTime", end_time); .count()};
AddField(Telemetry::FieldType::Session, "Shutdown_Time", shutdown_time);
// Complete the session, submitting to web service if necessary // Complete the session, submitting to web service if necessary
// This is just a placeholder to wrap up the session once the core completes and this is // This is just a placeholder to wrap up the session once the core completes and this is

@ -12,6 +12,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h"
#include "video_core/regs_framebuffer.h" #include "video_core/regs_framebuffer.h"
#include "video_core/regs_lighting.h" #include "video_core/regs_lighting.h"
#include "video_core/regs_texturing.h" #include "video_core/regs_texturing.h"
@ -72,9 +73,9 @@ inline GLenum WrapMode(Pica::TexturingRegs::TextureConfig::WrapMode mode) {
} }
if (static_cast<u32>(mode) > 3) { if (static_cast<u32>(mode) > 3) {
// It is still unclear whether mode 4-7 are valid, so log it if a game uses them. Core::Telemetry().AddField(Telemetry::FieldType::Session,
// TODO(wwylele): telemetry should be added here so we can collect more info about which "VideoCore_Pica_UnsupportedTextureWrapMode",
// game uses this. static_cast<u32>(mode));
LOG_WARNING(Render_OpenGL, "Using texture wrap mode %u", static_cast<u32>(mode)); LOG_WARNING(Render_OpenGL, "Using texture wrap mode %u", static_cast<u32>(mode));
} }

@ -481,9 +481,18 @@ bool RendererOpenGL::Init() {
glDebugMessageCallback(DebugHandler, nullptr); glDebugMessageCallback(DebugHandler, nullptr);
} }
LOG_INFO(Render_OpenGL, "GL_VERSION: %s", glGetString(GL_VERSION)); const char* gl_version{reinterpret_cast<char const*>(glGetString(GL_VERSION))};
LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", glGetString(GL_VENDOR)); const char* gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))};
LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER)); const char* gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))};
LOG_INFO(Render_OpenGL, "GL_VERSION: %s", gl_version);
LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", gpu_vendor);
LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", gpu_model);
Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor);
Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model);
Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_OpenGL_Version", gl_version);
if (!GLAD_GL_VERSION_3_3) { if (!GLAD_GL_VERSION_3_3) {
return false; return false;
} }