Feature: add heap details to system info and prometheus (#595)
this change adds the values of ESP.gteMaxAllocHeap() and ESP.getMinFreeHead() to the prometheus metrics and the system information object. the web UI uses these values to diplay the size of the largest free contiguous block, calculate a rough estimate for the level of fragmentation, and the maximum usage of heap memory since boot in absolute and relative amounts.
This commit is contained in:
parent
3c8b8d4427
commit
377406f10c
@ -54,6 +54,14 @@ void WebApiPrometheusClass::onPrometheusMetricsGet(AsyncWebServerRequest* reques
|
||||
stream->print("# TYPE opendtu_free_heap_size gauge\n");
|
||||
stream->printf("opendtu_free_heap_size %zu\n", ESP.getFreeHeap());
|
||||
|
||||
stream->print("# HELP opendtu_biggest_heap_block Biggest free heap block\n");
|
||||
stream->print("# TYPE opendtu_biggest_heap_block gauge\n");
|
||||
stream->printf("opendtu_biggest_heap_block %zu\n", ESP.getMaxAllocHeap());
|
||||
|
||||
stream->print("# HELP opendtu_heap_min_free Minimum free memory since boot\n");
|
||||
stream->print("# TYPE opendtu_heap_min_free gauge\n");
|
||||
stream->printf("opendtu_heap_min_free %zu\n", ESP.getMinFreeHeap());
|
||||
|
||||
stream->print("# HELP wifi_rssi WiFi RSSI\n");
|
||||
stream->print("# TYPE wifi_rssi gauge\n");
|
||||
stream->printf("wifi_rssi %d\n", WiFi.RSSI());
|
||||
|
||||
@ -49,6 +49,8 @@ void WebApiSysstatusClass::onSystemStatus(AsyncWebServerRequest* request)
|
||||
|
||||
root["heap_total"] = ESP.getHeapSize();
|
||||
root["heap_used"] = ESP.getHeapSize() - ESP.getFreeHeap();
|
||||
root["heap_max_block"] = ESP.getMaxAllocHeap();
|
||||
root["heap_min_free"] = ESP.getMinFreeHeap();
|
||||
root["sketch_total"] = ESP.getFreeSketchSpace();
|
||||
root["sketch_used"] = ESP.getSketchSize();
|
||||
root["littlefs_total"] = LittleFS.totalBytes();
|
||||
|
||||
55
webapp/src/components/HeapDetails.vue
Normal file
55
webapp/src/components/HeapDetails.vue
Normal file
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<CardElement :text="$t('heapdetails.HeapDetails')" textVariant="text-bg-primary">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>{{ $t('heapdetails.TotalFree') }}</th>
|
||||
<td>{{ $n(Math.round(getFreeHeap() / 1024), 'kilobyte') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ $t('heapdetails.LargestFreeBlock') }}</th>
|
||||
<td>{{ $n(Math.round(systemStatus.heap_max_block / 1024), 'kilobyte') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ $t('heapdetails.Fragmentation') }}</th>
|
||||
<td>{{ $n(getFragmentation(), 'percent') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ $t('heapdetails.MaxUsage') }}</th>
|
||||
<td>{{ $n(Math.round(getMaxUsageAbs() / 1024), 'kilobyte') }} ({{ $n(getMaxUsageRel(), 'percent') }})</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</CardElement>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import CardElement from '@/components/CardElement.vue';
|
||||
import type { SystemStatus } from '@/types/SystemStatus';
|
||||
import { defineComponent, type PropType } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CardElement,
|
||||
},
|
||||
props: {
|
||||
systemStatus: { type: Object as PropType<SystemStatus>, required: true },
|
||||
},
|
||||
methods: {
|
||||
getFreeHeap() {
|
||||
return this.systemStatus.heap_total - this.systemStatus.heap_used;
|
||||
},
|
||||
getMaxUsageAbs() {
|
||||
return this.systemStatus.heap_total - this.systemStatus.heap_min_free;
|
||||
},
|
||||
getMaxUsageRel() {
|
||||
return this.getMaxUsageAbs() / this.systemStatus.heap_total;
|
||||
},
|
||||
getFragmentation() {
|
||||
return 1 - (this.systemStatus.heap_max_block / this.getFreeHeap());
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -248,6 +248,13 @@
|
||||
"LittleFs": "LittleFs",
|
||||
"Sketch": "Sketch"
|
||||
},
|
||||
"heapdetails": {
|
||||
"HeapDetails": "Detailinformationen zum Heap",
|
||||
"TotalFree": "Insgesamt frei",
|
||||
"LargestFreeBlock": "Größter zusammenhängender freier Block",
|
||||
"MaxUsage": "Maximale Speichernutzung seit Start",
|
||||
"Fragmentation": "Grad der Fragmentierung"
|
||||
},
|
||||
"radioinfo": {
|
||||
"RadioInformation": "Funkmodulinformationen",
|
||||
"Status": "{module} Status",
|
||||
|
||||
@ -249,6 +249,13 @@
|
||||
"LittleFs": "LittleFs",
|
||||
"Sketch": "Sketch"
|
||||
},
|
||||
"heapdetails": {
|
||||
"HeapDetails": "Heap Details",
|
||||
"TotalFree": "Total free",
|
||||
"LargestFreeBlock": "Biggest contiguous free block",
|
||||
"MaxUsage": "Maximum usage since start",
|
||||
"Fragmentation": "Level of fragmentation"
|
||||
},
|
||||
"radioinfo": {
|
||||
"RadioInformation": "Radio Information",
|
||||
"Status": "{module} Status",
|
||||
|
||||
@ -248,6 +248,13 @@
|
||||
"LittleFs": "LittleFs",
|
||||
"Sketch": "Sketch"
|
||||
},
|
||||
"heapdetails": {
|
||||
"HeapDetails": "Heap Details",
|
||||
"TotalFree": "Total free",
|
||||
"LargestFreeBlock": "Biggest contiguous free block",
|
||||
"MaxUsage": "Maximum usage since start",
|
||||
"Fragmentation": "Level of fragmentation"
|
||||
},
|
||||
"radioinfo": {
|
||||
"RadioInformation": "Informations sur la radio",
|
||||
"Status": "{module} Statut",
|
||||
|
||||
@ -22,6 +22,8 @@ export interface SystemStatus {
|
||||
// MemoryInfo
|
||||
heap_total: number;
|
||||
heap_used: number;
|
||||
heap_max_block: number;
|
||||
heap_min_free: number;
|
||||
littlefs_total: number;
|
||||
littlefs_used: number;
|
||||
sketch_total: number;
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
<div class="mt-5"></div>
|
||||
<MemoryInfo :systemStatus="systemDataList" />
|
||||
<div class="mt-5"></div>
|
||||
<HeapDetails :systemStatus="systemDataList" />
|
||||
<div class="mt-5"></div>
|
||||
<RadioInfo :systemStatus="systemDataList" />
|
||||
<div class="mt-5"></div>
|
||||
</BasePage>
|
||||
@ -16,6 +18,7 @@ import BasePage from '@/components/BasePage.vue';
|
||||
import FirmwareInfo from "@/components/FirmwareInfo.vue";
|
||||
import HardwareInfo from "@/components/HardwareInfo.vue";
|
||||
import MemoryInfo from "@/components/MemoryInfo.vue";
|
||||
import HeapDetails from "@/components/HeapDetails.vue";
|
||||
import RadioInfo from "@/components/RadioInfo.vue";
|
||||
import type { SystemStatus } from '@/types/SystemStatus';
|
||||
import { authHeader, handleResponse } from '@/utils/authentication';
|
||||
@ -27,6 +30,7 @@ export default defineComponent({
|
||||
FirmwareInfo,
|
||||
HardwareInfo,
|
||||
MemoryInfo,
|
||||
HeapDetails,
|
||||
RadioInfo,
|
||||
},
|
||||
data() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user