Events.cpp 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "Events.h"
  2. #include <algorithm>
  3. #include "esp_app_format.h"
  4. #include "esp_ota_ops.h"
  5. #if CONFIG_WITH_METRICS
  6. static const char* const TAG = "MetricsEvent";
  7. namespace Metrics {
  8. Event& Event::add_property(const char* name, const char* value) {
  9. ESP_LOGV(TAG, "Adding property %s:%s to event %s",name,value,_name);
  10. char* mutable_name = strdup_psram(name); // Cast away const-ness, be careful with this
  11. auto elem = properties.find(mutable_name);
  12. FREE_AND_NULL(mutable_name)
  13. if (elem == properties.end()) {
  14. ESP_LOGV(TAG, "Adding property %s:%s to event %s",name,value,_name);
  15. properties.insert({strdup_psram(name), strdup_psram(value)});
  16. } else {
  17. ESP_LOGV(TAG, "Replacing value for property %s. Old: %s New: %s, Event: %s",name,elem->second,value,name);
  18. FREE_AND_NULL(elem->second)
  19. elem->second = strdup_psram(value);
  20. }
  21. return *this;
  22. }
  23. bool Event::has_property_value(const char* name, const char* value) const {
  24. ESP_LOGV(TAG, "Checking if event %s property %s has value %s",_name, name,value);
  25. return std::any_of(properties.begin(), properties.end(),
  26. [name, value](const std::pair<const char* const, char*>& kv) {
  27. ESP_LOGV(TAG, "Found property %s=%s", name,value);
  28. return strcmp(kv.first, name) == 0 && strcmp(kv.second, value) == 0;
  29. });
  30. }
  31. void Event::remove_property(const char* name, const char* value) {
  32. auto it = properties.begin();
  33. ESP_LOGV(TAG, "Removing event %s property %s=%s",_name, name,value);
  34. while (it != properties.end()) {
  35. if (strcmp(it->first, name) == 0 && strcmp(it->second, value)) {
  36. properties.erase(it);
  37. return;
  38. }
  39. }
  40. ESP_LOGV(TAG, "Property %s=%s not found.", name,value);
  41. }
  42. cJSON* Event::properties_to_json() {
  43. ESP_LOGV(TAG, "Event %s properties to json.",_name);
  44. const esp_app_desc_t* desc = esp_ota_get_app_description();
  45. #ifdef CONFIG_FW_PLATFORM_NAME
  46. const char* platform = CONFIG_FW_PLATFORM_NAME;
  47. #else
  48. const char* platform = desc->project_name;
  49. #endif
  50. cJSON* prop_json = cJSON_CreateObject();
  51. auto it = properties.begin();
  52. while (it != properties.end()) {
  53. cJSON_AddStringToObject(prop_json, it->first, it->second);
  54. ++it;
  55. }
  56. cJSON_AddStringToObject(prop_json, "platform", platform);
  57. cJSON_AddStringToObject(prop_json, "build", desc->version);
  58. dump_json_content("User properties for event:", prop_json, ESP_LOG_VERBOSE);
  59. return prop_json;
  60. }
  61. cJSON* Event::to_json(const char* distinct_id) {
  62. // The target structure looks like this
  63. // {
  64. // "event": "batched_event_name_1",
  65. // "properties": {
  66. // "distinct_id": "user distinct id",
  67. // "account_type": "pro"
  68. // },
  69. // "timestamp": "[optional timestamp in ISO 8601 format]"
  70. // }
  71. ESP_LOGV(TAG,"Event %s to json",_name);
  72. free_json();
  73. _json = cJSON_CreateObject();
  74. cJSON_AddStringToObject(_json, "name", _name);
  75. cJSON_AddItemToObject(_json, "properties", properties_to_json());
  76. char buf[26] = {};
  77. strftime(buf, sizeof(buf), "%FT%TZ", gmtime(&_time));
  78. // this will work too, if your compiler doesn't support %F or %T:
  79. // strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
  80. cJSON_AddStringToObject(_json, "timestamp", buf);
  81. cJSON* prop_json = properties_to_json();
  82. cJSON_AddStringToObject(prop_json, "distinct_id", distinct_id);
  83. dump_json_content("Full Event:", _json, ESP_LOG_VERBOSE);
  84. return _json;
  85. }
  86. void Event::free_json() { cJSON_Delete(_json); }
  87. void Event::update_time() {
  88. if (_time == 0) {
  89. _time = time(nullptr);
  90. }
  91. }
  92. } // namespace Metrics
  93. #endif