feat(ops/monitoring): add in-memory log buffer, metrics time-series and ops UI integration

This commit is contained in:
2026-02-19 17:23:43 +00:00
parent dc6ce341bd
commit eacddc7ce1
14 changed files with 482 additions and 128 deletions

View File

@@ -20,6 +20,15 @@ export class OpsViewLogs extends DeesElement {
filters: {},
};
@state()
accessor filterLevel: string | undefined;
@state()
accessor filterCategory: string | undefined;
@state()
accessor filterLimit: number = 100;
constructor() {
super();
const subscription = appstate.logStatePart
@@ -174,29 +183,43 @@ export class OpsViewLogs extends DeesElement {
`;
}
async connectedCallback() {
super.connectedCallback();
// Auto-fetch logs when the view mounts
this.fetchLogs();
}
private async fetchLogs() {
const filters = this.getActiveFilters();
await appstate.logStatePart.dispatchAction(appstate.fetchRecentLogsAction, {
limit: filters.limit || 100,
level: filters.level as 'debug' | 'info' | 'warn' | 'error' | undefined,
category: filters.category as 'smtp' | 'dns' | 'security' | 'system' | 'email' | undefined,
limit: this.filterLimit,
level: this.filterLevel as 'debug' | 'info' | 'warn' | 'error' | undefined,
category: this.filterCategory as 'smtp' | 'dns' | 'security' | 'system' | 'email' | undefined,
});
}
private updateFilter(type: string, value: string) {
if (value === 'all') {
value = undefined;
const resolved = value === 'all' ? undefined : value;
switch (type) {
case 'level':
this.filterLevel = resolved;
break;
case 'category':
this.filterCategory = resolved;
break;
case 'limit':
this.filterLimit = resolved ? parseInt(resolved, 10) : 100;
break;
}
// Update filters then fetch logs
this.fetchLogs();
}
private getActiveFilters() {
return {
level: this.logState.filters.level?.[0],
category: this.logState.filters.category?.[0],
limit: 100,
level: this.filterLevel,
category: this.filterCategory,
limit: this.filterLimit,
};
}