Files
logwisp/doc/installation.md
T

6.5 KiB
Raw Blame History

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 1580115804. 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