Skip to content

Commit

Permalink
Added the support to report the chip system statistics to the esp-ins…
Browse files Browse the repository at this point in the history
…ights.

- The system stats from src/system/SystemStats.h are reported on enabling a config option to esp-insights.
  • Loading branch information
shripad621git committed Sep 12, 2023
1 parent aed2bcd commit 20af69a
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 15 deletions.
4 changes: 4 additions & 0 deletions config/esp32/components/chip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE)
chip_gn_arg_append("matter_enable_esp_insights_trace" "true")
endif()

if (CONFIG_ENABLE_ESP_INSIGHTS_SYSTEM_STATS)
chip_gn_arg_append("matter_enable_esp_insights_system_stats" "true")
endif()

if (CONFIG_USE_ESP32_ECDSA_PERIPHERAL)
chip_gn_arg_append("chip_use_esp32_ecdsa_peripheral" "true")
endif()
Expand Down
6 changes: 6 additions & 0 deletions config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,12 @@ menu "CHIP Device Layer"
Enabling the above option will enable the esp32 specific tracing functionality and report the
diagnostic information to the insights cloud.

config ENABLE_ESP_INSIGHTS_SYSTEM_STATS
bool "Enable System Stats for insights"
depends on ESP_INSIGHTS_ENABLED
default n
help
This option enables the system statistics to be sent to the insights cloud.
endmenu


Expand Down
37 changes: 23 additions & 14 deletions examples/lighting-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <platform/ESP32/ESP32Utils.h>

#if CONFIG_ENABLE_ESP_INSIGHTS_SYSTEM_STATS
#include <matter/tracing/insights_sys_stats.h>
#endif

#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
Expand Down Expand Up @@ -113,6 +117,25 @@ static void InitServer(intptr_t context)

DeviceCallbacksDelegate::Instance().SetAppDelegate(&sAppDeviceCallbacksDelegate);
Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config

#if CONFIG_ENABLE_ESP_INSIGHTS_TRACE
esp_insights_config_t config = {
.log_type = ESP_DIAG_LOG_TYPE_ERROR | ESP_DIAG_LOG_TYPE_WARNING | ESP_DIAG_LOG_TYPE_EVENT,
.auth_key = insights_auth_key_start,
};

esp_err_t ret = esp_insights_init(&config);

if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to initialize ESP Insights, err:0x%x", ret);
}

// Setting the sampling time to 30 seconds i.e 30,000 ms
#if CONFIG_ENABLE_ESP_INSIGHTS_SYSTEM_STATS
chip::System::Stats::InsightsSystemMetrics::GetInstance().RegisterAndEnable(chip::System::Clock::Timeout(60000));
#endif
#endif
}

extern "C" void app_main()
Expand All @@ -134,20 +157,6 @@ extern "C" void app_main()
chip::rpc::Init();
#endif

#if CONFIG_ENABLE_ESP_INSIGHTS_TRACE
esp_insights_config_t config = {
.log_type = ESP_DIAG_LOG_TYPE_ERROR | ESP_DIAG_LOG_TYPE_WARNING | ESP_DIAG_LOG_TYPE_EVENT,
.auth_key = insights_auth_key_start,
};

esp_err_t ret = esp_insights_init(&config);

if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to initialize ESP Insights, err:0x%x", ret);
}
#endif

ESP_LOGI(TAG, "==================================================");
ESP_LOGI(TAG, "chip-esp32-light-example starting");
ESP_LOGI(TAG, "==================================================");
Expand Down
14 changes: 13 additions & 1 deletion src/tracing/esp32_trace/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@ import("//build_overrides/chip.gni")
config("tracing") {
include_dirs = [ "include" ]
}

declare_args() {
matter_enable_esp_insights_system_stats = false
}
source_set("esp32_trace") {
public = [ "include/matter/tracing/macros_impl.h" ]
sources = [ "include/matter/tracing/macros_impl.cpp" ]
public_configs = [ ":tracing" ]

if (matter_enable_esp_insights_system_stats) {
public += [ "include/matter/tracing/insights_sys_stats.h" ]
sources += [ "include/matter/tracing/insights_sys_stats.cpp" ]
deps = [
"${chip_root}/src/lib/core",
"${chip_root}/src/platform",
"${chip_root}/src/system",
]
}
}
164 changes: 164 additions & 0 deletions src/tracing/esp32_trace/include/matter/tracing/insights_sys_stats.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "insights_sys_stats.h"
#include <esp_diagnostics_metrics.h>
#include <esp_err.h>
#include <esp_log.h>
#include <platform/CHIPDeviceLayer.h>
#include <string.h>
#include <system/SystemStats.h>

