Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ESP32] Platform diagnostics framework #36532

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
38a5b47
esp32 diagnostic trace
pimpalemahesh Oct 10, 2024
54a2e6e
example/temperature-measurement-app
pimpalemahesh Nov 14, 2024
167bd6a
backend: Add description for diagnosticstorage interface, remove unnc…
pimpalemahesh Nov 15, 2024
640911b
temperature_measurement_app: Review changes
pimpalemahesh Nov 19, 2024
8cc00d8
esp32_diagnostic_trace: Review changes
pimpalemahesh Nov 26, 2024
029d534
temperature_measurement_app: Review changes
pimpalemahesh Nov 19, 2024
da9e7f1
backend: map for counter diagnostics related changes
pimpalemahesh Nov 21, 2024
03f8f7a
example: Remove redundant code
pimpalemahesh Dec 11, 2024
c698573
diagnostic-buffer: clear buffer after successful bdx log transfer
pimpalemahesh Dec 23, 2024
692abf0
diagnostic-storage: Remove singltone design for storage instance
pimpalemahesh Dec 26, 2024
e0ce37a
temperature-measurement-app: use seperate buffer for retrieval of dia…
pimpalemahesh Dec 27, 2024
b238f91
temperature-measurement-app: pass diagnostic storage Instance as poin…
pimpalemahesh Jan 6, 2025
b875ddf
backend: update methods to propagate error to level up
pimpalemahesh Jan 6, 2025
542cee8
temperature-measurement-app: review changes
pimpalemahesh Jan 23, 2025
b4f2001
esp32_diagnostic_trace: review changes
pimpalemahesh Jan 24, 2025
4cc21a3
esp32_diagnostic_trace: Add clearBuffer() method, update api document…
pimpalemahesh Jan 24, 2025
e5ff131
fixed trace instant filter
pimpalemahesh Feb 11, 2025
427ae7b
esp_diagnostic_trace: add clearbuffer method to diagnostic interface
pimpalemahesh Feb 11, 2025
0916562
diagnostics: add decode method
pimpalemahesh Mar 5, 2025
b4f724e
readme update
pimpalemahesh Mar 12, 2025
52da1f9
Review changes
pimpalemahesh Mar 17, 2025
1ef047b
Modified chip log statements, make string values mutable
pimpalemahesh Mar 17, 2025
66f50db
Restyled changes
pimpalemahesh Mar 17, 2025
4236f3c
backend: copyright header change, retrieve api return value changed
pimpalemahesh Mar 19, 2025
a7fec5a
diagnosticEntry: add invalid valuetype
pimpalemahesh Mar 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions config/esp32/components/chip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE)
chip_gn_arg_append("matter_trace_config" "\"${CHIP_ROOT}/src/tracing/esp32_trace:esp32_trace_tracing\"")
endif()

if (CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE)
chip_gn_arg_bool("matter_enable_tracing_support" "true")
chip_gn_arg_append("matter_trace_config" "\"${CHIP_ROOT}/src/tracing/esp32_diagnostic_trace:esp32_diagnostic_tracing\"")
endif()

if (CONFIG_ENABLE_ESP_INSIGHTS_SYSTEM_STATS)
chip_gn_arg_append("matter_enable_esp_insights_system_stats" "true")
endif()
Expand All @@ -314,6 +319,10 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE)
target_include_directories(${COMPONENT_LIB} INTERFACE "${CHIP_ROOT}/src/tracing/esp32_trace/include")
endif()

if (CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE)
target_include_directories(${COMPONENT_LIB} INTERFACE "${CHIP_ROOT}/src/tracing/esp32_diagnostic_trace/include")
endif()

if (CONFIG_CHIP_DEVICE_ENABLE_DYNAMIC_SERVER)
chip_gn_arg_append("chip_build_controller_dynamic_server" "true")
endif()
Expand Down Expand Up @@ -379,6 +388,11 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE)
list(APPEND chip_libraries "${CMAKE_CURRENT_BINARY_DIR}/lib/libEsp32TracingBackend.a")
endif()

if (CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE)
list(APPEND chip_libraries "${CMAKE_CURRENT_BINARY_DIR}/lib/libEsp32DiagnosticsBackend.a")
endif()


# When using the pregenerated files, there is a edge case where an error appears for
# undeclared argument chip_code_pre_generated_directory. To get around with it we are
# disabling the --fail-on-unused-args flag.
Expand Down
24 changes: 15 additions & 9 deletions config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,13 @@ menu "CHIP Device Layer"
NVS namespace. If this option is enabled, the application can use an API to set a CD,
the configured CD will be used for subsequent CD reads.

config ENABLE_ESP_DIAGNOSTICS_TRACE
bool "Enable ESP Platform Diagnostics for Matter"
default n
help
Enables the ESP Diagnostics platform to collect, store, and retrieve diagnostic data for the Matter protocol.
This feature helps monitor system health and performance by providing insights through diagnostics logs.

config ENABLE_ESP_INSIGHTS_TRACE
bool "Enable Matter ESP Insights"
depends on ESP_INSIGHTS_ENABLED
Expand All @@ -876,15 +883,14 @@ menu "CHIP Device Layer"
help
This option enables the system statistics to be sent to the insights cloud.

