diff --git a/CMakeLists.txt b/CMakeLists.txt
index 79d8046d9d..ddba04ef93 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -295,11 +295,18 @@ function(create_directory_groups)
     endforeach()
 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)
 get_git_head_revision(GIT_REF_SPEC GIT_REV)
 git_describe(GIT_DESC --always --long --dirty)
 git_branch_name(GIT_BRANCH)
+get_timestamp(BUILD_DATE)
 
 enable_testing()
 add_subdirectory(externals)
diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in
index 0080db5d5d..4083095d50 100644
--- a/src/common/scm_rev.cpp.in
+++ b/src/common/scm_rev.cpp.in
@@ -8,6 +8,7 @@
 #define GIT_BRANCH   "@GIT_BRANCH@"
 #define GIT_DESC     "@GIT_DESC@"
 #define BUILD_NAME   "@REPO_NAME@"
+#define BUILD_DATE   "@BUILD_DATE@"
 
 namespace Common {
 
@@ -15,6 +16,7 @@ const char g_scm_rev[]      = GIT_REV;
 const char g_scm_branch[]   = GIT_BRANCH;
 const char g_scm_desc[]     = GIT_DESC;
 const char g_build_name[]   = BUILD_NAME;
+const char g_build_date[]   = BUILD_DATE;
 
 } // namespace
 
diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h
index e223898035..18aaa1735d 100644
--- a/src/common/scm_rev.h
+++ b/src/common/scm_rev.h
@@ -10,5 +10,6 @@ extern const char g_scm_rev[];
 extern const char g_scm_branch[];
 extern const char g_scm_desc[];
 extern const char g_build_name[];
+extern const char g_build_date[];
 
 } // namespace
diff --git a/src/core/core.h b/src/core/core.h
index 4e3b6b4092..9805cc6941 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 #include "common/common_types.h"
+#include "core/loader/loader.h"
 #include "core/memory.h"
 #include "core/perf_stats.h"
 #include "core/telemetry_session.h"
@@ -14,10 +15,6 @@
 class EmuWindow;
 class ARM_Interface;
 
-namespace Loader {
-class AppLoader;
-}
-
 namespace Core {
 
 class System {
@@ -119,6 +116,10 @@ public:
         return status_details;
     }
 
+    Loader::AppLoader& GetAppLoader() const {
+        return *app_loader;
+    }
+
 private:
     /**
      * Initialize the emulated system.
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 4e6b7b6f5d..0109fa2b26 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -75,6 +75,10 @@ void Initialize(Service::Interface* self) {
 void GetSharedFont(Service::Interface* self) {
     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x44, 0, 0); // 0x00440000
     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) {
         LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds");
         rb.Push<u32>(-1); // TODO: Find the right error code
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 48bbf687dd..e731888a27 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -166,6 +166,15 @@ public:
         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:
     FileUtil::IOFile file;
     bool is_loaded = false;
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index fc4d14a595..c007069a9e 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -4,7 +4,9 @@
 
 #include <algorithm>
 #include <cinttypes>
+#include <codecvt>
 #include <cstring>
+#include <locale>
 #include <memory>
 #include "common/logging/log.h"
 #include "common/string_util.h"
@@ -420,4 +422,22 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_
     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
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h
index 0ebd47fd5c..e40cef7649 100644
--- a/src/core/loader/ncch.h
+++ b/src/core/loader/ncch.h
@@ -191,23 +191,13 @@ public:
 
     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;
 
-    /**
-     * 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,
                            u64& size) override;
 
+    ResultStatus ReadTitle(std::string& title) override;
+
 private:
     /**
      * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.)
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 841d6cfa1b..94483f3852 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -7,6 +7,7 @@
 #include "common/assert.h"
 #include "common/scm_rev.h"
 #include "common/x64/cpu_detect.h"
+#include "core/core.h"
 #include "core/settings.h"
 #include "core/telemetry_session.h"
 
@@ -39,12 +40,19 @@ TelemetrySession::TelemetrySession() {
                             std::chrono::system_clock::now().time_since_epoch())
                             .count()};
     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
     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_Branch", Common::g_scm_branch);
     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
     AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
@@ -68,6 +76,15 @@ TelemetrySession::TelemetrySession() {
              Common::GetCPUCaps().sse4_1);
     AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42",
              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
     AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching",