6.5 KiB
Installation Guide
Requirements
- Operating systems: Linux (kernel 6.10+), FreeBSD (14.0+)
- Architecture: amd64
- Go: 1.27.1 or newer, to build from source
Building from Source
git clone https://github.com/lixenwraith/logwisp.git
cd logwisp
make
sudo make install # installs to $PREFIX/bin, default /usr/local/bin
The Makefile works with both GNU make and BSD make. Targets:
| Target | Effect |
|---|---|
make / make build |
Build bin/logwisp with version metadata |
make dev |
Build with the race detector enabled |
make install |
Install the binary to $(PREFIX)/bin (default /usr/local) |
make uninstall |
Intended to remove the installed binary — currently broken: it expands to $(BINDIR)/bin/logwisp instead of $(BINDIR)/logwisp, so it removes nothing. Delete the binary by hand |
make clean |
Remove the built binary |
make version |
Print the version, commit, and build time that would be embedded |
Version, commit hash, and build time are injected via -ldflags from git describe and git rev-parse. A plain go build produces a working binary that
reports dev for all three:
go build -o bin/logwisp ./cmd/logwisp
go install github.com/lixenwraith/logwisp/cmd/logwisp@latest also works, with
the same loss of version metadata.
Container Image
The root Dockerfile builds the same package into scratch under UID 65532,
static and stripped. There is no shell and no config in the image: mount one and
name it, as the binary has no daemon mode and no built-in defaults worth running.
REV=$(git rev-parse HEAD)
docker build -t "logwisp:$(git rev-parse --short HEAD)" \
--build-arg VERSION="$(git describe --tags --always)" \
--build-arg REVISION="$REV" .
docker run --rm -v /etc/logwisp:/etc/logwisp:ro logwisp:... -c /etc/logwisp/logwisp.toml
Sinks that listen (http, tcp) need their ports published; the read-only
root filesystem and dropped capabilities a restricted runtime imposes are all
compatible with it, provided a file sink's directory is writable by 65532.
Configuration
Copy the annotated reference configuration and edit it:
sudo mkdir -p /etc/logwisp
sudo cp config/logwisp.toml /etc/logwisp/logwisp.toml
LogWisp searches, in order: -c <path>, --config=<path>,
$LOGWISP_CONFIG_DIR/$LOGWISP_CONFIG_FILE, ~/.config/logwisp/logwisp.toml,
./logwisp.toml. See Configuration.
Running as a Service
LogWisp has no daemon mode; run it in the foreground under a supervisor.
Linux (systemd)
/etc/systemd/system/logwisp.service:
[Unit]
Description=LogWisp Log Transport Service
After=network.target
[Service]
Type=simple
User=logwisp
Group=logwisp
ExecStart=/usr/local/bin/logwisp -c /etc/logwisp/logwisp.toml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=10
WorkingDirectory=/var/lib/logwisp
StandardOutput=journal
StandardError=journal
# Hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/logwisp /var/lib/logwisp
[Install]
WantedBy=multi-user.target
ExecReload gives you systemctl reload logwisp for configuration and
certificate rotation without dropping the process.
If a pipeline binds a port below 1024, add
AmbientCapabilities=CAP_NET_BIND_SERVICE rather than running as root.
Setup:
sudo useradd -r -s /usr/sbin/nologin logwisp
sudo mkdir -p /etc/logwisp /var/lib/logwisp /var/log/logwisp
sudo chown logwisp:logwisp /var/lib/logwisp /var/log/logwisp
sudo systemctl daemon-reload
sudo systemctl enable --now logwisp
The service account needs read access to every directory a file source
watches and write access to every directory a file sink or
logging.file writes to.
FreeBSD (rc.d)
/usr/local/etc/rc.d/logwisp:
#!/bin/sh
# PROVIDE: logwisp
# REQUIRE: DAEMON NETWORKING
# KEYWORD: shutdown
. /etc/rc.subr
name="logwisp"
rcvar="${name}_enable"
pidfile="/var/run/${name}.pid"
procname="/usr/local/bin/logwisp"
command="/usr/sbin/daemon"
command_args="-p ${pidfile} -f ${procname} -c /usr/local/etc/logwisp/logwisp.toml"
load_rc_config $name
: ${logwisp_enable:="NO"}
run_rc_command "$1"
Setup:
sudo chmod +x /usr/local/etc/rc.d/logwisp
sudo pw useradd logwisp -d /nonexistent -s /usr/sbin/nologin
sudo mkdir -p /usr/local/etc/logwisp /var/log/logwisp
sudo chown logwisp:logwisp /var/log/logwisp
sudo sysrc logwisp_enable="YES"
sudo service logwisp start
Directory Layout
| Purpose | Linux | FreeBSD |
|---|---|---|
| Binary | /usr/local/bin/logwisp |
/usr/local/bin/logwisp |
| Configuration | /etc/logwisp/ |
/usr/local/etc/logwisp/ |
| TLS material | /etc/logwisp/tls/ |
/usr/local/etc/logwisp/tls/ |
| Working directory | /var/lib/logwisp/ |
/var/db/logwisp/ |
| Application logs | /var/log/logwisp/ |
/var/log/logwisp/ |
Key files should be mode 0600 and owned by the service account.
Verification
logwisp --version
# start in the foreground with debug logging and watch pipelines come up
logwisp -c /etc/logwisp/logwisp.toml --logging.level=debug --logging.output=stderr
sudo systemctl status logwisp # Linux
sudo service logwisp status # FreeBSD
Expect Created source instance, Created sink instance, and
Starting pipeline for each configured pipeline. There is no validate-only
mode; see Operations.
Test Scripts
End-to-end scripts under test/ run against a local build:
make
./test/chain-test.sh --auto # two independent relay pipelines
./test/chain-aggregate-test.sh --auto # fan-in: both edges into one pipeline
./test/mtls-chain-test.sh --auto # the same fan-in under mTLS
./test/passthrough-test.sh # file source relays a wide envelope intact
Without --auto the chain scripts run the relay in the foreground for
interactive inspection. They need bash 5+, coreutils, and curl, and they bind
ports 15801–15804. The pass-through test binds nothing. Generated configuration
and logs land in test/run/.
Uninstall
Linux
sudo systemctl disable --now logwisp
sudo rm /usr/local/bin/logwisp /etc/systemd/system/logwisp.service
sudo systemctl daemon-reload
sudo rm -rf /etc/logwisp /var/lib/logwisp /var/log/logwisp
sudo userdel logwisp
FreeBSD
sudo service logwisp stop
sudo sysrc -x logwisp_enable
sudo rm /usr/local/bin/logwisp /usr/local/etc/rc.d/logwisp
sudo rm -rf /usr/local/etc/logwisp /var/db/logwisp /var/log/logwisp
sudo pw userdel logwisp