diff --git a/pio-scripts/inject_syslog_ui.py b/pio-scripts/inject_syslog_ui.py
new file mode 100644
index 0000000000..08077cf636
--- /dev/null
+++ b/pio-scripts/inject_syslog_ui.py
@@ -0,0 +1,153 @@
+# 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, re, shutil
+from SCons.Script import Import
+
+Import("env")
+
+# detect full vs. partial compile
+is_full_build = env.get("PIOENV") is not None
+
+# Track the state between builds
+def get_previous_syslog_state(project_dir):
+ state_file = os.path.join(project_dir, "wled00/data/.syslog_state")
+ if os.path.exists(state_file):
+ with open(state_file, 'r') as f:
+ return f.read().strip() == "1"
+ return None # None means no previous state recorded
+
+def set_syslog_state(project_dir, enabled):
+ state_file = os.path.join(project_dir, "wled00/data/.syslog_state")
+ with open(state_file, 'w') as f:
+ f.write("1" if enabled else "0")
+
+# This is the HTML we want to inject
+SYSLOG_HTML = """
Syslog
+
+ Enable Syslog:
+ Host:
+ Port:
+
"""
+
+def inject_syslog_ui(source, target, env, retry_count=0):
+ print("\033[44m==== inject_syslog_ui.py (PRE BUILD) ====\033[0m")
+ if not is_full_build:
+ print("\033[43mNot a full build, skipping Syslog UI operations.\033[0m")
+ return
+
+ # Check for the define in BUILD_FLAGS
+ build_flags = env.get("BUILD_FLAGS", "")
+ if isinstance(build_flags, list):
+ build_flags = " ".join(build_flags)
+ has_syslog = bool(re.search(r'-D\s*WLED_ENABLE_SYSLOG\b', build_flags))
+
+ project_dir = env.subst("$PROJECT_DIR")
+ html_path = os.path.join(project_dir, "wled00/data/settings_sync.htm")
+ bak = html_path + ".backup"
+
+ # Detect state change → touch to force rebuild
+ prev = get_previous_syslog_state(project_dir)
+ if prev is not None and prev != has_syslog:
+ print(f"\033[43mSYSLOG state changed from {prev} to {has_syslog}, forcing UI rebuild.\033[0m")
+ if os.path.exists(html_path):
+ with open(html_path, 'a'):
+ os.utime(html_path, None)
+
+ set_syslog_state(project_dir, has_syslog)
+
+ if not has_syslog:
+ print("\033[43mWLED_ENABLE_SYSLOG not defined, skipping injection.\033[0m")
+ # restore if backup exists
+ if os.path.exists(bak):
+ print("Restoring original file from backup...")
+ shutil.copy2(bak, html_path)
+ os.remove(bak)
+ return
+
+ # 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 the single comment with HTML
+ if '' in modified:
+ modified = modified.replace('', SYSLOG_HTML)
+ else:
+ # insert before last
+ idx = modified.rfind('')
+ if idx == -1:
+ print("\033[41mCould not find to insert Syslog UI!\033[0m")
+ # Clean up backup since injection failed
+ if os.path.exists(bak):
+ os.remove(bak)
+ return
+ modified = (
+ modified[:idx]
+ + SYSLOG_HTML + '\n'
+ + modified[idx:]
+ )
+
+ with open(html_path, 'w', encoding='utf8') as f:
+ f.write(modified)
+ print("\033[42mSyslog UI injected successfully!\033[0m")
+
+ 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)
+ else:
+ print("Backup exists; assume already injected.")
+ # verify that SYSLOG markers really are in the file
+ with open(html_path, 'r', encoding='utf8') as f:
+ content = f.read()
+ if '
Syslog
' not in content:
+ print("Backup exists but SYSLOG markers missing—forcing re-injection.")
+ os.remove(bak)
+ # 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")
+ else:
+ print("Backup exists and markers found; already injected.")
+
+def restore_syslog_ui(source, target, env):
+ print("\033[44m==== inject_syslog_ui.py (POST BUILD) ====\033[0m")
+ project_dir = env.subst("$PROJECT_DIR")
+ html_path = os.path.join(project_dir, "wled00/data/settings_sync.htm")
+ bak = html_path + ".backup"
+
+ # restore only if backup file is present
+ if os.path.exists(bak):
+ print("Restoring original file from backup...")
+ shutil.copy2(bak, html_path)
+ os.remove(bak)
+
+# always register the post-action on checkprogsize so it runs every build
+env.AddPostAction("checkprogsize", restore_syslog_ui)
+
+# only inject on full build
+if is_full_build:
+ inject_syslog_ui(None, None, env)
\ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
index a7485244cd..8cee7ea9b8 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -115,6 +115,7 @@ extra_scripts =
post:pio-scripts/strip-floats.py
pre:pio-scripts/user_config_copy.py
pre:pio-scripts/load_usermods.py
+ pre:pio-scripts/inject_syslog_ui.py
pre:pio-scripts/build_ui.py
; post:pio-scripts/obj-dump.py ;; convenience script to create a disassembly dump of the firmware (hardcore debugging)
diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h
index 0570cc2d6c..b72560cddd 100644
--- a/wled00/bus_manager.h
+++ b/wled00/bus_manager.h
@@ -24,7 +24,10 @@ make_unique(Args&&... args)
#endif
// enable additional debug output
-#if defined(WLED_DEBUG_HOST)
+#if defined(WLED_ENABLE_SYSLOG)
+ #include "syslog.h"
+ #define DEBUGOUT Syslog
+#elif defined(WLED_DEBUG_HOST)
#include "net_debug.h"
#define DEBUGOUT NetDebug
#else
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index fa0397fc65..5e06944920 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -536,6 +536,13 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(hueIP[i], if_hue_ip[i]);
#endif
+#ifdef WLED_ENABLE_SYSLOG
+ JsonObject if_syslog = interfaces["syslog"];
+ CJSON(syslogEnabled, if_syslog["en"]);
+ getStringFromJson(syslogHost, if_syslog[F("host")], 33);
+ CJSON(syslogPort, if_syslog["port"]);
+#endif
+
JsonObject if_ntp = interfaces[F("ntp")];
CJSON(ntpEnabled, if_ntp["en"]);
getStringFromJson(ntpServerName, if_ntp[F("host")], 33); // "1.wled.pool.ntp.org"
@@ -1051,6 +1058,13 @@ void serializeConfig(JsonObject root) {
}
#endif
+#ifdef WLED_ENABLE_SYSLOG
+ JsonObject if_syslog = interfaces.createNestedObject("syslog");
+ if_syslog["en"] = syslogEnabled;
+ if_syslog["host"] = syslogHost;
+ if_syslog["port"] = syslogPort;
+#endif
+
JsonObject if_ntp = interfaces.createNestedObject("ntp");
if_ntp["en"] = ntpEnabled;
if_ntp[F("host")] = ntpServerName;
diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm
index ca6c0fb59c..983d0a6cbc 100644
--- a/wled00/data/settings_sync.htm
+++ b/wled00/data/settings_sync.htm
@@ -237,6 +237,7 @@
Serial
Keep at 115200 to use Improv. Some boards may not support high rates.
+
diff --git a/wled00/json.cpp b/wled00/json.cpp
index c09b543f1c..ce9b3e7b8c 100644
--- a/wled00/json.cpp
+++ b/wled00/json.cpp
@@ -298,7 +298,11 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
bool stateResponse = root[F("v")] | false;
#if defined(WLED_DEBUG) && defined(WLED_DEBUG_HOST)
- netDebugEnabled = root[F("debug")] | netDebugEnabled;
+ netDebugEnabled = root[F("debug")] | netDebugEnabled;
+ #elif defined(WLED_DEBUG) && defined(WLED_ENABLE_SYSLOG)
+ syslogEnabled = root[F("debug")] | syslogEnabled;
+ configNeedsWrite = true;
+ DEBUG_PRINTF_P(PSTR("Syslog: %s\n"), syslogEnabled ? PSTR("ENABLED") : PSTR("DISABLED") );
#endif
bool onBefore = bri;
@@ -781,6 +785,9 @@ void serializeInfo(JsonObject root)
#ifdef WLED_DEBUG_HOST
os |= 0x0100;
if (!netDebugEnabled) os &= ~0x0080;
+ #elif defined(WLED_ENABLE_SYSLOG)
+ os |= 0x0100;
+ if (!syslogEnabled) os &= ~0x0080;
#endif
#endif
#ifndef WLED_DISABLE_ALEXA
diff --git a/wled00/set.cpp b/wled00/set.cpp
index 725875023e..1db411af47 100644
--- a/wled00/set.cpp
+++ b/wled00/set.cpp
@@ -472,6 +472,19 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
t = request->arg(F("BD")).toInt();
if (t >= 96 && t <= 15000) serialBaud = t;
updateBaudRate(serialBaud *100);
+
+ #ifdef WLED_ENABLE_SYSLOG
+ syslogEnabled = request->hasArg(F("SL_en"));
+ strlcpy(syslogHost, request->arg(F("SL_host")).c_str(), sizeof(syslogHost));
+
+ t = request->arg(F("SL_port")).toInt();
+ if (t > 0) syslogPort = t;
+
+ Syslog.begin(syslogHost, syslogPort,
+ syslogFacility, syslogSeverity, syslogProtocol);
+
+ Syslog.setAppName("WLED");
+ #endif
}
//TIME
diff --git a/wled00/syslog.cpp b/wled00/syslog.cpp
new file mode 100644
index 0000000000..384a937e4e
--- /dev/null
+++ b/wled00/syslog.cpp
@@ -0,0 +1,195 @@
+#include "wled.h"
+#ifdef WLED_ENABLE_SYSLOG
+
+#include "syslog.h"
+
+SyslogPrinter::SyslogPrinter() :
+ _lastOperationSucceeded(true),
+ _lastErrorMessage(""),
+ _facility(SYSLOG_LOCAL0),
+ _severity(SYSLOG_DEBUG),
+ _protocol(SYSLOG_PROTO_BSD),
+ _appName("WLED"),
+ _bufferIndex(0) {}
+
+void SyslogPrinter::begin(const char* host, uint16_t port,
+ uint8_t facility, uint8_t severity, uint8_t protocol) {
+
+ DEBUG_PRINTF_P(PSTR("===== WLED SYSLOG CONFIGURATION =====\n"));
+ DEBUG_PRINTF_P(PSTR(" Hostname: %s\n"), host);
+ DEBUG_PRINTF_P(PSTR(" Cached IP: %s\n"), syslogHostIP.toString().c_str());
+ DEBUG_PRINTF_P(PSTR(" Port: %u\n"), (unsigned)port);
+ DEBUG_PRINTF_P(PSTR("======================================\n"));
+
+ strlcpy(syslogHost, host, sizeof(syslogHost));
+ syslogPort = port;
+ _facility = facility;
+ _severity = severity;
+ _protocol = protocol;
+
+ // clear any cached IP so resolveHostname() will run next write()
+ syslogHostIP = IPAddress(0,0,0,0);
+}
+
+void SyslogPrinter::setAppName(const String &appName) {
+ _appName = appName;
+}
+
+bool SyslogPrinter::resolveHostname() {
+ if (!WLED_CONNECTED || !syslogEnabled) return false;
+
+ // If we already have an IP or can parse the hostname as an IP, use that
+ if (syslogHostIP || syslogHostIP.fromString(syslogHost)) {
+ return true;
+ }
+
+ // Otherwise resolve the hostname
+ #ifdef ESP8266
+ WiFi.hostByName(syslogHost, syslogHostIP, 750);
+ #else
+ #ifdef WLED_USE_ETHERNET
+ ETH.hostByName(syslogHost, syslogHostIP);
+ #else
+ WiFi.hostByName(syslogHost, syslogHostIP);
+ #endif
+ #endif
+
+ return syslogHostIP != IPAddress(0, 0, 0, 0);
+}
+
+void SyslogPrinter::flushBuffer() {
+ if (_bufferIndex == 0) return;
+
+ // Skip pure "#015" lines
+ if (_bufferIndex == 4 && memcmp(_buffer, "#015", 4) == 0) {
+ _bufferIndex = 0;
+ return;
+ }
+
+ // Check if the message contains only whitespace
+ bool onlyWhitespace = true;
+ for (size_t i = 0; i < _bufferIndex; i++) {
+ if (_buffer[i] != ' ' && _buffer[i] != '\t') {
+ onlyWhitespace = false;
+ break;
+ }
+ }
+ if (onlyWhitespace) {
+ _bufferIndex = 0;
+ return;
+ }
+
+ // Null-terminate
+ _buffer[_bufferIndex] = '\0';
+
+ // Send the buffer with default severity
+ write((const uint8_t*)_buffer, _bufferIndex, _severity);
+
+ // Reset buffer index
+ _bufferIndex = 0;
+}
+
+size_t SyslogPrinter::write(uint8_t c) {
+ // Store in buffer regardless of connection status
+ if (_bufferIndex < sizeof(_buffer) - 1) {
+ _buffer[_bufferIndex++] = c;
+ }
+
+ // If newline or buffer full, flush buffer
+ if (c == '\n' || _bufferIndex >= sizeof(_buffer) - 1) {
+ flushBuffer();
+ }
+
+ return 1;
+}
+
+size_t SyslogPrinter::write(const uint8_t *buf, size_t size) {
+ return write(buf, size, _severity);
+}
+
+size_t SyslogPrinter::write(const uint8_t *buf, size_t size, uint8_t severity) {
+ _lastOperationSucceeded = true;
+ if (!WLED_CONNECTED) {
+ _lastOperationSucceeded = false;
+ _lastErrorMessage = F("Network not connected");
+ return 0;
+ }
+ if (buf == nullptr) {
+ _lastOperationSucceeded = false;
+ _lastErrorMessage = F("Null buffer provided");
+ return 0;
+ }
+ if (!syslogEnabled) {
+ _lastOperationSucceeded = false;
+ _lastErrorMessage = F("Syslog is disabled");
+ return 0;
+ }
+ if (!resolveHostname()) {
+ _lastOperationSucceeded = false;
+ _lastErrorMessage = F("Failed to resolve hostname");
+ return 0;
+ }
+
+ // Check for special case - literal "#015" string
+ if (size >= 4 && buf[0] == '#' && buf[1] == '0' && buf[2] == '1' && buf[3] == '5') {
+ return size; // Skip sending this message
+ }
+
+ // Skip empty messages
+ if (size == 0) return 0;
+
+ // Check if the message contains only whitespace
+ bool onlyWhitespace = true;
+ for (size_t i = 0; i < size; i++) {
+ if (buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\r' && buf[i] != '\n') {
+ onlyWhitespace = false;
+ break;
+ }
+ }
+ if (onlyWhitespace) return size; // Skip sending this message
+
+ syslogUdp.beginPacket(syslogHostIP, syslogPort);
+
+ // Calculate priority value
+ uint8_t pri = (_facility << 3) | severity;
+
+ // Add hostname (replacing spaces with underscores) and app name
+ String cleanHostname = String(serverDescription);
+ cleanHostname.replace(' ', '_');
+
+ // Note: Only BSD protocol is currently implemented
+ syslogUdp.printf("<%d>", pri);
+
+ if (ntpEnabled && ntpConnected) {
+ // Month abbreviation
+ static const char* const months[] = {
+ "Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"
+ };
+
+ syslogUdp.printf("%s %2d %02d:%02d:%02d ",
+ months[month(localTime) - 1],
+ day(localTime),
+ hour(localTime),
+ minute(localTime),
+ second(localTime));
+ } else {
+ // No valid time available
+ syslogUdp.print(F("Jan 01 00:00:00 "));
+ }
+
+ // Add hostname and app name
+ syslogUdp.print(cleanHostname);
+ syslogUdp.print(" ");
+ syslogUdp.print(_appName);
+ syslogUdp.print(": ");
+
+ // Add message content
+ size = syslogUdp.write(buf, size);
+
+ syslogUdp.endPacket();
+ return size;
+}
+
+SyslogPrinter Syslog;
+#endif // WLED_ENABLE_SYSLOG
\ No newline at end of file
diff --git a/wled00/syslog.h b/wled00/syslog.h
new file mode 100644
index 0000000000..98b4e39134
--- /dev/null
+++ b/wled00/syslog.h
@@ -0,0 +1,59 @@
+#ifndef WLED_SYSLOG_H
+#define WLED_SYSLOG_H
+#include
+#include
+
+// Buffer management
+#ifndef SYSLOG_BUFFER_SIZE
+ #define SYSLOG_BUFFER_SIZE 128
+#endif
+
+#define SYSLOG_LOCAL0 16 // local use 0
+#define SYSLOG_DEBUG 7 // Debug: debug-level messages
+
+// Syslog protocol formats - commented out but preserved
+#define SYSLOG_PROTO_BSD 0 // Legacy BSD format (RFC 3164)
+
+class SyslogPrinter : public Print {
+ private:
+ WiFiUDP syslogUdp; // needs to be here otherwise UDP messages get truncated upon destruction
+ IPAddress syslogHostIP;
+ bool resolveHostname();
+ bool _lastOperationSucceeded;
+ String _lastErrorMessage;
+
+ // Syslog configuration - using globals from wled.h
+ uint8_t _facility; // Internal copy of syslogFacility (from wled.h), fixed to SYSLOG_LOCAL0
+ uint8_t _severity; // Internal copy of syslogSeverity (from wled.h), fixed to SYSLOG_DEBUG
+ uint8_t _protocol; // Internal copy of syslogProtocol (from wled.h), fixed to SYSLOG_PROTO_BSD
+ String _appName;
+
+ char _buffer[SYSLOG_BUFFER_SIZE]; // Buffer for collecting characters
+
+ size_t _bufferIndex;
+ void flushBuffer();
+
+ public:
+ SyslogPrinter();
+ void begin(const char* host, uint16_t port,
+ uint8_t facility = SYSLOG_LOCAL0,
+ uint8_t severity = SYSLOG_DEBUG,
+ uint8_t protocol = SYSLOG_PROTO_BSD);
+ void setAppName(const String &appName);
+
+ // Print interface implementation
+ virtual size_t write(uint8_t c);
+ virtual size_t write(const uint8_t *buf, size_t size);
+
+ // Severity override for specific messages
+ size_t write(const uint8_t *buf, size_t size, uint8_t severity);
+
+ // Error handling
+ bool lastOperationSucceeded() const { return _lastOperationSucceeded; }
+ String getLastErrorMessage() const { return _lastErrorMessage; }
+};
+
+// Default instance
+extern SyslogPrinter Syslog;
+
+#endif
\ No newline at end of file
diff --git a/wled00/wled.cpp b/wled00/wled.cpp
index cc338d23f2..97d092ba61 100644
--- a/wled00/wled.cpp
+++ b/wled00/wled.cpp
@@ -329,7 +329,7 @@ void WLED::setup()
#if defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || ARDUINO_USB_CDC_ON_BOOT)
delay(2500); // allow CDC USB serial to initialise
#endif
- #if !defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DEBUG_HOST) && ARDUINO_USB_CDC_ON_BOOT
+ #if !defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DEBUG_HOST) && !defined(WLED_ENABLE_SYSLOG) && ARDUINO_USB_CDC_ON_BOOT
Serial.setDebugOutput(false); // switch off kernel messages when using USBCDC
#endif
DEBUG_PRINTLN();
@@ -387,7 +387,7 @@ void WLED::setup()
usePWMFixedNMI(); // link the NMI fix
#endif
-#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
+#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST) && !defined(WLED_ENABLE_SYSLOG)
PinManager::allocatePin(hardwareTX, true, PinOwner::DebugOut); // TX (GPIO1 on ESP32) reserved for debug output
#endif
#ifdef WLED_ENABLE_DMX //reserve GPIO2 as hardcoded DMX pin
@@ -422,6 +422,13 @@ void WLED::setup()
WLED_SET_AP_SSID(); // otherwise it is empty on first boot until config is saved
multiWiFi.push_back(WiFiConfig(CLIENT_SSID,CLIENT_PASS)); // initialise vector with default WiFi
+#ifdef WLED_ENABLE_SYSLOG
+ // Configure and initialize Syslog client
+ Syslog.begin(syslogHost, syslogPort,
+ syslogFacility, syslogSeverity, syslogProtocol);
+ Syslog.setAppName("WLED");
+#endif
+
DEBUG_PRINTLN(F("Reading config"));
deserializeConfigFromFS();
DEBUG_PRINTF_P(PSTR("heap %u\n"), ESP.getFreeHeap());
diff --git a/wled00/wled.h b/wled00/wled.h
index f8dc1252a8..e7a3c7a2fa 100644
--- a/wled00/wled.h
+++ b/wled00/wled.h
@@ -964,7 +964,24 @@ WLED_GLOBAL JsonDocument *pDoc _INIT(&gDoc);
WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
// enable additional debug output
-#if defined(WLED_DEBUG_HOST)
+#if defined(WLED_ENABLE_SYSLOG)
+ #include "syslog.h"
+ // On the host side, use a standard syslog server or tools like rsyslog
+ // use -D WLED_ENABLE_SYSLOG and -D WLED_DEBUG
+ #define DEBUGOUT Syslog
+ WLED_GLOBAL bool syslogEnabled _INIT(true);
+ #ifndef WLED_SYSLOG_HOST
+ #define WLED_SYSLOG_HOST ""
+ #endif
+ WLED_GLOBAL char syslogHost[33] _INIT(WLED_SYSLOG_HOST);
+ #ifndef WLED_SYSLOG_PORT
+ #define WLED_SYSLOG_PORT 514
+ #endif
+ WLED_GLOBAL int syslogPort _INIT(WLED_SYSLOG_PORT);
+ WLED_GLOBAL uint8_t syslogProtocol _INIT(SYSLOG_PROTO_BSD); // Direct initialization with hardcoded BSD protocol value
+ WLED_GLOBAL uint8_t syslogFacility _INIT(SYSLOG_LOCAL0); // Direct initialization with hardcoded LOCAL0 facility value
+ WLED_GLOBAL uint8_t syslogSeverity _INIT(SYSLOG_DEBUG); // Direct initialization with hardcoded DEBUG severity value
+#elif defined(WLED_DEBUG_HOST)
#include "net_debug.h"
// On the host side, use netcat to receive the log statements: nc -l 7868 -u
// use -D WLED_DEBUG_HOST='"192.168.xxx.xxx"' or FQDN within quotes
diff --git a/wled00/xml.cpp b/wled00/xml.cpp
index de2f5590df..17303bf240 100644
--- a/wled00/xml.cpp
+++ b/wled00/xml.cpp
@@ -105,7 +105,7 @@ void appendGPIOinfo(Print& settingsScript) {
settingsScript.print(2); // DMX hardcoded pin
firstPin = false;
#endif
- #if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
+ #if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST) && !defined(WLED_ENABLE_SYSLOG)
if (!firstPin) settingsScript.print(',');
settingsScript.print(hardwareTX); // debug output (TX) pin
firstPin = false;
@@ -516,6 +516,13 @@ void getSettingsJS(byte subPage, Print& settingsScript)
settingsScript.print(F("toggle('Hue');")); // hide Hue Sync settings
#endif
printSetFormValue(settingsScript,PSTR("BD"),serialBaud);
+
+ #ifdef WLED_ENABLE_SYSLOG
+ printSetFormCheckbox(settingsScript,PSTR("SL_en"), syslogEnabled); // enable/disable
+ printSetFormValue (settingsScript,PSTR("SL_host"), syslogHost); // host
+ printSetFormValue (settingsScript,PSTR("SL_port"), syslogPort); // port
+ #endif
+
#ifndef WLED_ENABLE_ADALIGHT
settingsScript.print(F("toggle('Serial');"));
#endif