config MAX_PERMIT_LIST_SIZE
int "Set permit list size for Insights traces"
range 5 30
depends on ESP_INSIGHTS_ENABLED
default 20
help
Maximum number of group entries that can be included in the permit list for reporting
the traces to insights.

config MAX_PERMIT_LIST_SIZE
int "Set permit list size for Insights traces"
range 5 30
depends on ESP_INSIGHTS_ENABLED || ENABLE_ESP_DIAGNOSTICS_TRACE
default 20
help
Set the maximum number of group entries that can be included in the permit list for reporting
traces to Insights or diagnostics. This ensures proper management of trace reporting capacity.
endmenu


Expand Down
15 changes: 15 additions & 0 deletions examples/temperature-measurement-app/esp32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ main/diagnostic_logs

These files contain dummy data.

#### To use diagnostic tracing

Open menuconfig

```
idf.py menuconfig
```

Enable `ENABLE_ESP_DIAGNOSTICS_TRACE` option from menuconfig

Set diagnostic storage buffer size from `Platform Diagnostics` menu

- End user buffer default size 4096
- Retrieval buffer default size 4096

#### To test the diagnostic logs cluster

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,21 @@ depends on ENABLE_PW_RPC
about available pin numbers for UART.

endmenu

menu "Platform Diagnostics"

config END_USER_BUFFER_SIZE
int "Set buffer size for end user diagnostic data"
depends on ENABLE_ESP_DIAGNOSTICS_TRACE
default 4096
help
Defines the buffer size (in bytes) for storing diagnostic data related to end user activity.
This buffer will hold logs and traces relevant to user interactions with the Matter protocol.

config RETRIEVAL_BUFFER_SIZE
int "Set buffer size for retrieval of diagnostics from diagnostic storage"
depends on ENABLE_ESP_DIAGNOSTICS_TRACE
default 4096
help
Defines the buffer size (in bytes) for retrieval of diagnostic data.
endmenu
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ using namespace chip::app::Clusters::DiagnosticLogs;
LogProvider LogProvider::sInstance;
LogProvider::CrashLogContext LogProvider::sCrashLogContext;

#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
static uint32_t sReadEntries = 0;
static uint8_t retrievalBuffer[CONFIG_RETRIEVAL_BUFFER_SIZE];
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE

namespace {
bool IsValidIntent(IntentEnum intent)
{
Expand Down Expand Up @@ -74,8 +79,16 @@ size_t LogProvider::GetSizeForIntent(IntentEnum intent)
{
switch (intent)
{
case IntentEnum::kEndUserSupport:
case IntentEnum::kEndUserSupport: {
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
VerifyOrReturnError(mStorageInstance != nullptr, 0,
ChipLogError(DeviceLayer, "Diagnostic Storage instance cannot be null."));
return mStorageInstance->GetDataSize();
#else
return static_cast<size_t>(endUserSupportLogEnd - endUserSupportLogStart);
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
}
break;
case IntentEnum::kNetworkDiag:
return static_cast<size_t>(networkDiagnosticLogEnd - networkDiagnosticLogStart);
case IntentEnum::kCrashLogs:
Expand Down Expand Up @@ -107,8 +120,24 @@ CHIP_ERROR LogProvider::PrepareLogContextForIntent(LogContext * context, IntentE
switch (intent)
{
case IntentEnum::kEndUserSupport: {
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
VerifyOrReturnError(mStorageInstance != nullptr, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Diagnostic Storage instance cannot be null."));
MutableByteSpan endUserSupportSpan(retrievalBuffer, CONFIG_RETRIEVAL_BUFFER_SIZE);
VerifyOrReturnError(!mStorageInstance->IsBufferEmpty(), CHIP_ERROR_NOT_FOUND,
ChipLogError(DeviceLayer, "Empty Diagnostic buffer"));
// Retrieve data from the diagnostic storage
CHIP_ERROR err = mStorageInstance->Retrieve(endUserSupportSpan, sReadEntries);
if (err != CHIP_NO_ERROR && err != CHIP_ERROR_BUFFER_TOO_SMALL && err != CHIP_ERROR_END_OF_TLV)
{
ChipLogError(DeviceLayer, "Failed to retrieve data: %s", ErrorStr(err));
return err;
}
context->EndUserSupport.span = endUserSupportSpan;
#else
context->EndUserSupport.span =
ByteSpan(&endUserSupportLogStart[0], static_cast<size_t>(endUserSupportLogEnd - endUserSupportLogStart));
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
}
break;

Expand Down Expand Up @@ -277,11 +306,23 @@ CHIP_ERROR LogProvider::StartLogCollection(IntentEnum intent, LogSessionHandle &

CHIP_ERROR LogProvider::EndLogCollection(LogSessionHandle sessionHandle, CHIP_ERROR error)
{
if (error != CHIP_NO_ERROR)
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
VerifyOrReturnError(mStorageInstance != nullptr, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Diagnostic Storage instance cannot be null."));
if (error == CHIP_NO_ERROR)
{
// Handle the error
ChipLogProgress(DeviceLayer, "End log collection reason: %s", ErrorStr(error));
CHIP_ERROR err = mStorageInstance->ClearBuffer(sReadEntries);
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Failed to clear diagnostic read entries");
}
else
{
ChipLogDetail(DeviceLayer, "Cleared all read diagnostics successfully");
}
}
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE

VerifyOrReturnValue(sessionHandle != kInvalidLogSessionHandle, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnValue(mSessionContextMap.count(sessionHandle), CHIP_ERROR_INVALID_ARGUMENT);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@
#pragma once

#include <app/clusters/diagnostic-logs-server/DiagnosticLogsProviderDelegate.h>

#include <map>

#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
#include <esp_core_dump.h>
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)

#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
#include <tracing/esp32_diagnostic_trace/DiagnosticStorage.h>
using namespace chip::Tracing::Diagnostics;
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE

namespace chip {
namespace app {
namespace Clusters {
Expand All @@ -49,6 +55,9 @@ class LogProvider : public DiagnosticLogsProviderDelegate
size_t GetSizeForIntent(IntentEnum intent) override;
CHIP_ERROR GetLogForIntent(IntentEnum intent, MutableByteSpan & outBuffer, Optional<uint64_t> & outTimeStamp,
Optional<uint64_t> & outTimeSinceBoot) override;
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
void SetDiagnosticStorageInstance(CircularDiagnosticBuffer * bufferInstance) { mStorageInstance = bufferInstance; }
#endif

private:
static LogProvider sInstance;
Expand All @@ -58,6 +67,11 @@ class LogProvider : public DiagnosticLogsProviderDelegate
LogProvider(const LogProvider &) = delete;
LogProvider & operator=(const LogProvider &) = delete;

#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
// If mStorageInstance is nullptr then operations related to diagnostic storage will be skipped.
CircularDiagnosticBuffer * mStorageInstance = nullptr;
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE

struct CrashLogContext
{
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
Expand Down
15 changes: 14 additions & 1 deletion examples/temperature-measurement-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
#include <DeviceInfoProviderImpl.h>
#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER

#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
#include <tracing/esp32_diagnostic_trace/DiagnosticTracing.h>
static uint8_t endUserBuffer[CONFIG_END_USER_BUFFER_SIZE]; // Global static buffer used to store diagnostics
using namespace chip::Tracing::Diagnostics;
CircularDiagnosticBuffer diagnosticStorage(endUserBuffer, CONFIG_END_USER_BUFFER_SIZE);
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE

namespace {
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
Expand All @@ -75,14 +82,17 @@ static AppDeviceCallbacks EchoCallbacks;
static void InitServer(intptr_t context)
{
Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
static ESP32Diagnostics diagnosticBackend(&diagnosticStorage);
Tracing::Register(diagnosticBackend);
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
}

extern "C" void app_main()
{
#if CONFIG_ENABLE_PW_RPC
chip::rpc::Init();
#endif

ESP_LOGI(TAG, "Temperature sensor!");

// Initialize the ESP NVS layer.
Expand Down Expand Up @@ -134,5 +144,8 @@ using namespace chip::app::Clusters::DiagnosticLogs;
void emberAfDiagnosticLogsClusterInitCallback(chip::EndpointId endpoint)
{
auto & logProvider = LogProvider::GetInstance();
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
logProvider.SetDiagnosticStorageInstance(&diagnosticStorage);
#endif
DiagnosticLogsServer::Instance().SetDiagnosticLogsProviderDelegate(endpoint, &logProvider);
}
3 changes: 3 additions & 0 deletions scripts/tools/check_includes_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@
'src/tracing/json/json_tracing.cpp': {'string', 'sstream'},
'src/tracing/json/json_tracing.h': {'fstream', 'unordered_map', 'string'},

# esp32 diagnostic tracing
'src/tracing/esp32_diagnostic_trace/Counter.h': {'map'},

# esp32 tracing
'src/tracing/esp32_trace/esp32_tracing.h': {'unordered_map'},

Expand Down
48 changes: 48 additions & 0 deletions src/tracing/esp32_diagnostic_trace/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
#Copyright (c) 2025 Project CHIP Authors
#
# 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.

import("//build_overrides/build.gni")
import("//build_overrides/chip.gni")

config("tracing") {
include_dirs = [ "include" ]
}

static_library("backend") {
output_name = "libEsp32DiagnosticsBackend"
output_dir = "${root_out_dir}/lib"

sources = [
"Counter.cpp",
"Counter.h",
"DiagnosticEntry.cpp",
"DiagnosticEntry.h",
"DiagnosticStorage.cpp",
"DiagnosticStorage.h",
"DiagnosticTracing.cpp",
"DiagnosticTracing.h",
]

public_deps = [
"${chip_root}/src/lib/core",
"${chip_root}/src/tracing",
]
}

source_set("esp32_diagnostic_tracing") {
public = [ "include/matter/tracing/macros_impl.h" ]
public_configs = [ ":tracing" ]
deps = [ ":backend" ]
}
Loading
Loading