@@ -163,13 +163,15 @@ Telemetry::Telemetry(FinalizedConfiguration config,
163163 " Error occurred during HTTP request for telemetry: " ));
164164 };
165165
166+ send_telemetry (" app-started" , app_started ());
166167 schedule_tasks ();
167168}
168169
169170void Telemetry::schedule_tasks () {
170171 tasks_.emplace_back (scheduler_->schedule_recurring_event (
171- config_.heartbeat_interval ,
172- [this ]() { send_heartbeat_and_telemetry (); }));
172+ config_.heartbeat_interval , [this ]() {
173+ send_telemetry (" app-heartbeat" , heartbeat_and_telemetry ());
174+ }));
173175
174176 if (config_.report_metrics ) {
175177 tasks_.emplace_back (scheduler_->schedule_recurring_event (
@@ -183,7 +185,7 @@ Telemetry::~Telemetry() {
183185 capture_metrics ();
184186 // The app-closing message is bundled with a message containing the
185187 // final metric values.
186- send_app_closing ( );
188+ send_telemetry ( " app-closing " , app_closing () );
187189 http_client_->drain (clock_ ().tick + 1s);
188190 }
189191}
@@ -239,7 +241,7 @@ Telemetry::Telemetry(Telemetry&& rhs)
239241 metrics_snapshots_.emplace_back (*m, MetricSnapshot{});
240242 }
241243
242- cancel_tasks (rhs. tasks_ );
244+ cancel_tasks (tasks_);
243245 schedule_tasks ();
244246}
245247
@@ -302,8 +304,6 @@ Telemetry& Telemetry::operator=(Telemetry&& rhs) {
302304 return *this ;
303305}
304306
305- // TODO(@dmehala): Move `report_logs` check in the serialization once
306- // `TracerTelemetry` will be removed.
307307void Telemetry::log_error (std::string message) {
308308 if (!config_.report_logs ) return ;
309309 log (std::move (message), LogLevel::ERROR);
@@ -340,7 +340,6 @@ void Telemetry::send_telemetry(StringView request_type, std::string payload) {
340340 }
341341 };
342342
343- // TODO(@dmehala): make `clock::instance()` a singleton
344343 auto post_result = http_client_->post (
345344 telemetry_endpoint_, set_telemetry_headers, std::move (payload),
346345 telemetry_on_response_, telemetry_on_error_,
@@ -351,24 +350,24 @@ void Telemetry::send_telemetry(StringView request_type, std::string payload) {
351350 }
352351}
353352
354- void Telemetry::send_app_started (
355- const std::unordered_map<tracing::ConfigName, tracing::ConfigMetadata>&
356- config_metadata) {
357- send_telemetry (" app-started" , app_started (config_metadata));
358- }
359-
360- void Telemetry::send_app_closing () {
361- send_telemetry (" app-closing" , app_closing ());
362- }
353+ void Telemetry::send_configuration_change () {
354+ if (configuration_snapshot_.empty ()) return ;
363355
364- void Telemetry::send_heartbeat_and_telemetry () {
365- send_telemetry (" app-heartbeat" , heartbeat_and_telemetry ());
366- }
356+ std::vector<ConfigMetadata> current_configuration;
357+ std::swap (current_configuration, configuration_snapshot_);
367358
368- void Telemetry::send_configuration_change () {
369- if (auto payload = configuration_change ()) {
370- send_telemetry (" app-client-configuration-change" , *payload);
359+ auto configuration_json = nlohmann::json::array ();
360+ for (const auto & config_metadata : current_configuration) {
361+ configuration_json.emplace_back (
362+ generate_configuration_field (config_metadata));
371363 }
364+
365+ auto telemetry_body =
366+ generate_telemetry_body (" app-client-configuration-change" );
367+ telemetry_body[" payload" ] =
368+ nlohmann::json{{" configuration" , configuration_json}};
369+
370+ send_telemetry (" app-client-configuration-change" , telemetry_body.dump ());
372371}
373372
374373std::string Telemetry::heartbeat_and_telemetry () {
@@ -523,72 +522,95 @@ std::string Telemetry::app_closing() {
523522 return message_batch_payload;
524523}
525524
526- std::string Telemetry::app_started (
527- const std::unordered_map<ConfigName, ConfigMetadata>& configurations) {
525+ std::string Telemetry::app_started () {
528526 auto configuration_json = nlohmann::json::array ();
529- for (const auto & [_, config_metadata] : configurations) {
530- // if (config_metadata.value.empty()) continue;
527+ auto product_json = nlohmann::json::object ();
531528
532- configuration_json.emplace_back (
533- generate_configuration_field (config_metadata));
529+ for (const auto & product : config_.products ) {
530+ auto & configurations = product.configurations ;
531+ for (const auto & [_, config_metadata] : configurations) {
532+ // if (config_metadata.value.empty()) continue;
533+
534+ configuration_json.emplace_back (
535+ generate_configuration_field (config_metadata));
536+ }
537+
538+ // / NOTE(@dmehala): Telemetry API is tightly related to APM tracing and
539+ // / assumes telemetry event can only be generated from a tracer. The
540+ // / assumption is that the tracing product is always enabled and there
541+ // / is no need to declare it.
542+ if (product.name == Product::Name::tracing) continue ;
543+
544+ auto p = nlohmann::json{
545+ {to_string (product.name ),
546+ nlohmann::json{
547+ {" version" , product.version },
548+ {" enabled" , product.enabled },
549+ }},
550+ };
551+
552+ if (product.error_code || product.error_message ) {
553+ auto p_error = nlohmann::json{};
554+ if (product.error_code ) {
555+ p_error.emplace (" code" , *product.error_code );
556+ }
557+ if (product.error_message ) {
558+ p_error.emplace (" message" , *product.error_message );
559+ }
560+
561+ p.emplace (" error" , std::move (p_error));
562+ }
563+
564+ product_json.emplace (std::move (p));
534565 }
535566
536- // clang-format off
537567 auto app_started_msg = nlohmann::json{
538- {" request_type" , " app-started" },
539- {" payload" , nlohmann::json{
540- {" configuration" , configuration_json}
541- }}
568+ {" request_type" , " app-started" },
569+ {
570+ " payload" ,
571+ nlohmann::json{
572+ {" configuration" , configuration_json},
573+ {" products" , product_json},
574+ },
575+ },
542576 };
543577
578+ if (config_.install_id .has_value ()) {
579+ app_started_msg[" payload" ].emplace (
580+ " install_signature" , nlohmann::json{
581+ {" install_id" , *config_.install_id },
582+ {" install_type" , *config_.install_type },
583+ {" install_time" , *config_.install_time },
584+ });
585+ }
586+
544587 auto batch = generate_telemetry_body (" message-batch" );
545- batch[" payload" ] = nlohmann::json::array ({
546- std::move (app_started_msg)
547- });
548- // clang-format on
588+ batch[" payload" ] = nlohmann::json::array ({std::move (app_started_msg)});
549589
550590 if (!config_.integration_name .empty ()) {
551- // clang-format off
552591 auto integration_msg = nlohmann::json{
553- {" request_type" , " app-integrations-change" },
554- {" payload" , nlohmann::json{
555- {" integrations" , nlohmann::json::array ({
556- nlohmann::json{
557- {" name" , config_.integration_name },
558- {" version" , config_.integration_version },
559- {" enabled" , true }
560- }
561- })}
562- }}
592+ {" request_type" , " app-integrations-change" },
593+ {
594+ " payload" ,
595+ nlohmann::json{
596+ {
597+ " integrations" ,
598+ nlohmann::json::array ({
599+ nlohmann::json{{" name" , config_.integration_name },
600+ {" version" , config_.integration_version },
601+ {" enabled" , true }},
602+ }),
603+ },
604+ },
605+ },
563606 };
564- // clang-format on
565607
566608 batch[" payload" ].emplace_back (std::move (integration_msg));
567609 }
568610
569611 return batch.dump ();
570612}
571613
572- Optional<std::string> Telemetry::configuration_change () {
573- if (configuration_snapshot_.empty ()) return nullopt ;
574-
575- std::vector<ConfigMetadata> current_configuration;
576- std::swap (current_configuration, configuration_snapshot_);
577-
578- auto configuration_json = nlohmann::json::array ();
579- for (const auto & config_metadata : current_configuration) {
580- configuration_json.emplace_back (
581- generate_configuration_field (config_metadata));
582- }
583-
584- auto telemetry_body =
585- generate_telemetry_body (" app-client-configuration-change" );
586- telemetry_body[" payload" ] =
587- nlohmann::json{{" configuration" , configuration_json}};
588-
589- return telemetry_body.dump ();
590- }
591-
592614nlohmann::json Telemetry::generate_telemetry_body (std::string request_type) {
593615 std::time_t tracer_time = std::chrono::duration_cast<std::chrono::seconds>(
594616 clock_ ().wall .time_since_epoch ())
0 commit comments