web_service: Implement JSON serialization of telemetry data.
This commit is contained in:
		| @@ -2,8 +2,88 @@ | |||||||
| // Licensed under GPLv2 or any later version | // Licensed under GPLv2 or any later version | ||||||
| // Refer to the license.txt file included. | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
|  | #include "common/assert.h" | ||||||
|  | #include "core/settings.h" | ||||||
| #include "web_service/telemetry_json.h" | #include "web_service/telemetry_json.h" | ||||||
|  | #include "web_service/web_backend.h" | ||||||
|  |  | ||||||
| namespace WebService { | namespace WebService { | ||||||
|  |  | ||||||
|  | TelemetryJson::TelemetryJson() {} | ||||||
|  |  | ||||||
|  | template <class T> | ||||||
|  | void TelemetryJson::Serialize(Telemetry::FieldType type, const std::string& name, T value) { | ||||||
|  |     sections[static_cast<u8>(type)][name] = value; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::SerializeSection(Telemetry::FieldType type, const std::string& name) { | ||||||
|  |     TopSection()[name] = sections[static_cast<unsigned>(type)]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<bool>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<double>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<float>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<u8>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<u16>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<u32>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<u64>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<s8>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<s16>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<s32>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<s64>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<std::string>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<const char*>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), std::string(field.GetValue())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Visit(const Telemetry::Field<std::chrono::microseconds>& field) { | ||||||
|  |     Serialize(field.GetType(), field.GetName(), field.GetValue().count()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void TelemetryJson::Complete() { | ||||||
|  |     SerializeSection(Telemetry::FieldType::App, "App"); | ||||||
|  |     SerializeSection(Telemetry::FieldType::Session, "Session"); | ||||||
|  |     SerializeSection(Telemetry::FieldType::Performance, "Performance"); | ||||||
|  |     SerializeSection(Telemetry::FieldType::UserFeedback, "UserFeedback"); | ||||||
|  |     SerializeSection(Telemetry::FieldType::UserConfig, "UserConfig"); | ||||||
|  |     SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem"); | ||||||
|  |     PostJson(Settings::values.telemetry_endpoint_url, TopSection().dump()); | ||||||
|  | } | ||||||
|  |  | ||||||
| } // namespace WebService | } // namespace WebService | ||||||
|   | |||||||
| @@ -4,6 +4,51 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  | #include <string> | ||||||
|  | #include <json.hpp> | ||||||
|  | #include "common/telemetry.h" | ||||||
|  |  | ||||||
| namespace WebService { | namespace WebService { | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Implementation of VisitorInterface that serialized telemetry into JSON, and submits it to the | ||||||
|  |  * Citra web service | ||||||
|  |  */ | ||||||
|  | class TelemetryJson : public Telemetry::VisitorInterface { | ||||||
|  | public: | ||||||
|  |     TelemetryJson(); | ||||||
|  |     ~TelemetryJson() = default; | ||||||
|  |  | ||||||
|  |     void Visit(const Telemetry::Field<bool>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<double>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<float>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<u8>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<u16>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<u32>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<u64>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<s8>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<s16>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<s32>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<s64>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<std::string>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<const char*>& field) override; | ||||||
|  |     void Visit(const Telemetry::Field<std::chrono::microseconds>& field) override; | ||||||
|  |  | ||||||
|  |     void Complete() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     nlohmann::json& TopSection() { | ||||||
|  |         return sections[static_cast<u8>(Telemetry::FieldType::None)]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     template <class T> | ||||||
|  |     void Serialize(Telemetry::FieldType type, const std::string& name, T value); | ||||||
|  |  | ||||||
|  |     void SerializeSection(Telemetry::FieldType type, const std::string& name); | ||||||
|  |  | ||||||
|  |     nlohmann::json output; | ||||||
|  |     std::array<nlohmann::json, 7> sections; | ||||||
|  | }; | ||||||
|  |  | ||||||
| } // namespace WebService | } // namespace WebService | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user