Add a 'logging' section to config.yaml supporting:
- output: stderr (default), stdout, or a file path
- level: debug, info, warn, error (default: info)
Implementation:
- New internal/logging package with Setup() for output destination
and Logger struct with level-aware Debug/Info/Warn/Error methods
- Config struct extended with Logging section (output + level fields)
- Hub refactored to accept *logging.Logger via constructor injection
- main.go initializes logging early after config load
The leveled logger suppresses messages below the configured threshold
while maintaining the stdlib log format. File output uses append mode
with 0644 permissions for safe log rotation.
🤖 Assisted by the code-assist SOP
WebSocket Relay Server
A minimal Go WebSocket relay server that broadcasts every incoming message to all connected clients. Supports TLS, Prometheus metrics, and graceful shutdown.
Features
- Fan-out broadcasting — every message is relayed to all connected clients
- TLS support — optional
wss://via cert/key PEM files - Prometheus metrics — connection counts, message totals, disconnections
- Graceful shutdown — clean exit on SIGINT/SIGTERM with client notification
- Zero dependencies at runtime — single static binary
Quick Start
# Install dependencies
go mod tidy
# Run the server (defaults to ws://localhost:8443)
make run
# Or with a custom config
go run . --config-file=./config.yaml
Open example/index.html in multiple browser tabs to test the P2P chat demo.
Configuration
Edit config.yaml:
server:
port: 8443
tls:
enabled: false # Set true for wss://
cert_file: cert.pem
key_file: key.pem
metrics:
enabled: true
port: 9090 # Prometheus metrics at :9090/metrics
Override the config file path with --config-file:
./websocket-relay --config-file=/etc/relay/config.yaml
Usage
Connect any WebSocket client to the server:
const ws = new WebSocket('ws://localhost:8443/');
ws.onmessage = (event) => console.log('Received:', event.data);
ws.onopen = () => ws.send('Hello from client!');
With TLS enabled:
const ws = new WebSocket('wss://localhost:8443/');
All messages sent by any client are broadcast to every connected client (including the sender).
Build
make build # Build binary → build/websocket-relay
make release # Cross-compile linux/amd64 + darwin/arm64
make clean # Remove build artifacts
Testing
make test # Run all tests (unit + integration)
Metrics
When metrics.enabled is true, Prometheus metrics are exposed at http://localhost:9090/metrics:
| Metric | Type | Description |
|---|---|---|
websocket_connected_clients |
Gauge | Currently connected clients |
websocket_messages_total |
Counter | Total messages relayed |
websocket_connections_total |
Counter | Total connections established |
websocket_disconnections_total |
Counter | Total disconnections |
Graceful Shutdown
The server handles SIGINT and SIGTERM signals:
- Stops accepting new connections
- Sends WebSocket
CloseGoingAwayframe to all connected clients - Closes all connections and exits cleanly
Shutdown timeout is 10 seconds.
Project Structure
websocket-relay/
├── main.go # Entry point, signal handling, graceful shutdown
├── internal/
│ ├── config/config.go # YAML config loader
│ ├── hub/hub.go # WebSocket hub, connection management, broadcast
│ └── metrics/metrics.go # Prometheus metric definitions
├── example/index.html # Browser P2P chat demo
├── config.yaml # Runtime configuration
├── config.example.yaml # Example config with TLS enabled
└── Makefile # Build, test, release commands
License
See repository for license details.
Description
Release v0.1.0
Latest
Languages
Go
86.2%
HTML
13.1%
Makefile
0.7%