264 lines
11 KiB
C++
264 lines
11 KiB
C++
#pragma once
|
|
|
|
#include <mutex>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
// HealthTelemetry owns the current operational status snapshot directly, so
|
|
// callers can report health without sharing runtime-store state.
|
|
class HealthTelemetry
|
|
{
|
|
public:
|
|
struct SignalStatusSnapshot
|
|
{
|
|
bool hasSignal = false;
|
|
unsigned width = 0;
|
|
unsigned height = 0;
|
|
std::string modeName;
|
|
};
|
|
|
|
struct VideoIOStatusSnapshot
|
|
{
|
|
std::string backendName = "decklink";
|
|
std::string modelName;
|
|
bool supportsInternalKeying = false;
|
|
bool supportsExternalKeying = false;
|
|
bool keyerInterfaceAvailable = false;
|
|
bool externalKeyingRequested = false;
|
|
bool externalKeyingActive = false;
|
|
std::string statusMessage;
|
|
};
|
|
|
|
struct PerformanceSnapshot
|
|
{
|
|
double frameBudgetMilliseconds = 0.0;
|
|
double renderMilliseconds = 0.0;
|
|
double smoothedRenderMilliseconds = 0.0;
|
|
double completionIntervalMilliseconds = 0.0;
|
|
double smoothedCompletionIntervalMilliseconds = 0.0;
|
|
double maxCompletionIntervalMilliseconds = 0.0;
|
|
uint64_t lateFrameCount = 0;
|
|
uint64_t droppedFrameCount = 0;
|
|
uint64_t flushedFrameCount = 0;
|
|
};
|
|
|
|
struct RuntimeEventQueueSnapshot
|
|
{
|
|
std::string queueName = "runtime-events";
|
|
std::size_t depth = 0;
|
|
std::size_t capacity = 0;
|
|
uint64_t droppedCount = 0;
|
|
double oldestEventAgeMilliseconds = 0.0;
|
|
};
|
|
|
|
struct RuntimeEventDispatchSnapshot
|
|
{
|
|
uint64_t dispatchCallCount = 0;
|
|
uint64_t dispatchedEventCount = 0;
|
|
uint64_t handlerInvocationCount = 0;
|
|
uint64_t handlerFailureCount = 0;
|
|
double lastDispatchDurationMilliseconds = 0.0;
|
|
double maxDispatchDurationMilliseconds = 0.0;
|
|
};
|
|
|
|
struct RuntimeEventMetricsSnapshot
|
|
{
|
|
RuntimeEventQueueSnapshot queue;
|
|
RuntimeEventDispatchSnapshot dispatch;
|
|
};
|
|
|
|
struct PersistenceSnapshot
|
|
{
|
|
uint64_t writeSuccessCount = 0;
|
|
uint64_t writeFailureCount = 0;
|
|
bool lastWriteSucceeded = true;
|
|
bool unsavedChanges = false;
|
|
bool newerRequestPending = false;
|
|
std::string lastTargetKind;
|
|
std::string lastTargetPath;
|
|
std::string lastReason;
|
|
std::string lastErrorMessage;
|
|
};
|
|
|
|
struct BackendPlayoutSnapshot
|
|
{
|
|
std::string lifecycleState = "NotStarted";
|
|
std::string completionResult = "Unknown";
|
|
std::size_t readyQueueDepth = 0;
|
|
std::size_t readyQueueCapacity = 0;
|
|
std::size_t minReadyQueueDepth = 0;
|
|
std::size_t maxReadyQueueDepth = 0;
|
|
uint64_t readyQueueZeroDepthCount = 0;
|
|
uint64_t readyQueuePushedCount = 0;
|
|
uint64_t readyQueuePoppedCount = 0;
|
|
uint64_t readyQueueDroppedCount = 0;
|
|
uint64_t readyQueueUnderrunCount = 0;
|
|
std::size_t systemFramePoolFree = 0;
|
|
std::size_t systemFramePoolReady = 0;
|
|
std::size_t systemFramePoolScheduled = 0;
|
|
uint64_t systemFrameUnderrunCount = 0;
|
|
uint64_t systemFrameRepeatCount = 0;
|
|
uint64_t systemFrameDropCount = 0;
|
|
double systemFrameAgeAtScheduleMilliseconds = 0.0;
|
|
double systemFrameAgeAtCompletionMilliseconds = 0.0;
|
|
double outputRenderMilliseconds = 0.0;
|
|
double smoothedOutputRenderMilliseconds = 0.0;
|
|
double maxOutputRenderMilliseconds = 0.0;
|
|
double outputFrameAcquireMilliseconds = 0.0;
|
|
double outputFrameRenderRequestMilliseconds = 0.0;
|
|
double outputFrameEndAccessMilliseconds = 0.0;
|
|
double outputRenderQueueWaitMilliseconds = 0.0;
|
|
double outputRenderDrawMilliseconds = 0.0;
|
|
double outputReadbackFenceWaitMilliseconds = 0.0;
|
|
double outputReadbackMapMilliseconds = 0.0;
|
|
double outputReadbackCopyMilliseconds = 0.0;
|
|
double outputCachedCopyMilliseconds = 0.0;
|
|
double outputAsyncQueueMilliseconds = 0.0;
|
|
double outputAsyncQueueBufferMilliseconds = 0.0;
|
|
double outputAsyncQueueSetupMilliseconds = 0.0;
|
|
double outputAsyncQueueReadPixelsMilliseconds = 0.0;
|
|
double outputAsyncQueueFenceMilliseconds = 0.0;
|
|
double outputSyncReadMilliseconds = 0.0;
|
|
uint64_t outputAsyncReadbackMissCount = 0;
|
|
uint64_t outputCachedFallbackCount = 0;
|
|
uint64_t outputSyncFallbackCount = 0;
|
|
uint64_t completedFrameIndex = 0;
|
|
uint64_t scheduledFrameIndex = 0;
|
|
uint64_t scheduledLeadFrames = 0;
|
|
uint64_t measuredLagFrames = 0;
|
|
uint64_t catchUpFrames = 0;
|
|
uint64_t lateStreak = 0;
|
|
uint64_t dropStreak = 0;
|
|
uint64_t lateFrameCount = 0;
|
|
uint64_t droppedFrameCount = 0;
|
|
uint64_t flushedFrameCount = 0;
|
|
bool degraded = false;
|
|
std::string statusMessage;
|
|
};
|
|
|
|
struct Snapshot
|
|
{
|
|
SignalStatusSnapshot signal;
|
|
VideoIOStatusSnapshot videoIO;
|
|
PerformanceSnapshot performance;
|
|
RuntimeEventMetricsSnapshot runtimeEvents;
|
|
PersistenceSnapshot persistence;
|
|
BackendPlayoutSnapshot backendPlayout;
|
|
};
|
|
|
|
HealthTelemetry() = default;
|
|
|
|
void ReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
|
|
bool TryReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
|
|
|
|
void ReportVideoIOStatus(const std::string& backendName, const std::string& modelName,
|
|
bool supportsInternalKeying, bool supportsExternalKeying, bool keyerInterfaceAvailable,
|
|
bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage);
|
|
bool TryReportVideoIOStatus(const std::string& backendName, const std::string& modelName,
|
|
bool supportsInternalKeying, bool supportsExternalKeying, bool keyerInterfaceAvailable,
|
|
bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage);
|
|
|
|
void RecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
|
|
bool TryRecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
|
|
|
|
void RecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
|
|
bool TryRecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
|
|
|
|
void RecordRuntimeEventQueueMetrics(const std::string& queueName, std::size_t depth, std::size_t capacity,
|
|
uint64_t droppedCount, double oldestEventAgeMilliseconds);
|
|
bool TryRecordRuntimeEventQueueMetrics(const std::string& queueName, std::size_t depth, std::size_t capacity,
|
|
uint64_t droppedCount, double oldestEventAgeMilliseconds);
|
|
|
|
void RecordRuntimeEventDispatchStats(std::size_t dispatchedEvents, std::size_t handlerInvocations,
|
|
std::size_t handlerFailures, double dispatchDurationMilliseconds);
|
|
bool TryRecordRuntimeEventDispatchStats(std::size_t dispatchedEvents, std::size_t handlerInvocations,
|
|
std::size_t handlerFailures, double dispatchDurationMilliseconds);
|
|
|
|
void RecordPersistenceWriteResult(bool succeeded, const std::string& targetKind, const std::string& targetPath,
|
|
const std::string& reason, const std::string& errorMessage, bool newerRequestPending);
|
|
bool TryRecordPersistenceWriteResult(bool succeeded, const std::string& targetKind, const std::string& targetPath,
|
|
const std::string& reason, const std::string& errorMessage, bool newerRequestPending);
|
|
|
|
void RecordBackendPlayoutHealth(const std::string& lifecycleState, const std::string& completionResult,
|
|
std::size_t readyQueueDepth, std::size_t readyQueueCapacity, uint64_t readyQueuePushedCount,
|
|
std::size_t minReadyQueueDepth, std::size_t maxReadyQueueDepth, uint64_t readyQueueZeroDepthCount,
|
|
uint64_t readyQueuePoppedCount, uint64_t readyQueueDroppedCount, uint64_t readyQueueUnderrunCount,
|
|
double outputRenderMilliseconds, double smoothedOutputRenderMilliseconds, double maxOutputRenderMilliseconds,
|
|
double outputFrameAcquireMilliseconds, double outputFrameRenderRequestMilliseconds, double outputFrameEndAccessMilliseconds,
|
|
uint64_t completedFrameIndex, uint64_t scheduledFrameIndex, uint64_t scheduledLeadFrames,
|
|
uint64_t measuredLagFrames, uint64_t catchUpFrames, uint64_t lateStreak, uint64_t dropStreak,
|
|
uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount,
|
|
bool degraded, const std::string& statusMessage);
|
|
bool TryRecordBackendPlayoutHealth(const std::string& lifecycleState, const std::string& completionResult,
|
|
std::size_t readyQueueDepth, std::size_t readyQueueCapacity, uint64_t readyQueuePushedCount,
|
|
std::size_t minReadyQueueDepth, std::size_t maxReadyQueueDepth, uint64_t readyQueueZeroDepthCount,
|
|
uint64_t readyQueuePoppedCount, uint64_t readyQueueDroppedCount, uint64_t readyQueueUnderrunCount,
|
|
double outputRenderMilliseconds, double smoothedOutputRenderMilliseconds, double maxOutputRenderMilliseconds,
|
|
double outputFrameAcquireMilliseconds, double outputFrameRenderRequestMilliseconds, double outputFrameEndAccessMilliseconds,
|
|
uint64_t completedFrameIndex, uint64_t scheduledFrameIndex, uint64_t scheduledLeadFrames,
|
|
uint64_t measuredLagFrames, uint64_t catchUpFrames, uint64_t lateStreak, uint64_t dropStreak,
|
|
uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount,
|
|
bool degraded, const std::string& statusMessage);
|
|
|
|
void RecordOutputRenderQueueWait(double queueWaitMilliseconds);
|
|
bool TryRecordOutputRenderQueueWait(double queueWaitMilliseconds);
|
|
|
|
void RecordSystemMemoryPlayoutStats(std::size_t freeFrameCount, std::size_t readyFrameCount,
|
|
std::size_t scheduledFrameCount, uint64_t underrunCount, uint64_t repeatCount, uint64_t dropCount,
|
|
double frameAgeAtScheduleMilliseconds, double frameAgeAtCompletionMilliseconds);
|
|
bool TryRecordSystemMemoryPlayoutStats(std::size_t freeFrameCount, std::size_t readyFrameCount,
|
|
std::size_t scheduledFrameCount, uint64_t underrunCount, uint64_t repeatCount, uint64_t dropCount,
|
|
double frameAgeAtScheduleMilliseconds, double frameAgeAtCompletionMilliseconds);
|
|
|
|
void RecordOutputRenderPipelineTiming(
|
|
double drawMilliseconds,
|
|
double fenceWaitMilliseconds,
|
|
double mapMilliseconds,
|
|
double readbackCopyMilliseconds,
|
|
double cachedCopyMilliseconds,
|
|
double asyncQueueMilliseconds,
|
|
double asyncQueueBufferMilliseconds,
|
|
double asyncQueueSetupMilliseconds,
|
|
double asyncQueueReadPixelsMilliseconds,
|
|
double asyncQueueFenceMilliseconds,
|
|
double syncReadMilliseconds,
|
|
bool asyncReadbackMissed,
|
|
bool cachedFallbackUsed,
|
|
bool syncFallbackUsed);
|
|
bool TryRecordOutputRenderPipelineTiming(
|
|
double drawMilliseconds,
|
|
double fenceWaitMilliseconds,
|
|
double mapMilliseconds,
|
|
double readbackCopyMilliseconds,
|
|
double cachedCopyMilliseconds,
|
|
double asyncQueueMilliseconds,
|
|
double asyncQueueBufferMilliseconds,
|
|
double asyncQueueSetupMilliseconds,
|
|
double asyncQueueReadPixelsMilliseconds,
|
|
double asyncQueueFenceMilliseconds,
|
|
double syncReadMilliseconds,
|
|
bool asyncReadbackMissed,
|
|
bool cachedFallbackUsed,
|
|
bool syncFallbackUsed);
|
|
|
|
SignalStatusSnapshot GetSignalStatusSnapshot() const;
|
|
VideoIOStatusSnapshot GetVideoIOStatusSnapshot() const;
|
|
PerformanceSnapshot GetPerformanceSnapshot() const;
|
|
RuntimeEventMetricsSnapshot GetRuntimeEventMetricsSnapshot() const;
|
|
PersistenceSnapshot GetPersistenceSnapshot() const;
|
|
BackendPlayoutSnapshot GetBackendPlayoutSnapshot() const;
|
|
Snapshot GetSnapshot() const;
|
|
|
|
private:
|
|
mutable std::mutex mMutex;
|
|
SignalStatusSnapshot mSignalStatus;
|
|
VideoIOStatusSnapshot mVideoIOStatus;
|
|
PerformanceSnapshot mPerformance;
|
|
RuntimeEventMetricsSnapshot mRuntimeEvents;
|
|
PersistenceSnapshot mPersistence;
|
|
BackendPlayoutSnapshot mBackendPlayout;
|
|
};
|