feat: unified monitoring service

This commit is contained in:
2025-09-16 20:09:48 +02:00
parent 83d87159fc
commit 93f09c3bb4
7 changed files with 533 additions and 3 deletions

View File

@@ -11,6 +11,7 @@
#include "core/TaskManager.h"
#include "Service.h"
#include "util/Logging.h"
#include "util/CpuUsage.h"
class Spore {
public:
@@ -33,6 +34,11 @@ public:
TaskManager& getTaskManager() { return taskManager; }
ClusterManager& getCluster() { return cluster; }
ApiServer& getApiServer() { return apiServer; }
// CPU usage monitoring
CpuUsage& getCpuUsage() { return cpuUsage; }
float getCurrentCpuUsage() const { return cpuUsage.getCpuUsage(); }
float getAverageCpuUsage() const { return cpuUsage.getAverageCpuUsage(); }
private:
@@ -45,6 +51,7 @@ private:
TaskManager taskManager;
ClusterManager cluster;
ApiServer apiServer;
CpuUsage cpuUsage;
std::vector<std::shared_ptr<Service>> services;
bool initialized;

View File

@@ -0,0 +1,51 @@
#pragma once
#include "spore/Service.h"
#include "spore/util/CpuUsage.h"
#include <functional>
class MonitoringService : public Service {
public:
MonitoringService(CpuUsage& cpuUsage);
void registerEndpoints(ApiServer& api) override;
const char* getName() const override { return "Monitoring"; }
// System resource information
struct SystemResources {
// CPU information
float currentCpuUsage;
float averageCpuUsage;
float maxCpuUsage;
float minCpuUsage;
unsigned long measurementCount;
bool isMeasuring;
// Memory information
size_t freeHeap;
size_t totalHeap;
size_t minFreeHeap;
size_t maxAllocHeap;
size_t heapFragmentation;
// Filesystem information
size_t totalBytes;
size_t usedBytes;
size_t freeBytes;
float usagePercent;
// System uptime
unsigned long uptimeMs;
unsigned long uptimeSeconds;
};
// Get current system resources
SystemResources getSystemResources() const;
private:
void handleResourcesRequest(AsyncWebServerRequest* request);
// Helper methods
size_t calculateHeapFragmentation() const;
void getFilesystemInfo(size_t& totalBytes, size_t& usedBytes) const;
CpuUsage& cpuUsage;
};

View File

@@ -0,0 +1,118 @@
#pragma once
#include <Arduino.h>
/**
* @brief CPU usage measurement utility for ESP32/ESP8266
*
* This class provides methods to measure CPU usage by tracking idle time
* and calculating the percentage of time the CPU is busy vs idle.
*/
class CpuUsage {
public:
/**
* @brief Construct a new CpuUsage object
*/
CpuUsage();
/**
* @brief Destructor
*/
~CpuUsage() = default;
/**
* @brief Initialize the CPU usage measurement
* Call this once during setup
*/
void begin();
/**
* @brief Start measuring CPU usage for the current cycle
* Call this at the beginning of your main loop
*/
void startMeasurement();
/**
* @brief End measuring CPU usage for the current cycle
* Call this at the end of your main loop
*/
void endMeasurement();
/**
* @brief Get the current CPU usage percentage
* @return float CPU usage percentage (0.0 to 100.0)
*/
float getCpuUsage() const;
/**
* @brief Get the average CPU usage over the measurement window
* @return float Average CPU usage percentage (0.0 to 100.0)
*/
float getAverageCpuUsage() const;
/**
* @brief Get the maximum CPU usage recorded
* @return float Maximum CPU usage percentage (0.0 to 100.0)
*/
float getMaxCpuUsage() const;
/**
* @brief Get the minimum CPU usage recorded
* @return float Minimum CPU usage percentage (0.0 to 100.0)
*/
float getMinCpuUsage() const;
/**
* @brief Reset all CPU usage statistics
*/
void reset();
/**
* @brief Check if measurement is currently active
* @return true if measurement is active, false otherwise
*/
bool isMeasuring() const;
/**
* @brief Get the number of measurements taken
* @return unsigned long Number of measurements
*/
unsigned long getMeasurementCount() const;
private:
// Measurement state
bool _initialized;
bool _measuring;
unsigned long _measurementCount;
// Timing variables
unsigned long _cycleStartTime;
unsigned long _idleStartTime;
unsigned long _totalIdleTime;
unsigned long _totalCycleTime;
// Statistics
float _currentCpuUsage;
float _averageCpuUsage;
float _maxCpuUsage;
float _minCpuUsage;
unsigned long _totalCpuTime;
// Rolling average window
static constexpr size_t ROLLING_WINDOW_SIZE = 10;
float _rollingWindow[ROLLING_WINDOW_SIZE];
size_t _rollingIndex;
bool _rollingWindowFull;
/**
* @brief Update rolling average calculation
* @param value New value to add to rolling average
*/
void updateRollingAverage(float value);
/**
* @brief Update min/max statistics
* @param value New value to check against min/max
*/
void updateMinMax(float value);
};