-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feature: websocket server framework, logs web session implementation #12053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This feature enables administrators to view management server logs directly in the UI through a dedicated API call. It leverages a Netty-based websocket server to stream logs in real time, offering an efficient way to monitor and debug server operations. Note that the plugin is disabled by default and must be enabled manually. Signed-off-by: Abhishek Kumar <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12053 +/- ##
============================================
- Coverage 17.56% 17.52% -0.05%
- Complexity 15539 15546 +7
============================================
Files 5911 5940 +29
Lines 529359 531063 +1704
Branches 64655 64822 +167
============================================
+ Hits 92979 93043 +64
- Misses 425922 427554 +1632
- Partials 10458 10466 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Signed-off-by: Abhishek Kumar <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
|
@blueorangutan package |
|
@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 15730 |
|
@blueorangutan package |
|
@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✖️ debian ✔️ suse15. SL-JID 15742 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a comprehensive WebSocket server framework enabling both standalone (Netty-based) and embedded (Jetty-based) WebSocket server modes. The first implementation provides a Logs Web Session feature allowing ROOT administrators to securely stream and view management server logs in real-time via the UI.
Key changes:
- New WebSocket framework with flexible server configuration (standalone/embedded modes)
- Logs Web Session API and UI for real-time log streaming with filtering
- Database schema additions for session and management server configuration storage
Reviewed Changes
Copilot reviewed 88 out of 88 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| framework/websocket-server/* | Core WebSocket server framework with Netty implementation and router |
| plugins/logs-web-server/* | Logs web session plugin with API, streaming, and session management |
| ui/src/components/view/LogsConsole.vue | New UI component for displaying real-time logs with filtering |
| ui/src/utils/plugins.js | Enhanced job polling with log viewing capabilities |
| engine/schema/.../schema-42200to42300.sql | Database schema for logs sessions and management server details |
| client/src/main/java/.../ServerDaemon.java | Jetty server integration for embedded WebSocket support |
| server/src/main/java/.../ManagementServerImpl.java | Management server capabilities and configuration updates |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| public class LogsWebSessionTokenCryptoUtil { | ||
| private static final String ALGORITHM = "AES"; | ||
| private static final String TRANSFORMATION = "AES"; |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weak encryption: Using AES in ECB mode (default when only "AES" is specified as transformation) is insecure as it doesn't use an initialization vector. Consider using "AES/GCM/NoPadding" or "AES/CBC/PKCS5Padding" with a random IV for better security.
| export const pollJobPlugin = { | ||
| install (app) { | ||
| function canViewLogs (logIds) { | ||
| console.log('canViewLogs', store.getters.features.logswebserverenabled, 'createLogsWebSession' in store.getters.apis, logIds, logIds && logIds.length > 0) |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Console.log statement should be removed from production code. This debug logging can expose sensitive information and impact performance.
| if (result.logids) { | ||
| allLogIds.push(...result.logids) | ||
| } | ||
| console.log('pollJobPlugin', result.logids, allLogIds) |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Console.log statement should be removed from production code. Debug logging should use proper logging mechanisms instead of console.log.
| } | ||
| }, | ||
| created () { | ||
| console.log('---------------', this.$route.meta.name) |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Console.log statement should be removed from production code. This appears to be debug code that was left in.
| CREATE TABLE IF NOT EXISTS `cloud`.`logs_web_session` ( | ||
| `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id of the session', | ||
| `uuid` varchar(40) NOT NULL COMMENT 'UUID generated for the session', | ||
| `filter` varchar(64) DEFAULT NULL COMMENT 'Filter keyword for the session', |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field name in the database schema is 'filter' (singular) but the converter is used for a List. This should be 'filters' (plural) to match the Java field name and be semantically correct. The SQL definition on line 38 should use filters instead of filter.
| `filter` varchar(64) DEFAULT NULL COMMENT 'Filter keyword for the session', | |
| `filters` varchar(64) DEFAULT NULL COMMENT 'Filter keywords for the session', |
| return null; | ||
| } | ||
| String keystoreFile = ServerPropertiesUtil.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_FILE); | ||
| String keystorePassword = ServerPropertiesUtil.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_FILE); |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong property key is being used. Line 127 should retrieve KEY_KEYSTORE_PASSWORD but it's retrieving KEY_KEYSTORE_FILE again. This will cause SSL context creation to fail as it will use the keystore file path as the password.
| String keystorePassword = ServerPropertiesUtil.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_FILE); | |
| String keystorePassword = ServerPropertiesUtil.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_PASSWORD); |
| if (StringUtils.isBlank(keystoreFile) || StringUtils.isBlank(keystorePassword)) { | ||
| throw new IllegalArgumentException("SSL is enabled but keystore file or password is not configured"); | ||
| } | ||
| if (Files.exists(Path.of(keystoreFile))) { |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inverted logic: the condition checks Files.exists(...) but the error message says "does not exist". This should be !Files.exists(Path.of(keystoreFile)) to correctly validate that the keystore file exists.
| if (Files.exists(Path.of(keystoreFile))) { | |
| if (!Files.exists(Path.of(keystoreFile))) { |
| <div | ||
| v-if="showRawLogs" | ||
| class="content" | ||
| v-html="webSocketData"> |
Copilot
AI
Nov 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential XSS vulnerability: HTML content is rendered using v-html without sanitization. The webSocketData contains unsanitized log data that could include malicious scripts. Consider using a library like DOMPurify to sanitize the HTML before rendering, or avoid using v-html altogether.
Signed-off-by: Abhishek Kumar <[email protected]>
Description
This PR introduces a WebSocket framework, enabling flexible configuration and management of WebSocket server and contexts.
The framework allows WebSocket services to run either as:
The first implementation built on this framework is the Logs Web Session, which allows ROOT administrators to securely stream and view logs in real-time via the UI, tied to specific API calls or actions.
Key Features
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?
How did you try to break this feature and the system with this change?