-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
add syslog function to wled #4664
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
Warning Rate limit exceeded@KrX3D has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 16 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThis change set introduces syslog support as a new debug output option in the WLED project. The syslog functionality is conditionally compiled using the Changes
Suggested reviewers
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 5
🧹 Nitpick comments (3)
wled00/syslog.h (2)
58-58
: Remove the unused test variable.This boolean member variable doesn't appear to be used anywhere in the implementation and seems to be leftover debug code.
- bool test = true;
60-60
: Consider a configurable buffer size.The fixed 128-byte buffer might be too small for complex log messages, especially when including timestamps and other syslog metadata. Consider making this configurable or handling message truncation more explicitly.
You could add a compile-time configuration option for the buffer size:
- char _buffer[128]; // Buffer for collecting characters + #ifndef SYSLOG_BUFFER_SIZE + #define SYSLOG_BUFFER_SIZE 128 + #endif + char _buffer[SYSLOG_BUFFER_SIZE]; // Buffer for collecting characterswled00/syslog.cpp (1)
135-149
: Add year to BSD syslog timestamp.The BSD format timestamp doesn't include the year, which could cause issues with log aggregation over year boundaries. Consider adding the year or a configuration option to include it.
if (ntpEnabled && ntpConnected) { // Month abbreviation const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - syslogUdp.printf("%s %2d %02d:%02d:%02d ", + syslogUdp.printf("%s %2d %04d %02d:%02d:%02d ", months[month(localTime) - 1], day(localTime), + year(localTime), hour(localTime), minute(localTime), second(localTime)); } else { // No valid time available - syslogUdp.print("Jan 01 00:00:00 "); + syslogUdp.print("Jan 01 1970 00:00:00 "); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
wled00/bus_manager.h
(1 hunks)wled00/cfg.cpp
(2 hunks)wled00/data/settings_sync.htm
(1 hunks)wled00/json.cpp
(2 hunks)wled00/set.cpp
(1 hunks)wled00/syslog.cpp
(1 hunks)wled00/syslog.h
(1 hunks)wled00/wled.cpp
(3 hunks)wled00/wled.h
(1 hunks)wled00/xml.cpp
(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
wled00/xml.cpp (2)
wled00/fcn_declare.h (4)
printSetFormCheckbox
(498-498)settingsScript
(421-421)printSetFormValue
(499-499)printSetFormValue
(500-500)wled00/util.cpp (6)
printSetFormCheckbox
(98-100)printSetFormCheckbox
(98-98)printSetFormValue
(101-103)printSetFormValue
(101-101)printSetFormValue
(108-110)printSetFormValue
(108-108)
🔇 Additional comments (16)
wled00/bus_manager.h (1)
26-35
: Well-implemented syslog integration in debug output mechanismThe conditional inclusion of syslog support is correctly ordered to prioritize syslog over network debug and serial output. This maintains backward compatibility while extending functionality.
wled00/data/settings_sync.htm (1)
240-292
: Well-structured Syslog UI sectionThe Syslog settings section is well-organized and follows the existing UI patterns. All relevant syslog parameters (enable/disable, host, port, protocol, facility, severity) are included with appropriate options.
wled00/set.cpp (1)
476-496
: Thorough parameter validation in syslog configuration handlerThe implementation correctly validates all syslog parameters before applying them, including checking for valid ranges for protocol, facility, and severity. The immediate initialization of the syslog client ensures changes take effect right away.
wled00/wled.cpp (3)
332-334
: Proper conditional for USB CDC debug outputGood modification to prevent disabling kernel messages when syslog is enabled, maintaining debug output capabilities when needed.
390-392
: Avoid TX pin allocation when using syslogCorrectly prevents allocating the hardware TX pin for debug output when syslog is enabled, avoiding potential pin conflicts.
425-430
: Clean syslog initialization during setupThe syslog client is properly initialized with the configured parameters and application name during setup. This ensures syslog is ready to use as soon as the system starts.
wled00/cfg.cpp (2)
539-547
: Good implementation of syslog configuration deserialization.The code adds proper support for reading syslog configuration from a JSON file, following the existing patterns used for other network services. All necessary syslog parameters are included and properly contained within the conditional compilation directive.
1064-1072
: Well-structured syslog configuration serialization.This implementation correctly writes syslog configuration to JSON, maintaining consistency with other configuration sections. Good use of conditional compilation to ensure the code is only included when syslog is enabled.
wled00/json.cpp (2)
302-305
: Good addition of syslog toggle via JSON API with feedback.The implementation correctly enables enabling/disabling syslog via the JSON API, with appropriate debug feedback. It follows the same pattern as the existing debug options, maintaining consistency.
787-789
: Consistent implementation of syslog flags in serialized info.This change properly updates the
os
flags to reflect syslog debug status in the serialized JSON output, following the same bit manipulation pattern used for other debug options. Excellent consistency with existing code.wled00/xml.cpp (2)
108-108
: Correct update to debug pin reservation logic.This change ensures the TX pin isn't needlessly reserved when syslog debugging is enabled, allowing it to be used for other purposes. Good attention to detail in working with the existing conditional compilation logic.
520-529
: Well-implemented syslog settings UI integration.The code adds all necessary UI elements for syslog configuration using existing helper functions. The toggle for hiding syslog settings when not compiled in follows the same pattern used for other optional features. Clean implementation.
wled00/wled.h (2)
967-992
: Well-structured syslog globals and configuration defaults.This implementation properly adds all necessary global variables and default settings for syslog functionality. The code is well-documented with helpful comments and follows the established patterns for configuration macros.
Each setting has a sensible default that can be overridden at compile time, and the naming conventions are consistent with the rest of the codebase.
993-993
: Correct modification to debug output selection chain.Changed
#ifdef
to#elif
to properly form a conditional chain with the new syslog section, ensuring only one debug output mechanism is selected.wled00/syslog.cpp (2)
104-111
:⚠️ Potential issuePrevent buffer overflow in write method.
The buffer check should use
>=
instead of<
to ensure there's always room for the null terminator.size_t SyslogPrinter::write(uint8_t c) { // Store in buffer regardless of connection status - if (_bufferIndex < sizeof(_buffer) - 1) { + if (_bufferIndex < sizeof(_buffer) - 1) { // Leave space for null terminator _buffer[_bufferIndex++] = c; } // If newline or buffer full, flush - if (c == '\n' || _bufferIndex >= sizeof(_buffer) - 1) { + if (c == '\n' || _bufferIndex >= sizeof(_buffer) - 1) { flushBuffer(); }Likely an incorrect or invalid review comment.
64-65
:❌ Incorrect review comment
Reduce dependency on global variables.
The code depends on global variables like
WLED_CONNECTED
andsyslogEnabled
which creates tight coupling and makes testing difficult. Consider passing these as parameters or having more self-contained logic.bool SyslogPrinter::resolveHostname() { - if (!WLED_CONNECTED || !syslogEnabled) return false; + // Check connection status locally - can be a class method or passed as parameter + bool isConnected = WLED_CONNECTED; + extern bool syslogEnabled; // Declare as extern if it must be used + if (!isConnected || !syslogEnabled) return false;
🏁 Script executed:
#!/bin/bash # Find where WLED_CONNECTED and syslogEnabled are defined echo "Searching for WLED_CONNECTED definition:" rg -A 2 -B 2 "define\s+WLED_CONNECTED" --no-ignore echo -e "\nSearching for syslogEnabled definition:" rg -A 2 -B 2 "bool\s+syslogEnabled" --no-ignoreLength of output: 816
Global connectivity and syslog flags are intended—no refactor needed
The use of WLED_CONNECTED and syslogEnabled here follows project conventions for runtime connectivity checks and feature toggles. Extracting them into method parameters would add complexity without improving clarity or testability.
- WLED_CONNECTED is a macro in wled00/wled.h that evaluates Wi-Fi/Ethernet status at runtime.
- syslogEnabled is declared as a WLED_GLOBAL bool in wled00/wled.h and controls syslog output globally.
If you need to isolate or mock these for unit tests, wrap them in a thin interface or use test‐level overrides rather than altering production code.
Likely an incorrect or invalid review comment.
i could just test it with the RFC 3164 format since my syslog server only works with this. The output of RAW should be the same as the Net Debug. Maybe someone could look through it since i wasnt really sure about: wled00/json.cpp:
I just took it from the WLED_DEBUG_HOST but im not sure what is does exactly. also i wansnt really sure where to put this in the setup part wled00/wled.cpp:
i just thought after Wifi would be good |
wled00/data/settings_sync.htm
Outdated
@@ -237,6 +237,59 @@ <h3>Serial</h3> | |||
</select><br> | |||
<i>Keep at 115200 to use Improv. Some boards may not support high rates.</i> | |||
</div> | |||
<h3>Syslog</h3> |
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.
this will add size to all builds, not acceptable for a debug function IMHO
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.
Yeah I would agree that allowing the user to select the facility and level is overkill
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.
this should solve that size problem when not using syslog:
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.
While that is an interesting approach to the problem, I still see no point in allowing the user to define nonsensical values. For example , WLED is not a printer, so what is the point of the user being able to select LPR as the facility.
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.
Hi i just added the full list i found online. So which should i remove/keep? i read somewhere that SYSLOG_LOCAL4 (LOCAL4) is normaly used for user output, thats why i also set is as default.
// Syslog facility codes
#define SYSLOG_KERN 0 // kernel messages
#define SYSLOG_USER 1 // user-level messages
#define SYSLOG_MAIL 2 // mail system
#define SYSLOG_DAEMON 3 // system daemons
#define SYSLOG_AUTH 4 // security/authorization messages
#define SYSLOG_SYSLOG 5 // messages generated internally by syslogd
#define SYSLOG_LPR 6 // line printer subsystem
#define SYSLOG_NEWS 7 // network news subsystem
#define SYSLOG_UUCP 8 // UUCP subsystem
#define SYSLOG_CRON 9 // clock daemon
#define SYSLOG_AUTHPRIV 10 // security/authorization messages (private)
#define SYSLOG_FTP 11 // FTP daemon
#define SYSLOG_NTP 12 // NTP subsystem (used in some systems)
#define SYSLOG_LOG_AUDIT 13 // log audit (used in some systems like Linux auditd)
#define SYSLOG_LOG_ALERT 14 // log alert
#define SYSLOG_CLOCK_DAEMON 15 // clock daemon (alternate)
#define SYSLOG_LOCAL0 16 // local use 0
#define SYSLOG_LOCAL1 17 // local use 1
#define SYSLOG_LOCAL2 18 // local use 2
#define SYSLOG_LOCAL3 19 // local use 3
#define SYSLOG_LOCAL4 20 // local use 4
#define SYSLOG_LOCAL5 21 // local use 5
#define SYSLOG_LOCAL6 22 // local use 6
#define SYSLOG_LOCAL7 23 // local use 7
i would think of least those ?
#define SYSLOG_USER 1 // user-level messages
#define SYSLOG_DAEMON 3 // system daemons
#define SYSLOG_LOCAL0 16 // local use 0
#define SYSLOG_LOCAL1 17 // local use 1
#define SYSLOG_LOCAL2 18 // local use 2
#define SYSLOG_LOCAL3 19 // local use 3
#define SYSLOG_LOCAL4 20 // local use 4
#define SYSLOG_LOCAL5 21 // local use 5
#define SYSLOG_LOCAL6 22 // local use 6
#define SYSLOG_LOCAL7 23 // local use 7
and maybe change th edefault to:
LOCAL0 is reserved for custom applications (i.e. it will never collide with kernel, mail, auth, etc.)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Add error state tracking to the SyslogPrinter class. - configurable buffer size. That way, anyone can -D SYSLOG_BUFFER_SIZE=256 (or larger) in their build flags to avoid silent truncation.
it sets or clears bits i.e. flags in os variaable, used in index.js |
Looks ok to me (untested), though it is a lot of code for somewhat useful feature. At least it is optional. |
to not wast size to all builds the html part will now be injected only when
is used: |
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.
Actionable comments posted: 0
🧹 Nitpick comments (3)
pio-scripts/inject_syslog_ui.py (3)
2-2
: Remove unused importThe
sys
module is imported but never used in the script.-import os, shutil, sys +import os, shutil🧰 Tools
🪛 Ruff (0.8.2)
2-2:
sys
imported but unusedRemove unused import:
sys
(F401)
120-121
: Use context manager for file operationsOpening files without a context manager can lead to resource leaks if exceptions occur.
- original = open(html_path, 'r', encoding='utf8').read() - modified = original + with open(html_path, 'r', encoding='utf8') as f: + original = f.read() + modified = original🧰 Tools
🪛 Ruff (0.8.2)
120-120: Use a context manager for opening files
(SIM115)
116-151
: Consider a more robust approach to detect completed injectionsThe script assumes that if a backup file exists, the injection has already been completed successfully. This might not be true if a previous run was interrupted or crashed.
Consider adding a more explicit indicator of successful injection, such as checking for the presence of the injected HTML content rather than just relying on the existence of the backup file.
# backup + inject only once if not os.path.exists(bak): print("Backing up and injecting Syslog UI...") shutil.copyfile(html_path, bak) try: with open(html_path, 'r', encoding='utf8') as f: original = f.read() modified = original # replace existing section if present if '<!-- SYSLOG-START -->' in modified and '<!-- SYSLOG-END -->' in modified: start = modified.index('<!-- SYSLOG-START -->') end = modified.index('<!-- SYSLOG-END -->') + len('<!-- SYSLOG-END -->') modified = ( modified[:start] + '<!-- SYSLOG-START -->\n' + SYSLOG_HTML + '\n<!-- SYSLOG-END -->' + modified[end:] ) else: # insert before last <hr> idx = modified.rfind('<hr>') if idx == -1: print("\033[41mCould not find <hr> to insert Syslog UI!\033[0m") return modified = ( modified[:idx] + '<!-- SYSLOG-START -->\n' + SYSLOG_HTML + '\n<!-- SYSLOG-END -->\n' + modified[idx:] ) with open(html_path, 'w', encoding='utf8') as f: f.write(modified) print("\033[42mSyslog UI injected successfully!\033[0m") except Exception as e: print(f"\033[41mError during injection: {e}\033[0m") + # Clean up the backup if injection failed + if os.path.exists(bak): + os.remove(bak) else: - print("Backup exists; assume already injected.") + # Verify that the injection was actually completed + with open(html_path, 'r', encoding='utf8') as f: + content = f.read() + if '<!-- SYSLOG-START -->' not in content or '<!-- SYSLOG-END -->' not in content: + print("Backup exists but injection markers not found. Re-injecting...") + os.remove(bak) # Remove the backup to force re-injection + inject_syslog_ui(source, target, env) # Recursive call to retry injection + else: + print("Backup exists and injection markers found; already injected.")🧰 Tools
🪛 Ruff (0.8.2)
120-120: Use a context manager for opening files
(SIM115)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
pio-scripts/inject_syslog_ui.py
(1 hunks)platformio.ini
(1 hunks)wled00/data/settings_sync.htm
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- platformio.ini
🚧 Files skipped from review as they are similar to previous changes (1)
- wled00/data/settings_sync.htm
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KrX3D
PR: wled/WLED#4664
File: wled00/syslog.cpp:50-51
Timestamp: 2025-04-26T12:51:04.972Z
Learning: In the WLED codebase, syslog configuration variables (syslogHost, syslogPort, syslogProtocol, syslogFacility, syslogSeverity) are defined as global variables in wled.h and are accessed directly in the SyslogPrinter implementation, rather than being class members.
🪛 Ruff (0.8.2)
pio-scripts/inject_syslog_ui.py
2-2: sys
imported but unused
Remove unused import: sys
(F401)
8-8: Undefined name env
(F821)
120-120: Use a context manager for opening files
(SIM115)
167-167: Undefined name env
(F821)
171-171: Undefined name env
(F821)
🔇 Additional comments (5)
pio-scripts/inject_syslog_ui.py (5)
32-32
: Consider handling placeholder valueThe
%SL_port%
placeholder is included in the HTML template. Ensure this is properly replaced during runtime by the WLED template system, otherwise users will see the literal placeholder.Is there a template replacement mechanism in WLED that handles these placeholders? If not, you may need to replace it with a default value or handle it in the script.
5-8
: LGTM for SCons environment handlingThe import and use of the SCons environment is correct. The static analysis tool incorrectly flagged
env
as undefined, but this is a standard SCons pattern.🧰 Tools
🪛 Ruff (0.8.2)
8-8: Undefined name
env
(F821)
80-114
: Well-structured build flag detection and state trackingThe build flag detection and state tracking logic is robust, with good handling of different flag formats and proper state persistence between builds.
152-165
: Effective restoration functionThe restoration function correctly handles cleaning up after the build, with proper file permission management and backup removal.
1-171
: Overall well-designed injection scriptThis script provides a clean solution for conditionally including the Syslog UI in the settings page. The approach of injecting at build time keeps the source HTML clean while allowing the feature to be conditionally enabled. The colored console output and detailed progress messages are helpful for debugging.
🧰 Tools
🪛 Ruff (0.8.2)
2-2:
sys
imported but unusedRemove unused import:
sys
(F401)
8-8: Undefined name
env
(F821)
120-120: Use a context manager for opening files
(SIM115)
167-167: Undefined name
env
(F821)
171-171: Undefined name
env
(F821)
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.
Actionable comments posted: 0
🧹 Nitpick comments (3)
pio-scripts/inject_syslog_ui.py (3)
18-22
: Consider adding directory creation check before writing state fileThe
set_syslog_state
function assumes the directory structure exists. If the script runs in a clean environment or the directory is missing, this could fail.def set_syslog_state(project_dir, enabled): state_file = os.path.join(project_dir, "wled00/data/.syslog_state") + os.makedirs(os.path.dirname(state_file), exist_ok=True) # Ensure directory exists with open(state_file, 'w') as f: f.write("1" if enabled else "0")
158-162
: Add retry limit to prevent potential infinite recursionThe current implementation uses recursion without a limit when re-injecting content with missing markers, which could lead to infinite recursion if there's a persistent issue.
- if '<!-- SYSLOG-START -->' not in content or '<!-- SYSLOG-END -->' not in content: - print("Backup exists but SYSLOG markers missing—forcing re-injection.") - os.remove(bak) - inject_syslog_ui(source, target, env) + if '<!-- SYSLOG-START -->' not in content or '<!-- SYSLOG-END -->' not in content: + print("Backup exists but SYSLOG markers missing—forcing re-injection.") + os.remove(bak) + # Pass a retry parameter to prevent infinite recursion + if 'retry_count' not in globals(): + global retry_count + retry_count = 0 + if retry_count < 3: + retry_count += 1 + inject_syslog_ui(source, target, env) + retry_count = 0 # Reset on success + else: + print("\033[41mToo many retry attempts. Manual intervention required.\033[0m") + retry_count = 0 # Reset for next runAlternatively, modify the function signature to accept a retry parameter:
def inject_syslog_ui(source, target, env, retry_count=0): # ... existing code ... # When recursing: if retry_count < 3: inject_syslog_ui(source, target, env, retry_count + 1) else: print("\033[41mToo many retry attempts. Manual intervention required.\033[0m")
119-122
: Consider handling large files more efficientlyLoading the entire file into memory could be problematic for very large HTML files. Consider reading and processing the file in chunks for better memory efficiency.
For most WLED installations this won't be an issue as the HTML files are relatively small, but it's a good practice to handle files more efficiently, especially in build scripts that might run on resource-constrained systems.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
pio-scripts/inject_syslog_ui.py
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KrX3D
PR: wled/WLED#4664
File: wled00/syslog.cpp:50-51
Timestamp: 2025-04-26T12:51:04.972Z
Learning: In the WLED codebase, syslog configuration variables (syslogHost, syslogPort, syslogProtocol, syslogFacility, syslogSeverity) are defined as global variables in wled.h and are accessed directly in the SyslogPrinter implementation, rather than being class members.
🪛 Ruff (0.8.2)
pio-scripts/inject_syslog_ui.py
8-8: Undefined name env
(F821)
180-180: Undefined name env
(F821)
184-184: Undefined name env
(F821)
🔇 Additional comments (4)
pio-scripts/inject_syslog_ui.py (4)
32-32
: Note about placeholder variableThe
%SL_port%
placeholder is used here, but this script doesn't replace it with an actual value. This appears to be an intentional design where the placeholder will be processed by WLED's template system when the HTML is served.
88-90
: LGTM: Good handling of build flagsGood approach for handling build flags that might be provided either as a list or a string.
174-177
: Good file permission handlingSetting the chmod before copying is a nice touch that ensures the file can be written even if permissions were changed.
1-184
: Overall feedback on inject_syslog_ui.pyThis is a well-structured build script that intelligently handles Syslog UI injection. The approach of backing up the original file, tracking state changes, and verifying markers is robust. The color-coded console output also makes it easy to track what's happening during the build process.
The script correctly integrates with the PlatformIO build system using SCons hooks and handles different build scenarios appropriately.
🧰 Tools
🪛 Ruff (0.8.2)
8-8: Undefined name
env
(F821)
180-180: Undefined name
env
(F821)
184-184: Undefined name
env
(F821)
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.
Actionable comments posted: 0
🧹 Nitpick comments (3)
pio-scripts/inject_syslog_ui.py (3)
155-156
: Add explicit handling for mismatched markers.Consider adding specific handling for the case where one marker exists but the other doesn't (incomplete previous run). Currently, you check if either marker is missing, but you might want to log which specific marker is missing for easier debugging.
- if '<!-- SYSLOG-START -->' not in content or '<!-- SYSLOG-END -->' not in content: - print("Backup exists but SYSLOG markers missing—forcing re-injection.") + if '<!-- SYSLOG-START -->' not in content and '<!-- SYSLOG-END -->' not in content: + print("Backup exists but both SYSLOG markers missing—forcing re-injection.") + elif '<!-- SYSLOG-START -->' not in content: + print("Backup exists but SYSLOG-START marker missing—forcing re-injection.") + elif '<!-- SYSLOG-END -->' not in content: + print("Backup exists but SYSLOG-END marker missing—forcing re-injection.")
159-162
: Consider adding delay between retry attempts.When retrying the injection after failure, consider adding a small delay between attempts to avoid potential file system contention. This could improve reliability when retrying rapidly.
# only retry up to 3 times if retry_count < 3: + # Add a small delay before retrying + import time + time.sleep(0.5 * (retry_count + 1)) # Increasing delay with each retry inject_syslog_ui(source, target, env, retry_count + 1) else: print("\033[41mToo many retry attempts. Manual intervention required.\033[0m")
1-2
: Consider adding a brief docstring for maintainability.While the code is well-structured and self-explanatory, adding a brief docstring at the top of the file would improve maintainability and help future developers understand the script's purpose.
# pio-scripts/inject_syslog_ui.py +""" +PlatformIO build script to conditionally inject Syslog UI elements into the settings HTML file. + +This script: +1. Injects Syslog UI elements when WLED_ENABLE_SYSLOG is defined in build flags +2. Restores the original HTML file after build completion +3. Tracks state between builds to force UI rebuilds when necessary +""" import os, shutil
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
pio-scripts/inject_syslog_ui.py
(1 hunks)wled00/xml.cpp
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- wled00/xml.cpp
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KrX3D
PR: wled/WLED#4664
File: wled00/syslog.cpp:50-51
Timestamp: 2025-04-26T12:51:04.972Z
Learning: In the WLED codebase, syslog configuration variables (syslogHost, syslogPort, syslogProtocol, syslogFacility, syslogSeverity) are defined as global variables in wled.h and are accessed directly in the SyslogPrinter implementation, rather than being class members.
🪛 Ruff (0.8.2)
pio-scripts/inject_syslog_ui.py
8-8: Undefined name env
(F821)
181-181: Undefined name env
(F821)
185-185: Undefined name env
(F821)
🔇 Additional comments (7)
pio-scripts/inject_syslog_ui.py (7)
1-6
: Well-structured script with clear imports and environment handling.The script properly imports necessary modules and retrieves the PlatformIO environment. The organization is clean and follows best practices for PlatformIO build scripts.
10-22
: Good state tracking implementation for build-to-build persistence.The state tracking functions are well-implemented with proper file handling and error cases. The approach of using a hidden state file to track changes between builds is elegant and efficient.
24-75
: Well-structured HTML for the Syslog UI configuration.The HTML definition provides a comprehensive UI for configuring all syslog parameters (protocol, facility, severity, etc.) with appropriate input types and validation.
87-87
: Robust build flag detection handles both spacing variants.Good job checking for both
-D WLED_ENABLE_SYSLOG
and-DWLED_ENABLE_SYSLOG
variants in the build flags. This ensures the script works correctly regardless of how the flag is specified.
94-101
: Effective change detection to force UI rebuilds when needed.The script intelligently detects state changes between builds and touches the HTML file to force a rebuild when necessary. This ensures the UI stays in sync with the build configuration.
166-179
: Good restoration logic with permission handling.The restoration function correctly handles file permissions (chmod) before copying the backup, which prevents potential permission-related errors. The function is also safely guarded by checking for the backup file's existence.
180-185
: Excellent build system integration.The script properly integrates with the PlatformIO build system by registering a post-action for cleanup and conditionally running the injection only on full builds. This ensures the HTML file is restored to its original state after the build completes.
🧰 Tools
🪛 Ruff (0.8.2)
181-181: Undefined name
env
(F821)
185-185: Undefined name
env
(F821)
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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
pio-scripts/inject_syslog_ui.py (2)
97-97
: Consider using regex for more robust build flag detection.The current approach checks for two specific patterns of the define flag. A regex approach might be more robust against variations in spacing or other flag formats.
- has_syslog = ("-D WLED_ENABLE_SYSLOG" in build_flags or "-DWLED_ENABLE_SYSLOG" in build_flags) + import re + has_syslog = bool(re.search(r'-D\s*WLED_ENABLE_SYSLOG', build_flags))
155-160
: Consider more specific exception handling for file operations.The current exception handling is generic. It might be beneficial to catch specific exceptions related to file operations separately from other potential issues.
- except Exception as e: - print(f"\033[41mError during injection: {e}\033[0m") - # injection failed → remove backup so we'll retry next time - if os.path.exists(bak): - os.remove(bak) + except (IOError, OSError) as e: + print(f"\033[41mFile operation error during injection: {e}\033[0m") + # injection failed → remove backup so we'll retry next time + if os.path.exists(bak): + os.remove(bak) + except Exception as e: + print(f"\033[41mUnexpected error during injection: {e}\033[0m") + # injection failed → remove backup so we'll retry next time + if os.path.exists(bak): + os.remove(bak)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
pio-scripts/inject_syslog_ui.py
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KrX3D
PR: wled/WLED#4664
File: wled00/syslog.cpp:50-51
Timestamp: 2025-04-26T12:51:04.972Z
Learning: In the WLED codebase, syslog configuration variables (syslogHost, syslogPort, syslogProtocol, syslogFacility, syslogSeverity) are defined as global variables in wled.h and are accessed directly in the SyslogPrinter implementation, rather than being class members.
🪛 Ruff (0.8.2)
pio-scripts/inject_syslog_ui.py
18-18: Undefined name env
(F821)
194-194: Undefined name env
(F821)
198-198: Undefined name env
(F821)
🔇 Additional comments (7)
pio-scripts/inject_syslog_ui.py (7)
1-19
: Well-structured script with clear purpose and good documentation.The file has a clear header, descriptive docstring, and appropriate imports. The detection of full vs. partial builds is a good optimization to avoid unnecessary processing.
🧰 Tools
🪛 Ruff (0.8.2)
18-18: Undefined name
env
(F821)
21-32
: Good implementation of state tracking between builds.The state tracking functions are well-implemented with proper file handling and error management. This approach ensures UI rebuilds only happen when the syslog state changes.
33-85
: Complete and well-structured HTML template for Syslog configuration.The HTML template includes all necessary configuration options for syslog: enable/disable toggle, host, port, protocol selection, facility, and severity levels. The dropdown options cover all standard syslog facilities and severity levels.
126-154
: Good implementation of HTML injection with marker-based replacement.The code properly handles both cases: replacing content between existing markers or inserting at a strategic location. The approach is robust and maintainable.
163-177
: Robust verification and retry mechanism for injection failures.The code verifies that markers are actually present in the file and implements a retry mechanism with incremental delays. This helps recover from potential race conditions or transient file system issues.
179-192
: Clean implementation of restore function with proper permission handling.The restore function properly handles file permissions before copying, which prevents potential permission-related errors. The backup file is correctly removed after restoration.
193-198
: Good integration with PlatformIO build process.The script properly integrates with the PlatformIO build process by registering the restore function as a post-action and conditionally running the injection only on full builds.
🧰 Tools
🪛 Ruff (0.8.2)
194-194: Undefined name
env
(F821)
198-198: Undefined name
env
(F821)
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.
Please remove any configuration options that do not add value
WLED Syslog Component
Overview
Adds a SyslogPrinter to the WLED core that captures all debug-print output and forwards it—over UDP—to a remote syslog server, in any of three standard formats (BSD/RFC3164, RFC5424 or raw text). This makes it easy to integrate WLED logs into your existing centralized logging/monitoring infrastructure.
How it works
1. Print interception & buffering
flushBuffer()
trims any trailing\r
, null-terminates, and sends the complete message over UDP.2. Hostname resolution
resolveHostname()
does a DNS lookup viaWiFi.hostByName()
(orETH.hostByName()
on Ethernet builds) and caches the resulting IP.3. Message formatting & UDP send
PRI
) =(facility << 3) | severity
.WiFiUDP
to emit one packet per message.In RAW mode the message payload is same as WLED’s existing NetDebug output—without any PRI, timestamp or header added.
Example log output
Usage
Build-time configuration (platform.ini)
Enable debug output and syslog in your
platform.ini
:Runtime configuration via GUI
In the WLED web interface, go to Settings → Sync (at the bottom) to enable/disable syslog and adjust:
You can also toggle syslog on/off under Info & Debug on the main page.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation