Merge pull request #2855 from bunnei/telemetry-additional-fields
Telemetry: Add several more useful fields
This commit is contained in:
commit
0dc285dcfd
|
@ -295,11 +295,18 @@ function(create_directory_groups)
|
||||||
endforeach()
|
endforeach()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# generate git revision information
|
# Gets a UTC timstamp and sets the provided variable to it
|
||||||
|
function(get_timestamp _var)
|
||||||
|
string(TIMESTAMP timestamp UTC)
|
||||||
|
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# generate git/build information
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||||
git_describe(GIT_DESC --always --long --dirty)
|
git_describe(GIT_DESC --always --long --dirty)
|
||||||
git_branch_name(GIT_BRANCH)
|
git_branch_name(GIT_BRANCH)
|
||||||
|
get_timestamp(BUILD_DATE)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(externals)
|
add_subdirectory(externals)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#define GIT_BRANCH "@GIT_BRANCH@"
|
#define GIT_BRANCH "@GIT_BRANCH@"
|
||||||
#define GIT_DESC "@GIT_DESC@"
|
#define GIT_DESC "@GIT_DESC@"
|
||||||
#define BUILD_NAME "@REPO_NAME@"
|
#define BUILD_NAME "@REPO_NAME@"
|
||||||
|
#define BUILD_DATE "@BUILD_DATE@"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ const char g_scm_rev[] = GIT_REV;
|
||||||
const char g_scm_branch[] = GIT_BRANCH;
|
const char g_scm_branch[] = GIT_BRANCH;
|
||||||
const char g_scm_desc[] = GIT_DESC;
|
const char g_scm_desc[] = GIT_DESC;
|
||||||
const char g_build_name[] = BUILD_NAME;
|
const char g_build_name[] = BUILD_NAME;
|
||||||
|
const char g_build_date[] = BUILD_DATE;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -10,5 +10,6 @@ extern const char g_scm_rev[];
|
||||||
extern const char g_scm_branch[];
|
extern const char g_scm_branch[];
|
||||||
extern const char g_scm_desc[];
|
extern const char g_scm_desc[];
|
||||||
extern const char g_build_name[];
|
extern const char g_build_name[];
|
||||||
|
extern const char g_build_date[];
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
|
@ -14,10 +15,6 @@
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
class ARM_Interface;
|
class ARM_Interface;
|
||||||
|
|
||||||
namespace Loader {
|
|
||||||
class AppLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
class System {
|
class System {
|
||||||
|
@ -119,6 +116,10 @@ public:
|
||||||
return status_details;
|
return status_details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader::AppLoader& GetAppLoader() const {
|
||||||
|
return *app_loader;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Initialize the emulated system.
|
* Initialize the emulated system.
|
||||||
|
|
|
@ -75,6 +75,10 @@ void Initialize(Service::Interface* self) {
|
||||||
void GetSharedFont(Service::Interface* self) {
|
void GetSharedFont(Service::Interface* self) {
|
||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x44, 0, 0); // 0x00440000
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x44, 0, 0); // 0x00440000
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||||
|
|
||||||
|
// Log in telemetry if the game uses the shared font
|
||||||
|
Core::Telemetry().AddField(Telemetry::FieldType::Session, "RequiresSharedFont", true);
|
||||||
|
|
||||||
if (!shared_font_loaded) {
|
if (!shared_font_loaded) {
|
||||||
LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds");
|
LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds");
|
||||||
rb.Push<u32>(-1); // TODO: Find the right error code
|
rb.Push<u32>(-1); // TODO: Find the right error code
|
||||||
|
|
|
@ -166,6 +166,15 @@ public:
|
||||||
return ResultStatus::ErrorNotImplemented;
|
return ResultStatus::ErrorNotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the application
|
||||||
|
* @param title Reference to store the application title into
|
||||||
|
* @return ResultStatus result of function
|
||||||
|
*/
|
||||||
|
virtual ResultStatus ReadTitle(std::string& title) {
|
||||||
|
return ResultStatus::ErrorNotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FileUtil::IOFile file;
|
FileUtil::IOFile file;
|
||||||
bool is_loaded = false;
|
bool is_loaded = false;
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
#include <codecvt>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <locale>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
@ -420,4 +422,22 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_
|
||||||
return ResultStatus::ErrorNotUsed;
|
return ResultStatus::ErrorNotUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultStatus AppLoader_NCCH::ReadTitle(std::string& title) {
|
||||||
|
std::vector<u8> data;
|
||||||
|
Loader::SMDH smdh;
|
||||||
|
ReadIcon(data);
|
||||||
|
|
||||||
|
if (!Loader::IsValidSMDH(data)) {
|
||||||
|
return ResultStatus::ErrorInvalidFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&smdh, data.data(), sizeof(Loader::SMDH));
|
||||||
|
|
||||||
|
const auto& short_title = smdh.GetShortTitle(SMDH::TitleLanguage::English);
|
||||||
|
auto title_end = std::find(short_title.begin(), short_title.end(), u'\0');
|
||||||
|
title = Common::UTF16ToUTF8(std::u16string{short_title.begin(), title_end});
|
||||||
|
|
||||||
|
return ResultStatus::Success;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Loader
|
} // namespace Loader
|
||||||
|
|
|
@ -191,23 +191,13 @@ public:
|
||||||
|
|
||||||
ResultStatus ReadLogo(std::vector<u8>& buffer) override;
|
ResultStatus ReadLogo(std::vector<u8>& buffer) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the program id of the application
|
|
||||||
* @param out_program_id Reference to store program id into
|
|
||||||
* @return ResultStatus result of function
|
|
||||||
*/
|
|
||||||
ResultStatus ReadProgramId(u64& out_program_id) override;
|
ResultStatus ReadProgramId(u64& out_program_id) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the RomFS of the application
|
|
||||||
* @param romfs_file Reference to buffer to store data
|
|
||||||
* @param offset Offset in the file to the RomFS
|
|
||||||
* @param size Size of the RomFS in bytes
|
|
||||||
* @return ResultStatus result of function
|
|
||||||
*/
|
|
||||||
ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
|
ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
|
||||||
u64& size) override;
|
u64& size) override;
|
||||||
|
|
||||||
|
ResultStatus ReadTitle(std::string& title) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.)
|
* Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
|
|
||||||
|
@ -39,12 +40,19 @@ TelemetrySession::TelemetrySession() {
|
||||||
std::chrono::system_clock::now().time_since_epoch())
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
.count()};
|
.count()};
|
||||||
AddField(Telemetry::FieldType::Session, "Init_Time", init_time);
|
AddField(Telemetry::FieldType::Session, "Init_Time", init_time);
|
||||||
|
std::string program_name;
|
||||||
|
const Loader::ResultStatus res{System::GetInstance().GetAppLoader().ReadTitle(program_name)};
|
||||||
|
if (res == Loader::ResultStatus::Success) {
|
||||||
|
AddField(Telemetry::FieldType::Session, "ProgramName", program_name);
|
||||||
|
}
|
||||||
|
|
||||||
// Log 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, "Git_IsDirty", is_git_dirty);
|
AddField(Telemetry::FieldType::App, "Git_IsDirty", is_git_dirty);
|
||||||
AddField(Telemetry::FieldType::App, "Git_Branch", Common::g_scm_branch);
|
AddField(Telemetry::FieldType::App, "Git_Branch", Common::g_scm_branch);
|
||||||
AddField(Telemetry::FieldType::App, "Git_Revision", Common::g_scm_rev);
|
AddField(Telemetry::FieldType::App, "Git_Revision", Common::g_scm_rev);
|
||||||
|
AddField(Telemetry::FieldType::App, "BuildDate", Common::g_build_date);
|
||||||
|
AddField(Telemetry::FieldType::App, "BuildName", Common::g_build_name);
|
||||||
|
|
||||||
// Log user system information
|
// Log user system information
|
||||||
AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
|
AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
|
||||||
|
@ -68,6 +76,15 @@ TelemetrySession::TelemetrySession() {
|
||||||
Common::GetCPUCaps().sse4_1);
|
Common::GetCPUCaps().sse4_1);
|
||||||
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42",
|
AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42",
|
||||||
Common::GetCPUCaps().sse4_2);
|
Common::GetCPUCaps().sse4_2);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Apple");
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Windows");
|
||||||
|
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
||||||
|
AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Linux");
|
||||||
|
#else
|
||||||
|
AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Unknown");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Log user configuration information
|
// Log user configuration information
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching",
|
AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching",
|
||||||
|
|
Loading…
Reference in a new issue