2182 - Observability loading issues#2208
Merged
crivetimihai merged 6 commits intomainfrom Jan 20, 2026
Merged
Conversation
5c76698 to
c0d0418
Compare
Resolves a GroupingError that occurred in PostgreSQL when querying observability data (tools, prompts, resources). The error was caused by SQLAlchemy generating different column expressions for the SELECT list and the GROUP BY clause when extracting data from JSON fields. This fix refactors the queries to create a single expression for the JSON field extraction and reuses it in both the SELECT and GROUP BY clauses, ensuring compatibility with PostgreSQL's strict grouping requirements. Additionally, this commit introduces: - Unit tests parametrized for both PostgreSQL and SQLite dialects to verify the fix at the query construction level. - An end-to-end test that calls the affected API endpoints to ensure they function correctly with a database backend. Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Introduces a global Chart.js registry to manage chart instances across the admin UI, preventing "canvas already in use" errors. Enhances observability panels (metrics, tools, prompts) by: - Centralizing chart destruction and registration. - Implementing visibility checks to defer rendering of charts on hidden canvases. - Adding safeguards to prevent redundant and concurrent loading of partial views. - Ensuring proper cleanup of charts and auto-refresh intervals when navigating between tabs or unloading the page. These changes improve the stability and performance of the observability dashboard, providing a smoother user experience. Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
The RBAC decorator expects a dict with 'email' and 'db' keys, not a MagicMock. Updated the tests to use create_mock_user_context() which provides the correct structure for permission checks. Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
- Remove redundant chart destruction on observability tab entry (charts are already destroyed when leaving the tab) - Replace ineffective 'destroy' DOM event listeners with beforeunload handlers (Alpine.js doesn't emit 'destroy' DOM events) - Move e2e test before __main__ block so it runs with pytest --main - Update observability_resources.html to use global chart registry for consistent chart lifecycle management - Add resources- prefix to chart cleanup when leaving observability tab These fixes address blank chart issues when returning to the observability tab and ensure proper cleanup of intervals/handlers. Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Addresses two issues identified in review: 1. Blank charts on return: When leaving observability tab, charts are destroyed but `metricsLoaded` etc. flags remained true, preventing partials from reloading. Now dispatch `observability:leave` event that resets loaded flags so partials reload on return. 2. Orphaned intervals: Auto-refresh timers continued running after leaving the tab. Now each partial (metrics, tools, prompts, resources) listens for `observability:leave` and calls cleanup() to stop intervals. The cleanup lifecycle is now: - Tab leave: dispatches observability:leave event - Partials: listen for event, call cleanup() to stop intervals - Parent: resets loaded flags so partials reload on next visit - Event handlers are properly removed in cleanup() to avoid leaks Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
c0d0418 to
03b638a
Compare
kcostell06
pushed a commit
to kcostell06/mcp-context-forge
that referenced
this pull request
Feb 24, 2026
* Resolve PostgreSQL GROUP BY error in analytics Resolves a GroupingError that occurred in PostgreSQL when querying observability data (tools, prompts, resources). The error was caused by SQLAlchemy generating different column expressions for the SELECT list and the GROUP BY clause when extracting data from JSON fields. This fix refactors the queries to create a single expression for the JSON field extraction and reuses it in both the SELECT and GROUP BY clauses, ensuring compatibility with PostgreSQL's strict grouping requirements. Additionally, this commit introduces: - Unit tests parametrized for both PostgreSQL and SQLite dialects to verify the fix at the query construction level. - An end-to-end test that calls the affected API endpoints to ensure they function correctly with a database backend. Signed-off-by: Gabriel Costa <gabrielcg@proton.me> * 2182 - Improve observability charts lifecycle Introduces a global Chart.js registry to manage chart instances across the admin UI, preventing "canvas already in use" errors. Enhances observability panels (metrics, tools, prompts) by: - Centralizing chart destruction and registration. - Implementing visibility checks to defer rendering of charts on hidden canvases. - Adding safeguards to prevent redundant and concurrent loading of partial views. - Ensuring proper cleanup of charts and auto-refresh intervals when navigating between tabs or unloading the page. These changes improve the stability and performance of the observability dashboard, providing a smoother user experience. Signed-off-by: Gabriel Costa <gabrielcg@proton.me> * Linting and testing fix Signed-off-by: Gabriel Costa <gabrielcg@proton.me> * fix(tests): use proper user context in observability SQL tests The RBAC decorator expects a dict with 'email' and 'db' keys, not a MagicMock. Updated the tests to use create_mock_user_context() which provides the correct structure for permission checks. Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix(observability): address chart lifecycle and cleanup issues - Remove redundant chart destruction on observability tab entry (charts are already destroyed when leaving the tab) - Replace ineffective 'destroy' DOM event listeners with beforeunload handlers (Alpine.js doesn't emit 'destroy' DOM events) - Move e2e test before __main__ block so it runs with pytest --main - Update observability_resources.html to use global chart registry for consistent chart lifecycle management - Add resources- prefix to chart cleanup when leaving observability tab These fixes address blank chart issues when returning to the observability tab and ensure proper cleanup of intervals/handlers. Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> * fix(observability): stop auto-refresh and reset state on tab leave Addresses two issues identified in review: 1. Blank charts on return: When leaving observability tab, charts are destroyed but `metricsLoaded` etc. flags remained true, preventing partials from reloading. Now dispatch `observability:leave` event that resets loaded flags so partials reload on return. 2. Orphaned intervals: Auto-refresh timers continued running after leaving the tab. Now each partial (metrics, tools, prompts, resources) listens for `observability:leave` and calls cleanup() to stop intervals. The cleanup lifecycle is now: - Tab leave: dispatches observability:leave event - Partials: listen for event, call cleanup() to stop intervals - Parent: resets loaded flags so partials reload on next visit - Event handlers are properly removed in cleanup() to avoid leaks Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> --------- Signed-off-by: Gabriel Costa <gabrielcg@proton.me> Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🐛 Bug-fix PR
📌 Summary
This PR addresses several issues:
GroupingErrorin Observability: The observability API endpoints for tools, prompts, and resources would fail when using a PostgreSQL database due to an SQL GROUP BY error. This prevented users on PostgreSQLfrom using the observability features.
user experience.
These fixes are important for ensuring the platform is stable, performant, and database-agnostic, providing a reliable experience for administrators and developers monitoring the system.
Closes #2182
🔁 Reproduction Steps
PostgreSQL
GroupingError:Frontend Chart Rendering Errors:
🐞 Root Cause
SELECTlist and theGROUP BYclause when extracting data from JSON fields. PostgreSQL requires these expressions to be identical, which was not the case, leading to a GroupingError.<canvas>element. This occurred because each observability panel managed its own charts independently and without a proper cleanup lifecycle when the view was changed.💡 Fix Description
SELECTandGROUP BYclauses, ensuring compatibility with PostgreSQL's strict grouping requirements.mcpgateway/static/admin.jsto manage the lifecycle of all Chart.js instances centrally.📋 Testing
tests/e2e/test_admin_apis.py): A new test test_observability_endpoints_with_database was added to call the affected API endpoints and ensure they return a successful response with the correct datastructure when backed by a database.
tests/unit/mcpgateway/test_admin_observability_sql.py): New test classes were added to verify the query construction. These tests are parameterized to run against both "postgresql" and "sqlite" dialects,ensuring the fix works for both and doesn't introduce regressions.
🧪 Verification
make lintmake testmake coverage✅ Checklist
make black isort pre-commit)