-
Bug
-
Resolution: Unresolved
-
Critical
-
None
-
quay-v3.17.0
-
None
-
False
-
-
False
-
-
Bug: Organization Mirror Logs Not Displayed in New UI Chart
Severity: High
Affected Component: New UI (React) - Usage Logs
Related Issues: PROJQUAY-10040 (Organization Mirroring Feature)
Affects Version: Quay 3.17 (new UI)


Problem Statement
Organization mirror log events (org_mirror_{}{}) are displayed in the **log table* but are {}missing from the chart and legend{} in the new UI's Usage Logs tab. This makes it impossible to visualize organization mirroring activity over time.
Comparison:
- Old UI (Angular): Shows org mirror events in chart with colored lines and legend entries ✅
- New UI (React): Filters out org mirror events, only shows them in table below ❌
Steps to Reproduce
1. Enable organization mirroring for an organization:
POST /api/v1/organization/myorg/mirror
{
"external_reference": "harbor.example.com/production",
"sync_interval": 3600,
"internal_robot": "myorg+robot",
"skopeo_timeout": 300
}
2. Wait for org mirror worker to run and sync repositories (creates log events)
3. Navigate to: Organization → myorg → Logs tab
4. Observe the chart and legend
Expected Behavior (Old UI)
Chart Legend shows:
- Enable Organization Mirror
- Organization Mirror Sync Success
- Organization Mirror Sync Started
- Organization Mirror Repository Created
- Organization Mirror Sync Now Requested
- ... etc.
Chart displays:
- Colored bars/lines for each org mirror event type
- Visual representation of mirror activity over time
- Ability to toggle event types on/off via legend
Example: See attached screenshot oldUI.jpg
Actual Behavior (New UI)
Chart Legend shows:
- Create Robot Account
- Create Application
- Create organization
- Push to repository
- ❌ NO org_mirror_* events!
Chart displays:
- Only 4 event types (none related to org mirroring)
- No visual representation of mirror activity
Log Table (bottom of page):
- ✅ Shows "Organization mirror sync completed successfully"
- ✅ Log data exists in database
- ✅ API returns org mirror events
Example: See attached screenshot 317newUI.jpg
Root Cause Analysis
File: web/src/routes/UsageLogs/UsageLogs.tsx (Lines 170-288)
The logKinds object is a hardcoded whitelist of log event types for the chart:
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yamlexport const logKinds = { user_create: 'Create user', create_repo: 'Create Repository', repo_mirror_enabled: 'Enable Repository Mirror', // ✅ Repo mirror // ... many other events ... export_logs_failure: 'Export logs failure', // ❌ NO org_mirror_* events defined! };
File: web/src/routes/UsageLogs/UsageLogsGraph.tsx (Lines 105-113)
The chart filters logs using this whitelist:
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yamlfunction createDataSet() { const logData = {}; if (aggregateLogs) { aggregateLogs.forEach((log) => { if (logKinds[log.kind]) { // ❌ FILTERS OUT org_mirror events! logData[log.kind] = logData[log.kind] || []; logData[log.kind].push({ name: logKinds[log.kind], x: new Date(log.datetime), y: log.count, }); } // ❌ org_mirror_* logs are SILENTLY DROPPED here! }); } }
What happens:
- API returns ALL logs including org_mirror_sync_success
- Chart iterates through each log event
- For each log, checks: if (logKinds[log.kind])
- org_mirror events are NOT in logKinds → condition fails
- Event is silently skipped (not added to chart data)
- Legend is built from chart data → org_mirror events missing
Missing Log Event Types
These 14 org mirror events are in the database but NOT in logKinds:
org_mirror_enabled org_mirror_disabled org_mirror_config_created org_mirror_config_changed org_mirror_config_deleted org_mirror_sync_started org_mirror_sync_success org_mirror_sync_failed org_mirror_sync_now_requested org_mirror_sync_cancelled org_mirror_repo_discovered org_mirror_repo_created org_mirror_repo_skipped org_mirror_repo_creation_failed
Note: These events ARE defined in web/src/hooks/UseLogDescriptions.tsx (lines 225-315) but not used by the chart.
Impact Assessment
User Impact:
- ❌ Cannot visualize org mirror activity in new UI
- ❌ Cannot see trends (sync frequency, failures over time)
- ❌ Cannot debug mirror issues using chart
- ❌ Feature regression from old UI
- ✅ Workaround: Use old UI or read table logs
Severity: HIGH because:
- Breaks feature parity with old UI
- Required for PROJQUAY-10040 (org mirror feature) usability
- Affects all users using org mirroring
- Data exists but is invisible to users
Recommended Fix
Option 1: Quick Fix (Add to hardcoded list)
File: web/src/routes/UsageLogs/UsageLogs.tsx
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yamlexport const logKinds = { // ... existing events ... export_logs_success: 'Export logs queued for delivery', export_logs_failure: 'Export logs failure', // ✅ ADD ORG MIRROR EVENTS: org_mirror_enabled: 'Enable Organization Mirror', org_mirror_disabled: 'Disable Organization Mirror', org_mirror_config_created: 'Create Organization Mirror Configuration', org_mirror_config_changed: 'Change Organization Mirror Configuration', org_mirror_config_deleted: 'Delete Organization Mirror Configuration', org_mirror_sync_started: 'Start Organization Mirror Sync', org_mirror_sync_success: 'Organization Mirror Sync Success', org_mirror_sync_failed: 'Organization Mirror Sync Failed', org_mirror_sync_now_requested: 'Organization Mirror Immediate Sync Requested', org_mirror_sync_cancelled: 'Organization Mirror Sync Cancelled', org_mirror_repo_discovered: 'Organization Mirror Repository Discovered', org_mirror_repo_created: 'Organization Mirror Repository Created', org_mirror_repo_skipped: 'Organization Mirror Repository Skipped', org_mirror_repo_creation_failed: 'Organization Mirror Repository Creation Failed', };
Effort: 5 minutes
Risk: Low (just adding constants)
Option 2: Better Fix (Use dynamic descriptions)
Replace hardcoded logKinds with dynamic useLogDescriptions() hook:
File: web/src/routes/UsageLogs/UsageLogsGraph.tsx
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yamlimport {useLogDescriptions} from 'src/hooks/UseLogDescriptions'; export default function UsageLogsGraph(props) { const {getDescription} = useLogDescriptions(); function createDataSet() { const logData = {}; if (aggregateLogs) { aggregateLogs.forEach((log) => { const description = getDescription(log.kind, log.metadata); if (description) { // ✅ Works for ANY event type! logData[log.kind] = logData[log.kind] || []; logData[log.kind].push({ name: description.trim(), // Use dynamic description x: new Date(log.datetime), y: log.count, }); } }); } return logData; } }
Benefits:
- Single source of truth (UseLogDescriptions.tsx)
- New events automatically appear in chart
- No frontend code changes when adding new log types
- Matches old UI architecture
- Future-proof
Effort: 30 minutes
Risk: Medium (refactoring existing code)
Files Requiring Changes
Quick Fix:
- web/src/routes/UsageLogs/UsageLogs.tsx - Add 14 lines to logKinds
Better Fix:
- web/src/routes/UsageLogs/UsageLogsGraph.tsx - Replace logKinds[log.kind] with getDescription()
- web/src/routes/UsageLogs/UsageLogs.tsx - Export logKinds can be removed
- web/src/hooks/UseLogDescriptions.tsx - Add helper method getDescription(kind, metadata)
Acceptance Criteria
✅ AC1: Organization mirror log events appear in chart legend
✅ AC2: Chart displays colored bars for each org mirror event type:
- org_mirror_enabled
- org_mirror_sync_success
- org_mirror_sync_failed
- org_mirror_repo_created
- etc.
✅ AC3: Clicking legend item toggles visibility of that event type
✅ AC4: Chart matches old UI functionality (feature parity)
✅ AC5: All 14 org mirror event types are visible (not just subset)
✅ AC6: Future org mirror events automatically appear without code changes (if using Option 2)
Testing Steps
1. Setup: - Create org mirror: POST /api/v1/organization/testorg/mirror - Wait for sync to complete (generates logs) 2. Navigate: - Go to: Organization → testorg → Logs tab 3. Verify Chart: ✅ Legend shows org_mirror_* events ✅ Chart displays colored bars for org mirror activity ✅ Hover shows event details ✅ Legend toggle works 4. Verify Table: ✅ Table still shows all logs (existing functionality) 5. Compare: ✅ New UI chart matches old UI chart
Screenshots
Attached:
- oldUI.jpg - Old UI showing org mirror events in chart/legend ✅
- 317newUI.jpg - New UI missing org mirror events in chart ❌
Evidence:
- Old UI legend: org_mirror_repo_created, org_mirror_sync_success, org_mirror_sync_now_requested, etc.
- New UI legend: Only shows Create Robot Account, Create Application, etc.
- New UI table (bottom): Shows "Organization mirror sync completed successfully" (proves data exists)
Workaround
Until fixed, users can:
- Use old Angular UI for org mirror log visualization
- Read org mirror logs from table (bottom of new UI page)
- Query logs API directly
Related Issues
- PROJQUAY-10040: Organization mirroring feature (main implementation)
- PROJQUAY-10672: Credential exposure in org mirror API
- PROJQUAY-10673: Hide incompatible policies for org-mirrored repos
Priority Justification
This should be HIGH priority because:
- ✅ Feature regression (works in old UI, broken in new UI)
- ✅ Blocks org mirror feature usability
- ✅ Data exists but is invisible (silent failure)
- ✅ Quick fix available (14 lines of code)
- ✅ Affects all org mirroring users
- ✅ Required for PROJQUAY-10040 feature completeness