feat(ground-suite): redesign observability console
This commit is contained in:
1 parent
c67d553076
commit
153b0bf262
12 files changed
+1145
-507
No files matched your search
+70
-15
@@ -20,6 +20,7 @@ final observabilityControllerProvider =
|
||||
|
||||
class ObservabilityController extends Notifier<ObservabilityState> {
|
||||
static const _criticalAnnouncementWindow = Duration(seconds: 2);
|
||||
static const _timelineCapacity = 500;
|
||||
|
||||
StreamSubscription<VehicleDataUpdate>? _subscription;
|
||||
DateTime? _lastCriticalAnnouncementAt;
|
||||
@@ -75,10 +76,22 @@ class ObservabilityController extends Notifier<ObservabilityState> {
|
||||
|
||||
void _record(ObservedEvent event) {
|
||||
final announcement = _announcementFor(event);
|
||||
final retention = _isTimelineEvent(event)
|
||||
? _retainTimelineEvent(state.events, event)
|
||||
: _TimelineRetention(state.events);
|
||||
final heartbeat = event is HeartbeatEvent ? event : state.lastHeartbeat;
|
||||
final observedStreams = switch (event) {
|
||||
TelemetryEvent(:final kind) => {...state.observedTelemetryKinds, kind},
|
||||
_ => state.observedTelemetryKinds,
|
||||
};
|
||||
state = state.copyWith(
|
||||
status: ObservationStatus.receiving,
|
||||
lastFrameAt: event.receivedAt,
|
||||
events: [...state.events, event],
|
||||
events: retention.events,
|
||||
lastHeartbeat: heartbeat,
|
||||
observedTelemetryKinds: Set.unmodifiable(observedStreams),
|
||||
localTimelineEvictionCount:
|
||||
state.localTimelineEvictionCount + retention.evictionCount,
|
||||
accessibilityAnnouncement: announcement.message,
|
||||
replaceAccessibilityAnnouncement: true,
|
||||
coalescedAlertCount:
|
||||
@@ -110,6 +123,45 @@ class ObservabilityController extends Notifier<ObservabilityState> {
|
||||
void _cancelSubscription() {
|
||||
_subscription?.cancel();
|
||||
}
|
||||
|
||||
_TimelineRetention _retainTimelineEvent(
|
||||
List<ObservedEvent> current,
|
||||
ObservedEvent incoming,
|
||||
) {
|
||||
if (current.length < _timelineCapacity) {
|
||||
return _TimelineRetention([...current, incoming]);
|
||||
}
|
||||
|
||||
final retained = List<ObservedEvent>.of(current);
|
||||
final optionalIndex = retained.indexWhere((event) => !_isCritical(event));
|
||||
if (optionalIndex >= 0) {
|
||||
retained.removeAt(optionalIndex);
|
||||
retained.add(incoming);
|
||||
return _TimelineRetention(retained, evictionCount: 1);
|
||||
}
|
||||
|
||||
if (_isCritical(incoming)) {
|
||||
retained.removeAt(0);
|
||||
retained.add(incoming);
|
||||
return _TimelineRetention(retained, evictionCount: 1);
|
||||
}
|
||||
|
||||
return _TimelineRetention(retained, evictionCount: 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool _isCritical(ObservedEvent event) =>
|
||||
event is ErrorEvent || event is ShutdownEvent;
|
||||
|
||||
bool _isTimelineEvent(ObservedEvent event) =>
|
||||
event is LogEvent || _isCritical(event);
|
||||
|
||||
class _TimelineRetention {
|
||||
_TimelineRetention(Iterable<ObservedEvent> events, {this.evictionCount = 0})
|
||||
: events = List.unmodifiable(events);
|
||||
|
||||
final List<ObservedEvent> events;
|
||||
final int evictionCount;
|
||||
}
|
||||
|
||||
enum ObservationStatus {
|
||||
@@ -129,9 +181,12 @@ class ObservabilityState {
|
||||
required this.isReplay,
|
||||
required this.status,
|
||||
required this.events,
|
||||
required this.lastHeartbeat,
|
||||
required this.observedTelemetryKinds,
|
||||
required this.parserDropCount,
|
||||
required this.semanticDropCount,
|
||||
required this.coalescedAlertCount,
|
||||
required this.localTimelineEvictionCount,
|
||||
this.lastFrameAt,
|
||||
this.accessibilityAnnouncement,
|
||||
});
|
||||
@@ -142,9 +197,12 @@ class ObservabilityState {
|
||||
isReplay: source.isReplay,
|
||||
status: ObservationStatus.starting,
|
||||
events: const [],
|
||||
lastHeartbeat: null,
|
||||
observedTelemetryKinds: const {},
|
||||
parserDropCount: 0,
|
||||
semanticDropCount: 0,
|
||||
coalescedAlertCount: 0,
|
||||
localTimelineEvictionCount: 0,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -152,32 +210,24 @@ class ObservabilityState {
|
||||
final bool isReplay;
|
||||
final ObservationStatus status;
|
||||
final List<ObservedEvent> events;
|
||||
final HeartbeatEvent? lastHeartbeat;
|
||||
final Set<TelemetryKind> observedTelemetryKinds;
|
||||
final int parserDropCount;
|
||||
final int semanticDropCount;
|
||||
final int coalescedAlertCount;
|
||||
final int localTimelineEvictionCount;
|
||||
final DateTime? lastFrameAt;
|
||||
final String? accessibilityAnnouncement;
|
||||
|
||||
HeartbeatEvent? get lastHeartbeat {
|
||||
for (final event in events.reversed) {
|
||||
if (event case HeartbeatEvent()) {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<TelemetryKind> get observedTelemetryKinds => {
|
||||
for (final event in events)
|
||||
if (event case TelemetryEvent(:final kind)) kind,
|
||||
};
|
||||
|
||||
ObservabilityState copyWith({
|
||||
ObservationStatus? status,
|
||||
List<ObservedEvent>? events,
|
||||
HeartbeatEvent? lastHeartbeat,
|
||||
Set<TelemetryKind>? observedTelemetryKinds,
|
||||
int? parserDropCount,
|
||||
int? semanticDropCount,
|
||||
int? coalescedAlertCount,
|
||||
int? localTimelineEvictionCount,
|
||||
DateTime? lastFrameAt,
|
||||
String? accessibilityAnnouncement,
|
||||
bool replaceAccessibilityAnnouncement = false,
|
||||
@@ -187,9 +237,14 @@ class ObservabilityState {
|
||||
isReplay: isReplay,
|
||||
status: status ?? this.status,
|
||||
events: events ?? this.events,
|
||||
lastHeartbeat: lastHeartbeat ?? this.lastHeartbeat,
|
||||
observedTelemetryKinds:
|
||||
observedTelemetryKinds ?? this.observedTelemetryKinds,
|
||||
parserDropCount: parserDropCount ?? this.parserDropCount,
|
||||
semanticDropCount: semanticDropCount ?? this.semanticDropCount,
|
||||
coalescedAlertCount: coalescedAlertCount ?? this.coalescedAlertCount,
|
||||
localTimelineEvictionCount:
|
||||
localTimelineEvictionCount ?? this.localTimelineEvictionCount,
|
||||
lastFrameAt: lastFrameAt ?? this.lastFrameAt,
|
||||
accessibilityAnnouncement: replaceAccessibilityAnnouncement
|
||||
? accessibilityAnnouncement
|
||||
|
||||
Reference in new issue
Block a user