{"id":28034866,"url":"https://github.com/niklaskarel/qt-multiclient-logger","last_synced_at":"2026-04-25T12:35:25.783Z","repository":{"id":291901027,"uuid":"979150128","full_name":"niklaskarel/qt-multiclient-logger","owner":"niklaskarel","description":"Qt-based multi-client TCP logger for structured JSON messages with real-time GUI, severity-aware handling, and modular logging logic. Designed to simulate communication with independent system modules.","archived":false,"fork":false,"pushed_at":"2025-10-21T23:36:02.000Z","size":8957,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-22T01:21:35.385Z","etag":null,"topics":["cpp","embedded-systems","gui","logger","multithreading","networking","qt","qtwidgets","real-time","tcp"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/niklaskarel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-07T04:31:39.000Z","updated_at":"2025-10-21T23:36:05.000Z","dependencies_parsed_at":"2025-06-03T00:54:18.661Z","dependency_job_id":"d7ed2925-4065-49d8-8d95-dae13a9057e7","html_url":"https://github.com/niklaskarel/qt-multiclient-logger","commit_stats":null,"previous_names":["niklaskarel/qt-multiclient-logger"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/niklaskarel/qt-multiclient-logger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niklaskarel%2Fqt-multiclient-logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niklaskarel%2Fqt-multiclient-logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niklaskarel%2Fqt-multiclient-logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niklaskarel%2Fqt-multiclient-logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/niklaskarel","download_url":"https://codeload.github.com/niklaskarel/qt-multiclient-logger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/niklaskarel%2Fqt-multiclient-logger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32262801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","embedded-systems","gui","logger","multithreading","networking","qt","qtwidgets","real-time","tcp"],"created_at":"2025-05-11T11:59:57.965Z","updated_at":"2026-04-25T12:35:25.773Z","avatar_url":"https://github.com/niklaskarel.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Qt Multi-Client TCP Logger\n\nThis ongoing project is a Qt-based application that functions as a TCP server designed to handle up to three concurrent clients (modules), each sending structured JSON messages over TCP. It features real-time message logging, GUI-based controls, error-handling mechanisms tailored for critical communication systems or monitoring tools and Writer that currently writes to a single session log file, with module identifiers included in each entry for traceability; advanced options are part of the ongoing development roadmap. It also displays a basic graph using QCustomPlot of the incoming data points after some basic thresholding and filtering.\n\n## Features\n\n- Supports up to 3 TCP clients simultaneously\n- Parses JSON messages with `clientId`, `type`, `message`, and `timestamp`\n- GUI with real-time log view, control buttons for stopping individual modules and graph that shows sensor data for each client using a moving average of X values in 2D and X and Y values in 3D in relation to time.\n  - 2D: QCustomPlot (default)\n  - 3D: OpenGL (experimental)\n- Settings dialog to configure: Port number, IP address, Plotting window duration, Thresholds for incoming sensor values, Flush interval and buffer size\n- Graceful disconnection and cleanup on critical failures\n- Python script included to simulate real client traffic with randomized message generation.\n- Logger system with bounded message queue and severity-based message discarding\n- Writer that writes the log messages to separate txt files in a predefined directory\n\n## UI Preview\n\nThis is a real-time log viewer showing messages from three simulated modules over TCP.\nThe GUI reacts to message severity—buttons are automatically disabled after CRITICAL messages.\n\n![Screenshot of the main window of the Qt Logger GUI](Main_window.png)\n![Screenshot of the settings dialog for connection settings](Settings_dialog_connection_settings.png)\n![Screenshot of the settings dialog for data settings](Settings_dialog_data_settings.png)\n![Screenshot of the settings dialog for logger settings](Settings_dialog_logger_settings.png)\n\n## Message Format (JSON)\n```json\n{\n  \"client\": 1,\n  \"type\": \"INFO\", // INFO, WARNING, ERROR, CRITICAL, DATA\n  \"message\": \"Module started\",\n  \"timestamp\": \"2025-05-06 06:29:51\"\n}\n```\n\n## Critical Behavior Logic\n- If **module 3** sends a CRITICAL message → all modules are disconnected and the application stops.\n- If **module 1 or 2** sends CRITICAL message → only that module is stopped.\n- If **module 3** sends a ERROR message → all three stop Module buttons are activated and the user can manually stop the modules.\n- If **module 1 or 2** sends ERROR message → only that module\"s stop button is activated.\n\n## Build Instructions\n1. Install Qt 6.8.3 (must include OpenGL and OpenGLWidgets modules) and CMake 3.28+\n2. `cmake -S . -B build`\n3. `cmake --build build`\n4. `cd build`\n5. run the executable\n6. On Windows, ensure `glu32.lib` is available. On Linux, ensure OpenGL headers and libraries are installed (`libgl1-mesa-dev`, `libglu1-mesa-dev`).\n\n## Code Highlights\n\n### Architecture \u0026 Core Design\n- Modular structure separating concerns across:\n  - `Controller` — orchestrates module startup/shutdown, thread assignment, and connects all components\n  - `EventReceiver` — manages TCP socket server, parses incoming JSON messages, detects CRITICAL state\n  - `Logger` — filters and routes incoming messages based on type and module, emits logging signals\n  - `Writer` — saves logs to disk with structured CSV formatting, handles safe file lifecycle\n  - `MainWindow` — interactive Qt Widgets UI for live monitoring, user control, and data display\n  - `Settings` — encapsulates runtime configuration (thresholds, ports, etc.), editable via GUI\n  - `DataProcessor` — calculates rolling statistics and alerts for visual and logical analysis\n  - `PythonProcessManager` — manages lifecycle of the Python-based client simulators\n- Uses modern C++ practices:\n  - `std::unique_ptr` for scoped ownership of threads and components\n  - `QPointer\u003cQTcpSocket\u003e` to ensure signal safety across asynchronous lifetimes\n- All cross-thread invocations use `QMetaObject::invokeMethod(..., Qt::BlockingQueuedConnection)` for synchronization\n- Non-blocking design across all slots; designed for long-running stable execution\n\n### Networking (EventReceiver)\n- Accepts multiple TCP clients using `QTcpServer`, identifies clients by a JSON `client` field\n- Tracks client sockets in `QMap\u003cuint32_t, QPointer\u003cQTcpSocket\u003e\u003e`\n- Sets up `readyRead`, `disconnected`, and `destroyed` handlers with `QPointer`-safe lambdas\n- Parses incoming JSON messages robustly:\n  - Validates client ID, type field, and timestamp\n  - Emits structured `EventMessage` instances\n  - Emits error messages for malformed input\n- Handles CRITICAL messages:\n  - Client 3: triggers global shutdown of all clients\n  - Clients 1 and 2: disconnects only the corresponding socket\n- Uses deferred deletion via `deleteLater()` and fallback `abort()` with `QTimer`\n\n### Message Handling (Logger)\n- Buffers incoming `EventMessage` entries with a configurable max size\n- Prioritizes `CRITICAL` and `ERROR` messages over lower-severity ones\n- Periodically flushes one message at a time via a `QTimer`\n- Passes flushed messages to Writer for persistence and to UI for live display\n- Adjusts flush rate dynamically based on application state\n\n### File Persistence (Writer)\n- Writes flushed messages to a timestamped `.txt` log file in a `logs/` directory\n- Each file is named as: `logger_\u003ctimestamp\u003e.txt`\n- Runs as a separate thread using `QThread` to ensure non-blocking I/O\n- Supports graceful termination via `finish()` and `wait()`\n\n### Data Processing (DataProcessor)\n- Calculates averages of every 5 values of the recent `DATA` messages per client\n- Routes processed values back to the main window for visualization\n\n### UI \u0026 Visualization (MainWindow)\n\n- Built with Qt Widgets and `QCustomPlot` for 2D real-time plotting\n- Displays logs color-coded by message type (INFO, WARNING, etc.)\n- Shows message content, timestamp, and client ID in a scrollable text area\n- Includes three Stop Logger buttons (one per client)\n- Supports `SettingsDialog` for buffer/flush control\n- Planned OpenGL extension (toggleable via radio buttons) to visualize:\n  - X: Raw sensor value\n  - Y: Canonicalized value (0–100)\n  - Z: Timestamp (OpenGL time-axis) (this is an ongoing change)\n\n### Settings (SettingsDialog)\n\n- Loads and saves user-defined settings using `QSettings`\n- Provides UI to modify:\n  - Logger flush interval\n  - Max message ring buffer size\n  - TCP ip address and port\n  - low and upper threshold for the filtering of the data in the graph\n  - window time of how many seconds will the graph show data\n\n\n## License\nMIT License (or specify yours)\n\n## Known issues\n\u003cdel\u003e\nIf modules**1 or 2**trigger a**CRITICAL** error, their sockets are closed.\nLater, if either:\n- module **3** sends a CRITICAL error (which tries to close all sockets again), or\n- the user closes the application (triggering destructor cleanup),\n then a **segmentation fault occurs** due to double-closing / double-deleting sockets.\nThis will be addressed in a future refactor of the socket shutdown logic.\u003c/del\u003e Fixed on 22.10.2025\n\n~~As of 13.06.2025 The application crashes when the python script generates a critical error for module 3~~\nFixed on 17.06.2025: Crash caused by improper deletion of client sockets on CRITICAL messages from module 3 was resolved.\n~~18.06.2025 Python proccess crashed when closing after a critical error in module 3.~~ Fixed\n~~INFO, WARNING, ERROR messages are not displayed after a few seconds on the logger, only the DATA messages.~~ Fixed on 21.06.2025\n\n---\n\n**Author:** Nikolaos Laskarelias\n\nFeel free to adapt, extend, or integrate this logger with your own backend or UI requirements.\n\n### TODO\n\n## Technical Improvements\n- Explore alternative communication protocols between frontend and backend, including:\n  - **WebSocket:** for real-time bidirectional message streaming (client ↔ server)\n  - **REST API:** for structured control, querying, and persistent log submission\n  - This includes manual JSON serialization/parsing and potential integration with PostgreSQL for durable log storage.\n- ~~Refactor EventReceiver to use QThread per client socket to improve stability and avoid crashes due to cross-thread access or unexpected deletions. Current design using QTcpServer in the main thread is fragile under high traffic~~ Done in 21.06.2025\n- Refactor Logger to run in its own thread to handle high-throughput message processing.\n- ~~Current architecture is functional but has tightly coupling between UI and control logic. Refactoring planned to introduce an EventController for better separation of concerns (UI vs. logic vs. transport).~~ Done in 07.07.2025\n- ~~Extend visualization support with an **OpenGL-based 3D graph mode** to render the new dual-value message format (`X` for raw input, `Y` for canonicalized [0–100] scale) over time; toggleable via radio buttons to switch between 2D (`QCustomPlot`) and 3D (OpenGL) modes. (ongoing change as of 07.07.2025)~~ (implemented on 16.07.2025)\n- Add QCustomPlot as a dynamic library and not as a static as it is increasing the time for building.\n- Add support for **MQTT** as a communication method between system components, using a publish/subscribe architecture via an MQTT broker\n- Add second way of messaging formating (f.e **XML**, **Protobuf**)\n- Add a settings panel to adjust:\n  - Give the user the possibility to chose a communication method between TCPSocket, WebSocket or REST\n  - Give the user the possibility to chose message formating\n\n\n## Functional Extensions\n- Support WebSocket or UDP modes for remote message streaming\n- Graphical message statistics (e.g., number of errors)\n- Authentication/token for sender script (basic security)\n- Use JSON schema validation for incoming messages\n\n## Testing\n- Add unit tests for `Logger` and `Writer `class\n- Stress-test script: burst of messages at 5ms intervals\n\n## Deployment\n- Bundle release with standalone Python\n- Add `.bat` or `.sh` launcher script for convenience\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniklaskarel%2Fqt-multiclient-logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fniklaskarel%2Fqt-multiclient-logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniklaskarel%2Fqt-multiclient-logger/lists"}