@ -2,93 +2,113 @@
// 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 <json.hpp>
# include "common/detached_tasks.h"
# include "common/detached_tasks.h"
# include "web_service/telemetry_json.h"
# include "web_service/telemetry_json.h"
# include "web_service/web_backend.h"
# include "web_service/web_backend.h"
namespace WebService {
namespace WebService {
struct TelemetryJson : : Impl {
Impl ( std : : string host , std : : string username , std : : string token )
: host { std : : move ( host ) } , username { std : : move ( username ) } , token { std : : move ( token ) } { }
nlohmann : : json & TopSection ( ) {
return sections [ static_cast < u8 > ( Telemetry : : FieldType : : None ) ] ;
}
const nlohmann : : json & TopSection ( ) const {
return sections [ static_cast < u8 > ( Telemetry : : FieldType : : None ) ] ;
}
template < class T >
void Serialize ( Telemetry : : FieldType type , const std : : string & name , T value ) {
sections [ static_cast < u8 > ( type ) ] [ name ] = value ;
}
void SerializeSection ( Telemetry : : FieldType type , const std : : string & name ) {
TopSection ( ) [ name ] = sections [ static_cast < unsigned > ( type ) ] ;
}
nlohmann : : json output ;
std : : array < nlohmann : : json , 7 > sections ;
std : : string host ;
std : : string username ;
std : : string token ;
} ;
TelemetryJson : : TelemetryJson ( std : : string host , std : : string username , std : : string token )
TelemetryJson : : TelemetryJson ( std : : string host , std : : string username , std : : string token )
: host ( std : : move ( host ) ) , username ( std : : move ( username ) ) , token ( std : : move ( token ) ) { }
: impl{ std : : make_unique < Impl > ( std : : move ( host ) , std: : move ( username ) , std: : move ( token ) ) } { }
TelemetryJson : : ~ TelemetryJson ( ) = default ;
TelemetryJson : : ~ TelemetryJson ( ) = default ;
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 ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < bool > & field ) {
Serialize ( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl - > Serialize ( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < double > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < double > & field ) {
Serialize ( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl - > Serialize ( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < float > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < float > & field ) {
Serialize ( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < u8 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < u8 > & field ) {
Serialize ( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < u16 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < u16 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < u32 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < u32 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < u64 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < u64 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < s8 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < s8 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < s16 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < s16 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < s32 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < s32 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < s64 > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < s64 > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < std : : string > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < std : : string > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < const char * > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < const char * > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , std : : string ( field . GetValue ( ) ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , std : : string ( field . GetValue ( ) ) ) ;
}
}
void TelemetryJson : : Visit ( const Telemetry : : Field < std : : chrono : : microseconds > & field ) {
void TelemetryJson : : Visit ( const Telemetry : : Field < std : : chrono : : microseconds > & field ) {
Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) . count ( ) ) ;
impl- > Serialize( field . GetType ( ) , field . GetName ( ) , field . GetValue ( ) . count ( ) ) ;
}
}
void TelemetryJson : : Complete ( ) {
void TelemetryJson : : Complete ( ) {
SerializeSection( Telemetry : : FieldType : : App , " App " ) ;
impl- > SerializeSection( Telemetry : : FieldType : : App , " App " ) ;
SerializeSection( Telemetry : : FieldType : : Session , " Session " ) ;
impl- > SerializeSection( Telemetry : : FieldType : : Session , " Session " ) ;
SerializeSection( Telemetry : : FieldType : : Performance , " Performance " ) ;
impl- > SerializeSection( Telemetry : : FieldType : : Performance , " Performance " ) ;
SerializeSection( Telemetry : : FieldType : : UserFeedback , " UserFeedback " ) ;
impl- > SerializeSection( Telemetry : : FieldType : : UserFeedback , " UserFeedback " ) ;
SerializeSection( Telemetry : : FieldType : : UserConfig , " UserConfig " ) ;
impl- > SerializeSection( Telemetry : : FieldType : : UserConfig , " UserConfig " ) ;
SerializeSection( Telemetry : : FieldType : : UserSystem , " UserSystem " ) ;
impl- > SerializeSection( Telemetry : : FieldType : : UserSystem , " UserSystem " ) ;
auto content = TopSection( ) . dump ( ) ;
auto content = impl- > TopSection( ) . dump ( ) ;
// Send the telemetry async but don't handle the errors since they were written to the log
// Send the telemetry async but don't handle the errors since they were written to the log
Common : : DetachedTasks : : AddTask (
Common : : DetachedTasks : : AddTask (
[ host { this - > host } , username { this - > username } , token { this - > token } , content ] ( ) {
[ host { impl - > host } , username { impl - > username } , token { impl - > token } , content ] ( ) {
Client { host , username , token } . PostJson ( " /telemetry " , content , true ) ;
Client { host , username , token } . PostJson ( " /telemetry " , content , true ) ;
} ) ;
} ) ;
}
}