Skip to content

Parse historical analysis logs from victoria#361

Merged
brucetony merged 4 commits intodevelopfrom
360-parse-historical-analysis-logs-from-victoria
Apr 23, 2026
Merged

Parse historical analysis logs from victoria#361
brucetony merged 4 commits intodevelopfrom
360-parse-historical-analysis-logs-from-victoria

Conversation

@brucetony
Copy link
Copy Markdown
Collaborator

@brucetony brucetony commented Apr 22, 2026

Summary by CodeRabbit

  • New Features

    • Toggle to show/hide UTC timestamps in container logs; download/copy now use the formatted output.
    • UI now shows current-run logs and a separate history view for previous runs.
  • Security

    • Log retrieval and event endpoints now require JWT authentication.
  • Tests

    • Updated tests and mocks to exercise the new log schemas and timestamped entries.

@brucetony brucetony linked an issue Apr 22, 2026 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

Introduces structured pod log DTOs and two new endpoints (GET /logs/{analysis_id}, GET /history/{analysis_id}); updates API client/types, composable fetch path/typing, components to consume PodLog[] (with optional timestamp toggle and formatted outputs), and test mocks/specs to match the new shapes.

Changes

Cohort / File(s) Summary
API Schemas & Client
app/services/Api.ts, app/services/hub_adapter_swagger.json
Added PodLog, RunLogs, AnalysisLogsResponse, AnalysisLogHistoryResponse; added GET /logs/{analysis_id} and GET /history/{analysis_id} endpoints; adjusted Registry/RegistryProject fields and StatusOnlyResponse nullability; marked some events endpoints as secure.
API Usage / Mocks
app/composables/useAPIFetch.ts, test/mockapi/handlers.ts
Changed fetch path from /po/logs/{id} to /logs/{id} and typed useAPIFetch as AnalysisLogsResponse; updated MSW handlers to new /logs and /history routes and response shapes.
Log Display Components
app/components/analysis/logs/AnalysisLogCardContent.vue, app/components/analysis/logs/ContainerLogs.vue
Switched log props/fields from `string
Tests
test/components/analysis/constants.ts, test/components/analysis/logs/AnalysisLogCardContent.spec.ts, test/components/analysis/logs/ContainerLogs.spec.ts
Introduced fakePodLogs: PodLog[]; updated tests to supply typed pod-log fixtures and mocked composable responses matching new API schemas; adjusted assertions to new payload shapes.

Sequence Diagram

sequenceDiagram
    participant Container as ContainerLogs
    participant API as PodOrc API
    participant Card as AnalysisLogCardContent

    Container->>+API: GET /logs/{analysis_id}
    API-->>-Container: AnalysisLogsResponse (analysis_logs[], nginx_logs[], run_number)
    Container->>+API: GET /history/{analysis_id}
    API-->>-Container: AnalysisLogHistoryResponse (runs: RunLogs[])

    Container->>Card: pass current analysis_logs / nginx_logs
    Card->>Card: compute formatted strings (formatTimestamp / formatLogs)
    Card-->>Container: render formatted/current logs (with toggle for timestamps)

    Container->>Card: pass previous runs' logs (prevRunsList)
    Card-->>Container: render historical run logs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • Parse historical analysis logs from Victoria #360: Adds /history endpoint and AnalysisLogHistoryResponse/RunLogs/PodLog types and updates ContainerLogs to fetch and render historical runs — aligns with the issue's objective to support historical analysis logs.

Poem

🐰 I hopped through logs both old and new,
Timestamps tucked in UTC blue,
Runs and pods in tidy rows,
Messages marching as time goes,
A tiny rabbit cheers—hooray for structured views!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Parse historical analysis logs from victoria' clearly describes the main objective of the PR, which adds support for retrieving and displaying historical analysis logs through new API endpoints and UI components.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 360-parse-historical-analysis-logs-from-victoria

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/mockapi/handlers.ts (1)

93-123: ⚠️ Potential issue | 🟠 Major

Update the mocks to return the new log DTOs.

These handlers now match /logs and /history, but still return the old nested { status, data: { analysis, nginx } } shape. Consumers now expect AnalysisLogsResponse and AnalysisLogHistoryResponse, so tests using these mocks will render empty logs or miss history entirely.

🐛 Proposed mock response update
 import {
+  type AnalysisLogHistoryResponse,
+  type AnalysisLogsResponse,
   type BodyKongInitializeKongInitializePost,
   type BodyPodorcPodsCreatePoPost,
   type CleanupPodResponse,
   PodStatus,
 } from "~/services/Api";
@@
   // Analysis logs
   http.get(`/logs/${fakeAnalysisId}`, () => {
-    return HttpResponse.json({
-      status: 200,
-      data: {
-        analysis: {
-          [fakeAnalysisId]: ["Starting FlameCoreSDK"],
-        },
-        nginx: {
-          [fakeAnalysisId]: [
-            "/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty",
-          ],
-        },
-      },
-    });
+    const response: AnalysisLogsResponse = {
+      analysis_id: fakeAnalysisId,
+      run_number: 1,
+      analysis_logs: [
+        {
+          timestamp: "2026-04-22T00:00:00Z",
+          message: "Starting FlameCoreSDK",
+        },
+      ],
+      nginx_logs: [
+        {
+          timestamp: "2026-04-22T00:00:00Z",
+          message: "/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty",
+        },
+      ],
+    };
+
+    return HttpResponse.json(response);
   }),
 
   http.get(`/history/${fakeAnalysisId}`, () => {
-    return HttpResponse.json({
-      status: 200,
-      data: {
-        analysis: {
-          [fakeAnalysisId]: ["Starting FlameCoreSDK"],
-        },
-        nginx: {
-          [fakeAnalysisId]: [
-            "/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty",
-          ],
-        },
-      },
-    });
+    const response: AnalysisLogHistoryResponse = {
+      analysis_id: fakeAnalysisId,
+      runs: [
+        {
+          run_number: 1,
+          analysis_logs: [
+            {
+              timestamp: "2026-04-22T00:00:00Z",
+              message: "Starting FlameCoreSDK",
+            },
+          ],
+          nginx_logs: [
+            {
+              timestamp: "2026-04-22T00:00:00Z",
+              message: "/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty",
+            },
+          ],
+        },
+      ],
+    };
+
+    return HttpResponse.json(response);
   }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/mockapi/handlers.ts` around lines 93 - 123, The mock handlers for
http.get(`/logs/${fakeAnalysisId}`) and http.get(`/history/${fakeAnalysisId}`)
still return the old {status, data: {analysis, nginx}} shape; update them to
return the new AnalysisLogsResponse and AnalysisLogHistoryResponse shapes
respectively so tests consume real DTOs. Replace the nested analysis/nginx
structure with the DTOs' expected top-level properties (e.g., the
response.data.logs or response.data.history arrays/objects per the
AnalysisLogsResponse/AnalysisLogHistoryResponse definitions) and populate
entries for the fakeAnalysisId with appropriate targets (analysis and nginx) and
their log lines so consumers see non-empty logs/history. Ensure you return the
same HTTP status (200) but with the new DTO structure from the handlers named in
the diff.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/analysis/logs/ContainerLogs.vue`:
- Around line 30-36: gatherCurrentLogs currently leaves currentLogs unchanged
for non-403 errors, causing stale live logs to persist when the live endpoint
returns 404; update the error handling in gatherCurrentLogs so that when
status.value === "error" and error.value?.statusCode === 404 you set
currentLogs.value = null (and keep the existing navigateTo("/error/403")
behavior for 403), and apply the same 404-clearing change to the similar block
around lines handling the same logic (the second occurrence referenced in the
review) so both code paths clear currentLogs on 404.
- Around line 45-49: The prevLogs list is including the same run twice because
historyResp.runs contains the current/latest run; update the assignment of
prevLogs (and the equivalent logic used for the “All Previous Runs” rendering
between lines 88-121) to filter out the run that is already shown as the
most-recent/live run by comparing run_number (e.g., exclude historyResp.runs
entries where run_number === currentRunNumber or activeLiveRun?.run_number),
then sort the remaining items descending as before so the UI never renders the
same run in both “Most Recent Run” and “All Previous Runs”.

In `@app/services/hub_adapter_swagger.json`:
- Around line 5894-5909: PodLog.timestamp is declared as a plain string with no
format/contract; update the PodLog schema (PodLog.timestamp) to either add
"format": "date-time" if the hub adapter normalizes timestamps to ISO‑8601 so
generated clients/validators match EventLog.timestamp, or otherwise add a clear
description on PodLog.timestamp indicating the exact format (e.g., epoch ms,
Victoria `_time`, or other) the frontend must parse; ensure the chosen change
keeps PodLog.timestamp consistent with EventLog.timestamp behavior.
- Around line 6175-6185: The Registry.account_secret and
RegistryProject.account_secret fields are exposed in response schemas and should
be treated as sensitive; update their property definitions in the OpenAPI JSON
(the objects named "Registry" and "RegistryProject" in
app/services/hub_adapter_swagger.json) to include "writeOnly": true so the field
is only accepted on input and omitted from responses (this will prevent the
TypeScript client from treating it as a response field once clients are
regenerated), and remove or redact any real secret values from the mock data
file public/analyses.json so tests/examples do not contain credentials.
- Around line 2819-2870: The new path parameters for analysis_id in the
endpoints "logs_analysis_live_get_logs__analysis_id__get" (/logs/{analysis_id})
and the analogous /history/{analysis_id} need to match the existing flexible
schema pattern: update the parameter schema for the "analysis_id" parameter (the
parameter object named analysis_id) to use anyOf with the same options used
elsewhere (e.g., anyOf: [ { type: "string", format: "uuid" }, { type: "string" }
] or anyOf: [ { type: "string", format: "uuid" }, { "type": "string" }, {
"type": "null" } ] depending on which pattern `/po/status/{analysis_id}` and
`/analyses/{analysis_id}` use) so the contract is consistent across endpoints.

---

Outside diff comments:
In `@test/mockapi/handlers.ts`:
- Around line 93-123: The mock handlers for http.get(`/logs/${fakeAnalysisId}`)
and http.get(`/history/${fakeAnalysisId}`) still return the old {status, data:
{analysis, nginx}} shape; update them to return the new AnalysisLogsResponse and
AnalysisLogHistoryResponse shapes respectively so tests consume real DTOs.
Replace the nested analysis/nginx structure with the DTOs' expected top-level
properties (e.g., the response.data.logs or response.data.history arrays/objects
per the AnalysisLogsResponse/AnalysisLogHistoryResponse definitions) and
populate entries for the fakeAnalysisId with appropriate targets (analysis and
nginx) and their log lines so consumers see non-empty logs/history. Ensure you
return the same HTTP status (200) but with the new DTO structure from the
handlers named in the diff.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ec0544ef-4f3d-4c13-a3dc-5c73de089714

📥 Commits

Reviewing files that changed from the base of the PR and between ddb01f0 and 2cb6c75.

📒 Files selected for processing (6)
  • app/components/analysis/logs/AnalysisLogCardContent.vue
  • app/components/analysis/logs/ContainerLogs.vue
  • app/composables/useAPIFetch.ts
  • app/services/Api.ts
  • app/services/hub_adapter_swagger.json
  • test/mockapi/handlers.ts

Comment thread app/components/analysis/logs/ContainerLogs.vue
Comment thread app/components/analysis/logs/ContainerLogs.vue Outdated
Comment thread app/services/hub_adapter_swagger.json
Comment thread app/services/hub_adapter_swagger.json
Comment thread app/services/hub_adapter_swagger.json
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
app/components/analysis/logs/ContainerLogs.vue (1)

61-64: ⚠️ Potential issue | 🟡 Minor

refreshLogs never refreshes history.

gatherPreviousLogs() only runs once at setup. When a run finishes (or a new run starts) while the panel is open, the polling loop updates currentLogs but prevLogs stays frozen — so the completed run never appears under "All Previous Runs" without a full remount, and the run-number filter at line 48 can also become stale.

♻️ Suggested fix
 async function refreshLogs() {
   await refresh();
   gatherCurrentLogs();
+  await gatherPreviousLogs();
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/analysis/logs/ContainerLogs.vue` around lines 61 - 64,
refreshLogs currently calls refresh() and gatherCurrentLogs() but never updates
the historical cache, so prevLogs and the run-number filter become stale when
runs start/finish; update refreshLogs to also call gatherPreviousLogs() (or call
the function that repopulates prevLogs) after refresh() so previous runs are
recomputed when polling occurs, ensuring gatherPreviousLogs(), currentLogs and
prevLogs stay in sync with refresh() updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@app/components/analysis/logs/ContainerLogs.vue`:
- Around line 61-64: refreshLogs currently calls refresh() and
gatherCurrentLogs() but never updates the historical cache, so prevLogs and the
run-number filter become stale when runs start/finish; update refreshLogs to
also call gatherPreviousLogs() (or call the function that repopulates prevLogs)
after refresh() so previous runs are recomputed when polling occurs, ensuring
gatherPreviousLogs(), currentLogs and prevLogs stay in sync with refresh()
updates.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bfca8d32-9ea4-4a24-996a-cb8427f76299

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb6c75 and 44f85d9.

📒 Files selected for processing (5)
  • app/components/analysis/logs/ContainerLogs.vue
  • test/components/analysis/constants.ts
  • test/components/analysis/logs/AnalysisLogCardContent.spec.ts
  • test/components/analysis/logs/ContainerLogs.spec.ts
  • test/mockapi/handlers.ts
✅ Files skipped from review due to trivial changes (1)
  • test/components/analysis/constants.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/mockapi/handlers.ts

@brucetony brucetony merged commit a095bc5 into develop Apr 23, 2026
5 checks passed
@brucetony brucetony deleted the 360-parse-historical-analysis-logs-from-victoria branch April 23, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse historical analysis logs from Victoria

1 participant