mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-12-13 07:36:06 +08:00
Add custom metrics to defender demo (#507)
Adds custom metrics to the defender demo. The metrics added are a list of the task ids and the stack high water mark.
This commit is contained in:
@@ -35,18 +35,20 @@
|
||||
* with another MQTT library. This demo requires using the AWS IoT broker as
|
||||
* Device Defender is an AWS service.
|
||||
*
|
||||
* This demo connects to the AWS IoT broker and subscribes to the device
|
||||
* defender topics. It then collects metrics for the open ports and sockets on
|
||||
* the device using FreeRTOS+TCP, and generates a device defender report. The
|
||||
* This demo subscribes to the device defender topics. It then collects metrics
|
||||
* for the open ports and sockets on the device using FreeRTOS+TCP. Additonally
|
||||
* the stack high water mark and task IDs are collected for custom metrics.
|
||||
* These metrics are used to generate a device defender report. The
|
||||
* report is then published, and the demo waits for a response from the device
|
||||
* defender service. Upon receiving the response or timing out, the demo
|
||||
* finishes.
|
||||
* defender service. Upon receiving an accepted response, the demo finishes.
|
||||
* If the demo receives a rejected response or times out, the demo repeats up to
|
||||
* a maximum of DEFENDER_MAX_DEMO_LOOP_COUNT times.
|
||||
*
|
||||
* This demo sets the report ID to xTaskGetTickCount(), which may collide if
|
||||
* the device is reset. Reports for a Thing with a previously used report ID
|
||||
* will be assumed to be duplicates and discarded by the Device Defender
|
||||
* service. The report ID needs to be unique per report sent with a given
|
||||
* Thing. We recommend using an increasing unique id such as the current
|
||||
* Thing. We recommend using an increasing unique ID such as the current
|
||||
* timestamp.
|
||||
*/
|
||||
|
||||
@@ -97,7 +99,7 @@
|
||||
#define DEFENDER_RESPONSE_WAIT_SECONDS ( 2 )
|
||||
|
||||
/**
|
||||
* @brief Name of the report id field in the response from the AWS IoT Device
|
||||
* @brief Name of the report ID field in the response from the AWS IoT Device
|
||||
* Defender service.
|
||||
*/
|
||||
#define DEFENDER_RESPONSE_REPORT_ID_FIELD "reportId"
|
||||
@@ -133,8 +135,8 @@ typedef enum
|
||||
ReportStatusRejected
|
||||
} ReportStatus_t;
|
||||
|
||||
/**
|
||||
* @brief Each compilation unit that consumes the NetworkContext must define it.
|
||||
/**
|
||||
* @brief Each compilation unit that consumes the NetworkContext must define it.
|
||||
* It should contain a single pointer to the type of your desired transport.
|
||||
* When using multiple transports in the same compilation unit, define this pointer as void *.
|
||||
*
|
||||
@@ -195,6 +197,16 @@ static uint16_t pusOpenUdpPorts[ democonfigOPEN_UDP_PORTS_ARRAY_SIZE ];
|
||||
*/
|
||||
static Connection_t pxEstablishedConnections[ democonfigESTABLISHED_CONNECTIONS_ARRAY_SIZE ];
|
||||
|
||||
/**
|
||||
* @brief Array of task statuses, used to generate custom metrics.
|
||||
*/
|
||||
static TaskStatus_t pxTaskStatusList[ democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE ];
|
||||
|
||||
/**
|
||||
* @brief Task numbers custom metric array.
|
||||
*/
|
||||
static uint32_t pulCustomMetricsTaskNumbers[ democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE ];
|
||||
|
||||
/**
|
||||
* @brief All the metrics sent in the device defender report.
|
||||
*/
|
||||
@@ -211,9 +223,10 @@ static ReportStatus_t xReportStatus;
|
||||
static char pcDeviceMetricsJsonReport[ democonfigDEVICE_METRICS_REPORT_BUFFER_SIZE ];
|
||||
|
||||
/**
|
||||
* @brief Report Id sent in the defender report.
|
||||
* @brief Report ID sent in the defender report.
|
||||
*/
|
||||
static uint32_t ulReportId = 0UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -463,7 +476,9 @@ static bool prvCollectDeviceMetrics( void )
|
||||
{
|
||||
bool xStatus = false;
|
||||
eMetricsCollectorStatus eMetricsCollectorStatus;
|
||||
uint32_t ulNumOpenTcpPorts = 0UL, ulNumOpenUdpPorts = 0UL, ulNumEstablishedConnections = 0UL;
|
||||
uint32_t ulNumOpenTcpPorts = 0UL, ulNumOpenUdpPorts = 0UL, ulNumEstablishedConnections = 0UL, i;
|
||||
UBaseType_t uxTasksWritten = { 0 };
|
||||
TaskStatus_t pxTaskStatus = { 0 };
|
||||
|
||||
/* Collect bytes and packets sent and received. */
|
||||
eMetricsCollectorStatus = eGetNetworkStats( &( xNetworkStats ) );
|
||||
@@ -516,6 +531,36 @@ static bool prvCollectDeviceMetrics( void )
|
||||
}
|
||||
}
|
||||
|
||||
/* Collect custom metrics. This demo sends this task's stack high water mark
|
||||
* as a number type custom metric and the current task IDs as a list of
|
||||
* numbers type custom metric. */
|
||||
if( eMetricsCollectorStatus == eMetricsCollectorSuccess )
|
||||
{
|
||||
vTaskGetInfo(
|
||||
/* Query this task. */
|
||||
NULL,
|
||||
&pxTaskStatus,
|
||||
/* Include the stack high water mark value. */
|
||||
pdTRUE,
|
||||
/* Don't include the task state in the TaskStatus_t structure. */
|
||||
0 );
|
||||
uxTasksWritten = uxTaskGetSystemState( pxTaskStatusList, democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE, NULL );
|
||||
|
||||
if( uxTasksWritten == 0 )
|
||||
{
|
||||
eMetricsCollectorStatus = eMetricsCollectorCollectionFailed;
|
||||
LogError( ( "Failed to collect system state. uxTaskGetSystemState() failed due to insufficient buffer space.",
|
||||
eMetricsCollectorStatus ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < uxTasksWritten; i++ )
|
||||
{
|
||||
pulCustomMetricsTaskNumbers[ i ] = pxTaskStatusList[ i ].xTaskNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Populate device metrics. */
|
||||
if( eMetricsCollectorStatus == eMetricsCollectorSuccess )
|
||||
{
|
||||
@@ -527,6 +572,9 @@ static bool prvCollectDeviceMetrics( void )
|
||||
xDeviceMetrics.ulOpenUdpPortsArrayLength = ulNumOpenUdpPorts;
|
||||
xDeviceMetrics.pxEstablishedConnectionsArray = &( pxEstablishedConnections[ 0 ] );
|
||||
xDeviceMetrics.ulEstablishedConnectionsArrayLength = ulNumEstablishedConnections;
|
||||
xDeviceMetrics.ulStackHighWaterMark = pxTaskStatus.usStackHighWaterMark;
|
||||
xDeviceMetrics.pulTaskIdArray = pulCustomMetricsTaskNumbers;
|
||||
xDeviceMetrics.ulTaskIdArrayLength = uxTasksWritten;
|
||||
}
|
||||
|
||||
return xStatus;
|
||||
@@ -671,14 +719,14 @@ void prvDefenderDemoTask( void * pvParameters )
|
||||
* DEFENDER_MAX_DEMO_LOOP_COUNT times. */
|
||||
do
|
||||
{
|
||||
/* Set a report Id to be used.
|
||||
/* Set a report ID to be used.
|
||||
*
|
||||
* !!!NOTE!!!
|
||||
* This demo sets the report ID to xTaskGetTickCount(), which may collide
|
||||
* if the device is reset. Reports for a Thing with a previously used
|
||||
* report ID will be assumed to be duplicates and discarded by the Device
|
||||
* Defender service. The report ID needs to be unique per report sent with
|
||||
* a given Thing. We recommend using an increasing unique id such as the
|
||||
* a given Thing. We recommend using an increasing unique ID such as the
|
||||
* current timestamp. */
|
||||
ulReportId = ( uint32_t ) xTaskGetTickCount();
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 15 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
@@ -103,15 +104,6 @@
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_pcTaskGetTaskName 1
|
||||
|
||||
/* This demo makes use of one or more example stats formatting functions. These
|
||||
* format the raw data provided by the uxTaskGetSystemState() function in to human
|
||||
* readable ASCII form. See the notes in the implementation of vTaskList() within
|
||||
* FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS
|
||||
* is set to 2 so the formatting functions are included without the stdio.h being
|
||||
* included in tasks.c. That is because this project defines its own sprintf()
|
||||
* functions. */
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
|
||||
/* Assert call defined for debug builds. */
|
||||
#ifdef _DEBUG
|
||||
extern void vAssertCalled( const char * pcFile,
|
||||
|
||||
@@ -52,4 +52,44 @@
|
||||
|
||||
/************ End of logging configuration ****************/
|
||||
|
||||
/**
|
||||
* AWS IoT Device Defender Service supports both long and short names for keys
|
||||
* in the report sent by a device. For example,
|
||||
*
|
||||
* A device defender report using long key names:
|
||||
* {
|
||||
* "header": {
|
||||
* "report_id": 1530304554,
|
||||
* "version": "1.0"
|
||||
* },
|
||||
* "metrics": {
|
||||
* "network_stats": {
|
||||
* "bytes_in": 29358693495,
|
||||
* "bytes_out": 26485035,
|
||||
* "packets_in": 10013573555,
|
||||
* "packets_out": 11382615
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* An equivalent report using short key names:
|
||||
* {
|
||||
* "hed": {
|
||||
* "rid": 1530304554,
|
||||
* "v": "1.0"
|
||||
* },
|
||||
* "met": {
|
||||
* "ns": {
|
||||
* "bi": 29358693495,
|
||||
* "bo": 26485035,
|
||||
* "pi": 10013573555,
|
||||
* "po": 11382615
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* Set to 1 to enable use of long key names in the defender report.
|
||||
*/
|
||||
#define DEFENDER_USE_LONG_KEYS 0
|
||||
|
||||
#endif /* ifndef DEFENDER_CONFIG_H_ */
|
||||
|
||||
@@ -261,6 +261,13 @@ extern void vLoggingPrintf( const char * pcFormatString,
|
||||
*/
|
||||
#define democonfigESTABLISHED_CONNECTIONS_ARRAY_SIZE 10
|
||||
|
||||
/**
|
||||
* @brief Size of the task numbers array.
|
||||
*
|
||||
* This must be at least the number of tasks used.
|
||||
*/
|
||||
#define democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE 10
|
||||
|
||||
/**
|
||||
* @brief Size of the buffer which contains the generated device defender report.
|
||||
*
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "FreeRTOS_IP.h"
|
||||
|
||||
/* FreeRTOS+TCP tcp_netstat utility include. */
|
||||
#include "tcp_netstat.h"
|
||||
|
||||
/* Demo config. */
|
||||
#include "demo_config.h"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,13 @@ typedef enum
|
||||
} eReportBuilderStatus;
|
||||
|
||||
/**
|
||||
* @brief Represents metrics to be included in the report.
|
||||
* @brief Represents metrics to be included in the report, including custom metrics.
|
||||
*
|
||||
* This demo demonstrates the use of the stack high water mark and list of
|
||||
* running task ids as custom metrics sent to AWS IoT Device Defender service.
|
||||
*
|
||||
* For more information on custom metrics, refer to the following AWS document:
|
||||
* https://docs.aws.amazon.com/iot/latest/developerguide/dd-detect-custom-metrics.html
|
||||
*/
|
||||
typedef struct ReportMetrics
|
||||
{
|
||||
@@ -52,6 +58,10 @@ typedef struct ReportMetrics
|
||||
uint32_t ulOpenUdpPortsArrayLength;
|
||||
Connection_t * pxEstablishedConnectionsArray;
|
||||
uint32_t ulEstablishedConnectionsArrayLength;
|
||||
/* Custom metrics */
|
||||
uint32_t ulStackHighWaterMark;
|
||||
uint32_t * pulTaskIdArray;
|
||||
uint32_t ulTaskIdArrayLength;
|
||||
} ReportMetrics_t;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user