123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
- #include "Batch.h"
- #include "esp_event.h"
- #include "esp_http_client.h"
- #include "esp_log.h"
- #include "esp_netif.h"
- #include "esp_ota_ops.h"
- #include "esp_tls.h"
- #include "nvs_flash.h"
- #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
- #include "esp_crt_bundle.h"
- #endif
- #include "esp_system.h"
- #include "http_handlers.h"
- #include "nvs.h"
- #include "nvs_flash.h"
- #include "nvs_utilities.h"
- #include "tools.h"
- #include <algorithm>
- #include <iomanip>
- #include <sstream>
- #include <string>
- #include <sys/param.h>
- #if CONFIG_WITH_METRICS
- static const char* const TAG = "MetricsBatch";
- static const char* const feature_evt_name = "$feature_flag_called";
- static const char* const feature_flag_name = "$feature_flag";
- static const char* const feature_flag_response_name = "$feature_flag_response";
- namespace Metrics {
- Event& Batch::add_feature_event() { return add_event(feature_evt_name); }
- void Batch::add_remove_feature_event(const char* name, bool active) {
- if (!active) {
- remove_feature_event(name);
- } else {
- add_event(feature_evt_name).add_property(feature_flag_name, name);
- }
- }
- Event& Batch::add_feature_variant_event(const char* const name, const char* const value) {
- return add_event(feature_evt_name)
- .add_property(feature_flag_name, name)
- .add_property(feature_flag_response_name, value);
- }
- void Batch::remove_feature_event(const char* name) {
- for (Metrics::Event& e : _events) {
- if (strcmp(e.get_name(), feature_evt_name) == 0) {
- e.remove_property(feature_flag_name, name);
- return;
- }
- }
- }
- cJSON* Batch::to_json() {
- cJSON* batch_json = cJSON_CreateArray();
- for (Metrics::Event& e : _events) {
- cJSON_AddItemToArray(batch_json, e.to_json(_metrics_uid.c_str()));
- }
- cJSON* message = cJSON_CreateObject();
- cJSON_AddItemToObject(message, "batch", batch_json);
- cJSON_AddStringToObject(message, "api_key", _api_key);
- return batch_json;
- }
- char* Batch::to_json_str() {
- cJSON* json = to_json();
- char* json_str = cJSON_PrintUnformatted(json);
- cJSON_Delete(json);
- return json_str;
- }
- void Batch::push() {
- int status_code = 0;
- if (_metrics_uid.empty() && !_warned) {
- ESP_LOGW(TAG, "Metrics disabled; no CID found");
- _warned = true;
- return;
- }
- char* json_str = to_json_str();
- ESP_LOGV(TAG, "Metrics payload: %s", json_str);
- uint32_t start_time = gettime_ms();
- status_code = metrics_http_post_request(json_str, _url);
- if (status_code == 200 || status_code == 204) {
- _events.clear();
- }
- FREE_AND_NULL(json_str)
- ESP_LOGD(TAG, "Total duration for metrics call: %lu. ", gettime_ms() - start_time);
- }
- void Batch::build_guid() {
- uint8_t raw[16];
- std::ostringstream oss;
- esp_fill_random(raw, 16);
- std::for_each(std::begin(raw), std::end(raw), [&oss](const uint8_t& byte) {
- oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
- });
- _metrics_uid = oss.str();
- }
- void Batch::assign_id() {
- size_t size = 0;
- esp_err_t esp_err = ESP_OK;
- _metrics_uid = std::string((char*)get_nvs_value_alloc_for_partition(
- NVS_DEFAULT_PART_NAME, TAG, NVS_TYPE_BLOB, "cid", &size));
- if (_metrics_uid[0] == 'G') {
- ESP_LOGW(TAG, "Invalid ID. %s", _metrics_uid.c_str());
- _metrics_uid.clear();
- }
- if (_metrics_uid.empty()) {
- build_guid();
- if (_metrics_uid.empty()) {
- ESP_LOGE(TAG, "ID Failed");
- return;
- }
- ESP_LOGW(TAG, "Metrics ID: %s", _metrics_uid.c_str());
- esp_err = store_nvs_value_len_for_partition(NVS_DEFAULT_PART_NAME, TAG, NVS_TYPE_BLOB,
- "cid", _metrics_uid.c_str(), _metrics_uid.length() + 1);
- if (esp_err != ESP_OK) {
- ESP_LOGE(TAG, "Store ID failed: %s", esp_err_to_name(esp_err));
- }
- }
- }
- } // namespace Metrics
- #endif
|