Files
LogMaster/DOCS.md
Kevin 44cd9ab001
Some checks failed
LogMaster CI/CD / build-and-test (push) Has been cancelled
LogMaster CI/CD / docker (push) Has been cancelled
Initial commit: LogMaster with Viewer Collector Monitor modes
2026-05-04 13:50:15 +02:00

21 KiB

LogMaster — Complete Documentation

A modular log management platform with four operating modes, a web UI for each, and full API control. Zero external dependencies beyond Node.js.


Table of Contents


Architecture

                        ┌──────────────────────────┐
                        │       LOG SOURCES         │
                        ├──────┬──────┬──────┬──────┤
                        │Files │ S3   │ UDP  │ HTTP │
                        │.log  │Bucket│:5140 │POST  │
                        │.gz   │      │      │/collect
                        └──┬───┴──┬───┴──┬───┴──┬───┘
                           │      │      │      │
                           ▼      ▼      ▼      ▼
┌──────────────────────────────────────────────────────────────┐
│                      LOGMASTER SERVER                         │
│                                                              │
│  ┌──────────┐   ┌───────────┐   ┌──────────┐   ┌─────────┐ │
│  │ VIEWER   │   │ COLLECTOR │   │ MONITOR  │   │   ALL   │ │
│  │          │   │           │   │          │   │         │ │
│  │ Read     │   │ Receive   │   │ Scan     │   │ Every   │ │
│  │ Filter   │   │ Store     │   │ Pattern  │   │ feature │ │
│  │ Search   │   │ Rotate    │   │ Alert    │   │ active  │ │
│  │ Export   │   │ Forward   │   │ Notify   │   │         │ │
│  └──────────┘   └───────────┘   └──────────┘   └─────────┘ │
│                                                              │
│  Forward Targets: HTTP │ File │ UDP │ Stream │ Console       │
│  Notifications:   Telegram │ Webhook │ Teams │ Email         │
└──────────────────────────────────────────────────────────────┘

Quick Start

npm install
npm run build                    # Compile TypeScript
node dist-server/server.js       # Start in "both" mode (viewer+collector) on :8080

Open http://localhost:8080.

Start specific modes

# Collector on port 8081
LOG_MODE=collector PORT=8081 node dist-server/server.js

# Viewer on port 9090, reading from collector
LOG_MODE=viewer PORT=9090 REMOTE_COLLECTOR_URL=http://localhost:8081 LOG_SOURCES=./logs/*.log node dist-server/server.js

# Monitor on port 8082
LOG_MODE=monitor PORT=8082 node dist-server/server.js

Operating Modes

Mode LOG_MODE= What it does Web UI
Viewer viewer Read & display logs Log viewer with filter, search, export
Collector collector Receive, store, rotate, forward logs Stream dashboard with live feed
Monitor monitor Scan files for patterns, send alerts Rule editor with test & alert history
Both both Viewer + Collector Viewer UI with collector active
All all All three modes Viewer UI, all features via API

Each mode serves its own dedicated web UI at the root URL.


Viewer

What it does

Reads logs from local files (plain, gzip, bz2, xz, zstd), S3 buckets, and remote collector streams. Displays them in a web UI with filtering, regex search, bookmarks, export, and live tail mode.

GUI walkthrough

  1. Open http://localhost:9090
  2. Sidebar shows all sources grouped by type (Files, S3, Collector Streams, Remote)
  3. Click a source to filter to just that file/stream
  4. Search bar — type to filter. Click .* for regex, Aa for case-sensitive
  5. Level dropdown — filter by ERROR, WARN, INFO, etc.
  6. Tail button — auto-scrolls to new lines. New lines flash blue briefly
  7. Right-click any line for copy, bookmark, filter options
  8. Export — download visible logs as .txt or .json

API examples

# List file sources
curl http://localhost:9090/api/sources

# Add a source
curl -X POST http://localhost:9090/api/sources \
  -H "Content-Type: application/json" \
  -d '{"path": "/var/log/syslog"}'

# Read all logs
curl http://localhost:9090/api/logs

# Read specific source
curl "http://localhost:9090/api/logs?source=/var/log/syslog"

# Read remote collector streams
curl http://localhost:9090/api/remote/streams
curl http://localhost:9090/api/remote/stream/my-app

