Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
DiscordLogSync
Pipes Valheim dedicated server logs to a Discord webhook in near-real-time. Configurable source: BepInEx pipeline, Console, or RawStdout (captures world saves and native stdout via fd-level interception).
| Date uploaded | 2 months ago |
| Version | 1.0.4 |
| Download link | tarbaby-DiscordLogSync-1.0.4.zip |
| Downloads | 38 |
| Dependency string | tarbaby-DiscordLogSync-1.0.4 |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.
Preferred version: 5.4.2333README
DiscordLogSync — Valheim Dedicated Server Mod
Pipes Valheim dedicated server logs to a Discord webhook in near-real-time, with local buffering so no lines are lost on unexpected process death.
How It Works
Server output (BepInEx pipeline, Console.Out, or raw stdout — see Source config)
│
▼
BepInEx/DiscordLogBuffer.txt ← every line flushed to disk immediately
│
▼ (background thread, every N seconds)
Discord Webhook POST
│
├─ success → remove sent lines from front of buffer (FIFO)
└─ failure → leave buffer intact, retry next tick
On startup:
buffer file exists from previous run? → send as ⚠️ crash-recovery message first
On clean shutdown:
flush remaining buffer as 🛑 shutdown message
Log Sources
Configure Source in the config file to choose what gets captured:
| Source | What it captures | Risk |
|---|---|---|
BepInEx (default) |
Everything flowing through BepInEx's log pipeline | Safe |
Console |
Managed Console.Out writes (superset of BepInEx in some cases) |
Low |
RawStdout |
All stdout at the OS fd level — including world saves, ZDO counts, PlayFab lines that bypass BepInEx entirely | Experimental — read warning below |
⚠️ RawStdout Warning
RawStdout uses Linux pipe() + dup2() to replace fd 1 with a kernel pipe.
A background relay thread forwards every byte to the original stdout and extracts
lines for Discord. If the relay thread crashes or deadlocks, the pipe buffer
(~64 KB) will fill up and block all stdout writes in the entire process.
- Linux only — falls back to
BepInExsource automatically on Windows or on any syscall failure - Only enable this if you specifically need to capture native stdout output (e.g. world save events)
- Designed as a diagnostic tool, not a permanent production setting
Install
- Copy
DiscordLogSync.dllintoBepInEx/plugins/ - Launch the server once to generate the config file
- Open
BepInEx/config/com.byawn.DiscordLogSync.cfg - Set your webhook URL and preferred source:
[Discord]
Source = BepInEx
WebhookUrl = https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN
SendIntervalSeconds = 3
MaxMessageChars = 1800
- Restart the server
Config Reference
| Key | Default | Description |
|---|---|---|
Source |
BepInEx |
Log source: BepInEx, Console, or RawStdout (see above) |
WebhookUrl |
(empty) | Required. Discord webhook URL. Plugin does nothing if unset. |
SendIntervalSeconds |
3 |
Flush interval in seconds. Minimum 2 (Discord rate limit). |
MaxMessageChars |
1800 |
Max characters per Discord message. Hard Discord limit is 2000. |
Buffer File
BepInEx/DiscordLogBuffer.txt
- Every line is flushed to disk immediately — a hard kill loses at most the current line
- Treated as a FIFO queue: oldest lines sent first, newest preserved at the back
- If the file exists on startup, its contents are sent as a crash-recovery message before normal logging begins
Build
Requires .NET SDK with netstandard2.1 support and a Valheim dedicated server + BepInEx installation.
The .csproj assumes the default Linux Steam path:
~/.steam/steam/steamapps/common/Valheim dedicated server
./build.sh # dotnet build -c Release
./deploy_server.sh # copy DLL + config to local server
./package.sh # zip ThunderstoreAssets + DLL for upload
CHANGELOG
1.0.4
- Updated BepInEx dependency to 5.4.2333
1.0.3
-
Windows compatibility for
RawStdoutsource — the fd-level pipe intercept now works on Windows via P/Invoke intoucrtbase.dll(_dup,_dup2,_pipe,_read,_write,_close). This works becauseucrtbase.dllis the Universal CRT shared across Unity's native engine and all managed code in the process.Silent failure mode: If the Unity build were statically linked against the CRT (extremely unlikely on modern Unity 6),
_dup2would still succeed but Unity's native writes would go to a separate fd table, never passing through the pipe. The plugin would start cleanly and BepInEx-sourced lines would still appear in Discord — but world save lines and other native stdout output would be silently absent. You would only notice by their absence. On Linux this concern does not apply.
1.0.2
- Add configurable
Sourcesetting:BepInEx(default),Console, orRawStdout BepInEx— original ILogListener approach, unchangedConsole— intercepts managed Console.Out via Console.SetOut()RawStdout— experimental, Linux only; intercepts stdout at the OS file descriptor level using pipe()+dup2(), capturing world saves, ZDO counts, and all native stdout writes that bypass BepInEx entirely. Falls back to BepInEx source on init failure.- Fix recovery message title to include server name and timestamp
- Fix shutdown message to use consistent em-dash formatting
1.0.1
- Add server name and timestamp to the message title
- Don't double up timestamps in the message content
- Show log event source and level
1.0.0
- Initial release
- Pipes all BepInEx and Unity logs to a Discord webhook in near-real-time
- Local buffer file flushed on every line — nothing lost on unexpected shutdown
- FIFO queue — oldest logs sent first, catches up automatically after bursts
- Crash recovery — leftover buffer from previous session sent on next startup flagged as recovered
- Configurable send interval and max message size