diff --git a/bin/web/src/lib/analysis.svelte.ts b/bin/web/src/lib/analysis.svelte.ts index f402a12..83ec70f 100644 --- a/bin/web/src/lib/analysis.svelte.ts +++ b/bin/web/src/lib/analysis.svelte.ts @@ -4,8 +4,15 @@ import { req } from "./utils.svelte"; export type AnalysisReport = { metadata: ReportMetadata; rows: AnalysisRow[]; + statistics: ReportStatistics; }; +export type ReportStatistics = { + num_warnings: number; + num_informational_logs: number; + num_skipped_packets: number; +} + export type ReportMetadata = { analyzers: AnalyzerMetadata[]; rayhunter: RayhunterMetadata; @@ -57,17 +64,22 @@ export type InformationalEvent = { export function parse_finished_report(report_json: NewlineDeliminatedJson): AnalysisReport { const metadata: ReportMetadata = report_json[0]; // this can be cast directly + let num_warnings = 0; + let num_informational_logs = 0; + let num_skipped_packets = 0; const rows: AnalysisRow[] = report_json.slice(1).map((row_json: any) => { const analysis: PacketAnalysis[] = row_json.analysis.map((analysis_json: any) => { const events: Event[] = analysis_json.events.map((event_json: any): Event | null => { if (event_json === null) { return null; } else if (event_json.event_type === "Informational") { + num_informational_logs += 1; return { type: EventType.Informational, message: event_json.message, }; } else { + num_warnings += 1; return { type: EventType.Warning, severity: event_json.severity === "High" ? Severity.High : @@ -82,6 +94,7 @@ export function parse_finished_report(report_json: NewlineDeliminatedJson): Anal events, }; }); + num_skipped_packets += row_json.skipped_message_reasons.length; return { timestamp: new Date(row_json.timestamp), skipped_message_reasons: row_json.skipped_message_reasons, @@ -89,6 +102,11 @@ export function parse_finished_report(report_json: NewlineDeliminatedJson): Anal }; }); return { + statistics: { + num_informational_logs, + num_warnings, + num_skipped_packets, + }, metadata, rows, }; diff --git a/bin/web/src/lib/components/AnalysisTable.svelte b/bin/web/src/lib/components/AnalysisTable.svelte index 441bc9a..e1b6f13 100644 --- a/bin/web/src/lib/components/AnalysisTable.svelte +++ b/bin/web/src/lib/components/AnalysisTable.svelte @@ -10,32 +10,75 @@ timeStyle: "long", dateStyle: "short", }); + + const skipped_messages: Map = $derived.by(() => { + let map = new Map(); + for (const row of report.rows) { + for (const message of row.skipped_message_reasons) { + let count = map.get(message); + if (count === undefined) { + count = 0; + } + map.set(message, count + 1); + } + } + return map; + }); -

Warnings

- - - - - - - - - - {#each report.rows as row, row_idx} - {#each row.analysis as analysis} - {@const parsed_date = new Date(analysis.timestamp)} - {@const warnings = analysis.events.filter(e => e.type === EventType.Warning)} - {#each warnings as warning} - {@const severity = ['Low', 'Medium', 'High'][warning.severity]} - {@const severity_class = ['bg-red-200', 'bg-red-400', 'bg-red-600'][warning.severity]} - - - - - +

Warnings and Informational Logs

+{#if report.statistics.num_warnings === 0 && report.statistics.num_informational_logs === 0} +

Nothing to show!

+{:else} +
TimestampWarningSeverity
{date_formatter.format(parsed_date)}{warning.message}{severity}
+ + + + + + + + + {#each report.rows as row, row_idx} + {#each row.analysis as analysis} + {@const parsed_date = new Date(analysis.timestamp)} + {#each analysis.events.filter(e => e !== null) as event} + + {#if event.type === EventType.Warning} + {@const severity = ['Low', 'Medium', 'High'][event.severity]} + {@const severity_class = ['bg-red-200', 'bg-red-400', 'bg-red-600'][event.severity]} + + + + {:else if event.type === EventType.Informational} + + + + {/if} + + {/each} {/each} {/each} - {/each} - -
TimestampWarningSeverity
{date_formatter.format(parsed_date)}{event.message}{severity}{date_formatter.format(parsed_date)}{event.message}Info
+ + +{/if} +{#if report.statistics.num_skipped_packets > 0} +

Unparsed Messages

+

These are due to a limitation or bug in Rayhunter's parser, and aren't ususally a problem.

+ + + + + + + + + {#each skipped_messages.entries() as [message, count]} + + + + + {/each} + +
# of messages affectedReason/Error
{count}{message}
+{/if} diff --git a/bin/web/src/lib/components/AnalysisView.svelte b/bin/web/src/lib/components/AnalysisView.svelte index 2bda260..7fbca1d 100644 --- a/bin/web/src/lib/components/AnalysisView.svelte +++ b/bin/web/src/lib/components/AnalysisView.svelte @@ -20,7 +20,7 @@

Error getting analysis report: {entry.analysis_report}

{:else} {@const metadata: ReportMetadata = entry.analysis_report.metadata} -
+
{#if entry.analysis_report.rows.length > 0} {:else} @@ -28,7 +28,7 @@ {/if}

Metadata

-

Rayhunter version: {metadata.rayhunter.rayhunter_version}

+

Analysis by Rayhunter version {metadata.rayhunter.rayhunter_version}

Device system OS: {metadata.rayhunter.system_os}

Analyzers

{#each metadata.analyzers as analyzer} diff --git a/bin/web/src/lib/components/ManifestTableRow.svelte b/bin/web/src/lib/components/ManifestTableRow.svelte index 47af51c..7fe0151 100644 --- a/bin/web/src/lib/components/ManifestTableRow.svelte +++ b/bin/web/src/lib/components/ManifestTableRow.svelte @@ -39,7 +39,7 @@ {/if} - +