namespace chip {
namespace System {
namespace Stats {

InsightsSystemMetrics & InsightsSystemMetrics::GetInstance()
{
static InsightsSystemMetrics instance;
return instance;
}

void InsightsSystemMetrics::StartTimerCallback(Layer * systemLayer, void * context)
{
auto instance = static_cast<InsightsSystemMetrics *>(context);
count_t * highwatermarks = GetHighWatermarks();
for (int i = 0; i < System::Stats::kNumEntries; i++)
{
esp_err_t err = esp_diag_metrics_add_uint(instance->mLabels[i], static_cast<int>(highwatermarks[i]));
if (err != ESP_OK)
{
ESP_LOGE(kTag, "Failed to add the metric:%s, err:%d", instance->mLabels[i], err);
}
}
DeviceLayer::SystemLayer().StartTimer(instance->GetTimeout(), StartTimerCallback, instance);
}

CHIP_ERROR InsightsSystemMetrics::Unregister()
{
if (!mRegistered)
{
return CHIP_ERROR_INCORRECT_STATE;
}
for (int i = 0; i < System::Stats::kNumEntries; i++)
{
if (mLabels[i] != nullptr)
{
esp_err_t err = esp_diag_metrics_unregister(mLabels[i]);
if (err != ESP_OK)
{
ESP_LOGE(kTag, "Failed to unregister metric %d", err);
}
free(mLabels[i]);
mLabels[i] = nullptr;
}
}
return CHIP_NO_ERROR;
}

void InsightsSystemMetrics::CancelTimeout(intptr_t arg)
{
auto instance = static_cast<InsightsSystemMetrics *>(reinterpret_cast<void *>(arg));
instance->_CancelTimeout();
}

void InsightsSystemMetrics::_CancelTimeout()
{
DeviceLayer::SystemLayer().CancelTimer(StartTimerCallback, this);
}

CHIP_ERROR InsightsSystemMetrics::SetTimeout(chip::System::Clock::Timeout aTimeout)
{
if (!mRegistered)
{
return CHIP_ERROR_INCORRECT_STATE;
}

if (aTimeout == System::Clock::kZero)
{
DeviceLayer::PlatformMgr().ScheduleWork(CancelTimeout, reinterpret_cast<intptr_t>(this));
}
else if (aTimeout != mTimeout)
{
DeviceLayer::PlatformMgr().ScheduleWork(CancelTimeout, reinterpret_cast<intptr_t>(this));
mTimeout = aTimeout;
CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(mTimeout, StartTimerCallback, this);
if (err != CHIP_NO_ERROR)
{
ESP_LOGE(kTag, "Failed to start the new timer %" CHIP_ERROR_FORMAT, err.Format());
return err;
}
}

return CHIP_NO_ERROR;
}

CHIP_ERROR InsightsSystemMetrics::RegisterAndEnable(chip::System::Clock::Timeout aTimeout)
{
if (mRegistered)
{
return CHIP_NO_ERROR;
}

if (aTimeout == System::Clock::kZero)
{
return CHIP_ERROR_INVALID_ARGUMENT;
}

const Label * labels = GetStrings();
for (int i = 0; i < System::Stats::kNumEntries; i++)
{
size_t labelLength = strlen(labels[i]);
if (labelLength >= kMaxStringLength)
{
labelLength = kMaxStringLength;
mLabels[i] = strndup(labels[i], labelLength - 1);
}
else
{
mLabels[i] = strndup(labels[i], labelLength);
}

if (mLabels[i] == NULL)
{
Unregister();
return CHIP_ERROR_NO_MEMORY;
}

esp_err_t err = esp_diag_metrics_register(kTag, mLabels[i], labels[i], kPath, ESP_DIAG_DATA_TYPE_UINT);
if (err != ESP_OK)
{
ESP_LOGE(kTag, "Failed to register metric:%s, err:%d", mLabels[i], err);
return CHIP_ERROR_INCORRECT_STATE;
}
}

mTimeout = System::Clock::Milliseconds32(aTimeout);

CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(GetTimeout(), StartTimerCallback, this);
if (err != CHIP_NO_ERROR)
{
ESP_LOGE(kTag, "Failed to start the timer, err:%" CHIP_ERROR_FORMAT, err.Format());
return err;
}
mRegistered = true;
return CHIP_NO_ERROR;
}

} // namespace Stats
} // namespace System
} // namespace chip
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <lib/core/CHIPError.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/SystemClock.h>
#include <system/SystemStats.h>
namespace chip {
namespace System {
namespace Stats {

class InsightsSystemMetrics
{
public:
static InsightsSystemMetrics & GetInstance();

/*
* This api registers the system metrics to the insights and starts the
* timer to enable system stats periodically to the insights.
*/
CHIP_ERROR RegisterAndEnable(chip::System::Clock::Timeout aTimeout);

/*
* This api unregisters the system stats which are registered
* as metrics to the esp-insights.
*/
CHIP_ERROR Unregister();

/*
* This api cancels the timeout providing the user the flexibility
* to increase or decrease the frequency of sampling the System
* Stats. It cancels the timer if new timeout value is zero.
* If the value of timeout differs from existing value, then
* it cancels the previous timer and starts a new timer.
*/
CHIP_ERROR SetTimeout(chip::System::Clock::Timeout aTimeout);

void _CancelTimeout();

System::Clock::Timeout GetTimeout() { return mTimeout; }

private:
InsightsSystemMetrics() {}
static constexpr int kMaxStringLength = 16;
bool mRegistered = false;
static constexpr char kPath[] = "sys.mtr";
static constexpr char kTag[] = "MTR";
System::Clock::Timeout mTimeout;
char * mLabels[chip::System::Stats::kNumEntries];

static void StartTimerCallback(System::Layer * systemLayer, void * context);
static void CancelTimeout(intptr_t arg);
};

} // namespace Stats
} // namespace System
} // namespace chip

0 comments on commit 20af69a

Please sign in to comment.