Configuration

LOG_MODE=viewer
PORT=9090
LOG_SOURCES=/var/log/syslog,/app/logs/*.log
LOG_THEME=dark
LOG_REFRESH_INTERVAL=2000
LOG_TAIL_MODE=true
LOG_MAX_LINES=50000
REMOTE_COLLECTOR_URL=http://collector:8081

Collector

What it does

Receives logs via HTTP POST and UDP, stores them in named streams, rotates files by size or time, compresses rotated files, and forwards to other targets (HTTP, file, UDP, another stream, console).

Sending logs

# Plain text (each line = one log entry)
curl -X POST http://localhost:8081/collect/my-app \
  -d "2026-05-04 ERROR Database connection lost"

# JSON array
curl -X POST http://localhost:8081/collect/my-app/json \
  -H "Content-Type: application/json" \
  -d '["INFO Started", "ERROR Crashed", "WARN Low memory"]'

# UDP (format: streamId|logline)
echo "my-app|2026-05-04 ERROR disk full" | nc -u localhost 5140

Streams are created automatically on first ingest. No pre-configuration needed.

GUI walkthrough

  1. Open http://localhost:8081
  2. Overview shows stream count, total lines, lines/minute
  3. Stream list — click a stream to filter the live feed
  4. Live Feed tab — real-time log lines with color coding (red=ERROR, orange=WARN)
  5. Configuration tab — edit storage, UDP, rotation, compression settings
  6. Forwarding tab — add/remove forward targets

API examples

# List streams
curl http://localhost:8081/collector/streams

# Read a stream
curl http://localhost:8081/collector/stream/my-app

# Read last 10 lines
curl "http://localhost:8081/collector/stream/my-app?tail=10"

# Delete a stream
curl -X DELETE http://localhost:8081/collector/stream/my-app

# Get config
curl http://localhost:8081/collector/config

Log rotation

Rotation triggers on whichever condition is met first:

Trigger Variable Default
File size COLLECTOR_ROTATION_MAX_SIZE 5MB (5242880)
File age COLLECTOR_ROTATION_MAX_AGE 10min (600000)

Compression options: none, gzip, bzip2, xz, zstd

Forward targets

# Forward to HTTP + local file + aggregate stream
COLLECTOR_FORWARD_TARGETS=[
  {"type":"http","url":"http://elk:9200/_bulk","format":"json","batchSize":100},
  {"type":"file","path":"/backup/all.log"},
  {"type":"stream","targetStream":"all-logs"},
  {"type":"console"}
]

The stream type copies logs from any stream into another stream on the same collector. Lines are prefixed with [fwd:source-stream].

Configuration

LOG_MODE=collector
PORT=8081
COLLECTOR_UDP_ENABLED=true
COLLECTOR_UDP_PORT=5140
COLLECTOR_STORAGE_DIR=./collector-data
COLLECTOR_MAX_LINES=100000
COLLECTOR_MAX_STREAMS=50
COLLECTOR_PERSIST=true
COLLECTOR_ROTATION_MAX_SIZE=5242880
COLLECTOR_ROTATION_MAX_AGE=600000
COLLECTOR_ROTATION_COMPRESSION=gzip
COLLECTOR_ROTATION_EXTENSION=.log

Monitor

What it does

Scans log files on a schedule, matches regex patterns, and sends notifications via Telegram, Webhook, Microsoft Teams, or Email. Supports time-range filtering, scheduled scans (continuous, daily, hourly), and automatic gzip attachment when matches exceed a threshold.

How scanning works

  1. Every N seconds, the monitor reads all source files for each enabled rule
  2. Only files matching the time range are scanned (today, week, month, last N hours)
  3. Each line is tested against the regex patterns (match any OR match all)
  4. If matches found AND cooldown expired → notifications sent
  5. If matches > maxLinesInMessage → first N lines inline, full results as .gz attachment

GUI walkthrough

  1. Open http://localhost:8082
  2. Click "+ New" to create a rule
  3. Fill in:
    • Name, sources (file paths, one per line, globs supported)
    • Patterns (one regex per line)
    • Time range (today, week, month, hours, all)
    • Schedule (continuous, daily at HH:MM, every N hours)
    • Max lines in notification, cooldown
  4. Add notification channels — select type, fill fields, click "+ Add Channel"
  5. Click "🧪 Test Notification" to verify the channel works
  6. Click "💾 Save Rule"
  7. Click "🧪 Test Now" to trigger the rule immediately
  8. Alerts appear in the sidebar — click for full detail with all matched lines

Notification channels

Telegram:

  • Type: telegram
  • Fields: Bot Token, Chat ID
  • Get a bot token from @BotFather, chat ID from @userinfobot

Webhook (Slack, Discord, custom):

  • Type: webhook
  • Fields: URL

Microsoft Teams:

  • Type: teams
  • Fields: Incoming Webhook URL

Email:

  • Type: email
  • Fields: SMTP Host, SMTP Port, SMTP User, SMTP Password, To address

API examples

# Create a rule
curl -X POST http://localhost:8082/api/monitor/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Root Access Alert",
    "enabled": true,
    "sources": ["/var/log/auth.log"],
    "patterns": ["root.*login", "su.*root"],
    "patternLogic": "any",
    "timeRange": {"type": "today"},
    "schedule": {"mode": "interval"},
    "notifications": [{"type":"telegram","botToken":"TOKEN","chatId":"CHAT_ID"}],
    "maxLinesInMessage": 20,
    "cooldownMs": 300000
  }'

# List rules
curl http://localhost:8082/api/monitor/rules

# Trigger a rule manually
curl -X POST http://localhost:8082/api/monitor/trigger/rule-id

# View alert history
curl http://localhost:8082/api/monitor/results

# Test a notification channel
curl -X POST http://localhost:8082/api/monitor/test-notification \
  -H "Content-Type: application/json" \
  -d '{"type":"telegram","botToken":"TOKEN","chatId":"CHAT_ID"}'

# Update a rule
curl -X PUT http://localhost:8082/api/monitor/rule/rule-id \
  -H "Content-Type: application/json" \
  -d '{"name": "Updated Name", "enabled": false}'

# Delete a rule
curl -X DELETE http://localhost:8082/api/monitor/rule/rule-id

Configuration

LOG_MODE=monitor
PORT=8082
MONITOR_ENABLED=true
MONITOR_SCAN_INTERVAL=60000
MONITOR_STORAGE_DIR=./monitor-data

Rules can be pre-configured via MONITOR_RULES env var (JSON array) or created via GUI/API at runtime.


S3 Integration

Via GUI

Click ☁️ S3 in the viewer toolbar. Fill in: name, bucket, prefix, access key, secret key, region, optional custom endpoint (for MinIO).

Via environment

S3_ACCESS_KEY_ID=AKIA...
S3_SECRET_ACCESS_KEY=...
S3_REGION=eu-central-1
S3_SOURCE_PROD=my-bucket:logs/production/
S3_SOURCE_STAGING=my-bucket:logs/staging/

Via API

curl -X POST http://localhost:9090/api/s3/add \
  -H "Content-Type: application/json" \
  -d '{"name":"prod","bucket":"my-bucket","prefix":"logs/","accessKeyId":"AKIA...","secretAccessKey":"...","region":"eu-central-1"}'

curl http://localhost:9090/api/s3/sources
curl "http://localhost:9090/api/s3/list?name=prod"
curl "http://localhost:9090/api/s3/read?name=prod&key=logs/app.log"

For S3-compatible services (MinIO, DigitalOcean Spaces), add endpoint:

S3_ENDPOINT=http://minio:9000

Configuration

Priority (highest wins)

  1. Environment variables
  2. logviewer.config.json (editable via GUI)
  3. .env file
  4. Built-in defaults

Full config file example

{
  "mode": "all",
  "port": 8080,
  "viewer": {
    "sources": ["/var/log/syslog", "/app/logs/*.log"],
    "theme": "dark",
    "refreshInterval": 2000,
    "tailMode": true,
    "maxLines": 50000
  },
  "collector": {
    "enabled": true,
    "storageDir": "./collector-data",
    "maxLinesPerStream": 100000,
    "maxStreams": 50,
    "persistToDisk": true,
    "udp": {"enabled": true, "port": 5140},
    "rotation": {"maxSizeBytes": 5242880, "maxAgeMs": 600000, "compression": "gzip", "fileExtension": ".log"},
    "forwardTargets": [{"type": "stream", "targetStream": "all-logs"}]
  },
  "monitor": {
    "enabled": true,
    "scanIntervalMs": 60000,
    "rules": []
  },
  "s3": {
    "sources": {
      "prod": {"bucket": "logs", "prefix": "prod/", "region": "eu-central-1", "accessKeyId": "...", "secretAccessKey": "..."}
    }
  },
  "remoteCollector": {"url": "http://collector:8081"}
}

All environment variables

Variable Default Description
LOG_MODE both viewer, collector, monitor, both, all
PORT 8080 HTTP port
HOST 0.0.0.0 Bind address
LOG_SOURCES Comma-separated file paths/globs
LOG_THEME dark dark or light
LOG_REFRESH_INTERVAL 2000 Auto-refresh ms
LOG_TAIL_MODE true Auto-scroll
LOG_MAX_LINES 50000 Max lines per file
COLLECTOR_UDP_ENABLED true UDP receiver
COLLECTOR_UDP_PORT 5140 UDP port
COLLECTOR_STORAGE_DIR ./collector-data Storage path
COLLECTOR_PERSIST true Write to disk
COLLECTOR_ROTATION_MAX_SIZE 5242880 Rotate at bytes
COLLECTOR_ROTATION_MAX_AGE 600000 Rotate at ms
COLLECTOR_ROTATION_COMPRESSION gzip none/gzip/bzip2/xz/zstd
COLLECTOR_FORWARD_TARGETS [] JSON array
MONITOR_ENABLED true Enable scanning
MONITOR_SCAN_INTERVAL 60000 Scan interval ms
MONITOR_RULES [] JSON array of rules
REMOTE_COLLECTOR_URL Remote collector URL
S3_ACCESS_KEY_ID S3 access key
S3_SECRET_ACCESS_KEY S3 secret key
S3_REGION us-east-1 S3 region
S3_ENDPOINT Custom S3 endpoint

API Reference

General

Method Path Description
GET /api/mode Current mode info
GET /api/config Active configuration
POST /api/config/save Save config to file

Viewer

Method Path Description
GET /api/sources List file sources
POST /api/sources Add source {"path":"..."}
DELETE /api/sources?path=... Remove source
GET /api/logs?source=... Read logs
GET /api/remote/streams Remote collector streams
GET /api/remote/stream/:id Read remote stream

Collector

Method Path Description
POST /collect/:id Ingest plain text
POST /collect/:id/json Ingest JSON
GET /collector/streams List streams
GET /collector/stream/:id?tail=N Read stream
GET /collector/config Collector config
DELETE /collector/stream/:id Delete stream

Monitor

Method Path Description
GET /api/monitor/rules List rules
POST /api/monitor/rules Create rule
PUT /api/monitor/rule/:id Update rule
DELETE /api/monitor/rule/:id Delete rule
POST /api/monitor/trigger/:id Trigger rule now
GET /api/monitor/results Alert history
POST /api/monitor/test-notification Test a channel

S3

Method Path Description
POST /api/s3/add Add S3 source
GET /api/s3/sources List S3 sources
GET /api/s3/list?name=... List S3 objects
GET /api/s3/read?name=...&key=... Read S3 object

GUI Walkthroughs

Viewer: Search for errors in the last hour

  1. Open http://localhost:9090
  2. Select "Error" from the level dropdown
  3. Type a search term or regex in the search bar
  4. Click .* to enable regex mode
  5. Results update live. Click 💾 Export to download

Collector: Watch live logs from multiple apps

  1. Open http://localhost:8081
  2. The Live Feed tab shows all incoming logs in real-time
  3. Click a stream in the sidebar to filter
  4. Click ⏸ Pause to freeze the feed
  5. Go to ⚙️ Configuration to change rotation/compression settings

Monitor: Set up a daily security scan

  1. Open http://localhost:8082
  2. Click "+ New"
  3. Name: "Daily Security Audit"
  4. Sources: /var/log/auth.log (one per line)
  5. Patterns: root.*login, sudo.*COMMAND, Failed password (one per line)
  6. Time Range: Today
  7. Schedule: Daily at 07:00
  8. Add Telegram notification: paste bot token and chat ID
  9. Click "🧪 Test Notification" to verify
  10. Click "💾 Save Rule"
  11. Click "🧪 Test Now" to see immediate results

Example Scenarios

1. Development: All-in-one

LOG_MODE=both PORT=8080 LOG_SOURCES=./logs/*.log node dist-server/server.js

View logs + receive from apps on one port.

2. Production: Separate services

# Server A: Collector
LOG_MODE=collector PORT=8081 COLLECTOR_UDP_PORT=5140 \
  COLLECTOR_ROTATION_COMPRESSION=gzip \
  COLLECTOR_FORWARD_TARGETS='[{"type":"stream","targetStream":"all-logs"}]' \
  node dist-server/server.js

# Server B: Viewer
LOG_MODE=viewer PORT=9090 REMOTE_COLLECTOR_URL=http://serverA:8081 \
  node dist-server/server.js

# Server C: Monitor
LOG_MODE=monitor PORT=8082 MONITOR_SCAN_INTERVAL=30000 \
  node dist-server/server.js

3. Security monitoring with Telegram alerts

LOG_MODE=monitor PORT=8082 MONITOR_SCAN_INTERVAL=10000 \
  MONITOR_RULES='[{"id":"sec","name":"Security","enabled":true,"sources":["/var/log/auth.log"],"patterns":["root","sudo","Failed"],"patternLogic":"any","timeRange":{"type":"today"},"notifications":[{"type":"telegram","botToken":"YOUR_TOKEN","chatId":"YOUR_CHAT"}],"maxLinesInMessage":20,"cooldownMs":60000}]' \
  node dist-server/server.js

4. Log aggregation with S3 archive

LOG_MODE=both PORT=8080 \
  S3_ACCESS_KEY_ID=AKIA... S3_SECRET_ACCESS_KEY=... S3_REGION=eu-central-1 \
  S3_SOURCE_ARCHIVE=my-bucket:logs/ \
  COLLECTOR_FORWARD_TARGETS='[{"type":"file","path":"/archive/all.log"}]' \
  node dist-server/server.js

Docker & CI/CD

Build and run

docker build -t logmaster .

# Collector
docker run -d -p 8081:8080 -p 5140:5140/udp -e LOG_MODE=collector logmaster

# Viewer
docker run -d -p 9090:8080 -e LOG_MODE=viewer -e REMOTE_COLLECTOR_URL=http://collector:8080 logmaster

# Monitor
docker run -d -p 8082:8080 -e LOG_MODE=monitor -v /var/log:/logs:ro logmaster

Docker Compose

services:
  collector:
    build: .
    ports: ["8081:8080", "5140:5140/udp"]
    environment:
      LOG_MODE: collector
      COLLECTOR_UDP_PORT: "5140"
    volumes:
      - collector-data:/app/collector-data

  viewer:
    build: .
    ports: ["9090:8080"]
    environment:
      LOG_MODE: viewer
      REMOTE_COLLECTOR_URL: http://collector:8080
    depends_on: [collector]

  monitor:
    build: .
    ports: ["8082:8080"]
    environment:
      LOG_MODE: monitor
      MONITOR_SCAN_INTERVAL: "30000"
    volumes:
      - /var/log:/logs:ro

volumes:
  collector-data:

CI/CD (Gitea Actions)

The .gitea/workflows/ci.yaml pipeline:

  1. Installs dependencies
  2. Compiles TypeScript
  3. Generates sample logs
  4. Starts all 3 services
  5. Runs the full integration test suite (41 tests)
  6. Builds Docker image
  7. Pushes to Gitea container registry

To enable: add a Gitea Actions runner and set REGISTRY_USER / REGISTRY_PASSWORD secrets.


Keyboard Shortcuts

Key Action
Ctrl+F Search
Ctrl+Shift+F Regex search
Ctrl+T Toggle tail mode
Ctrl+W Toggle word wrap
Ctrl+G Go to line
Ctrl+Shift+T Toggle theme
Ctrl+= / Ctrl+- Zoom in/out
Ctrl+0 Reset zoom
Home / End Scroll top/bottom
Escape Clear search / close modals

Supported Log Formats

Format Extensions Decompression
Plain text .log, .txt, no extension Direct read
Gzip .gz Node.js zlib (built-in)
Bzip2 .bz2 bzcat CLI
XZ .xz xzcat CLI
Zstandard .zst zstdcat CLI

License

MIT