Log Observability Setup
Overview
This guide walks through setting up a complete log observability stack for StorageLink, enabling you to search, analyze, and monitor file transfer activity through a web-based dashboard.
Core Components
The solution uses four interconnected services:
| Service | Role |
|---|---|
| Alloy | Monitors log files and extracts structured data (usernames, IP addresses, file paths) |
| Loki | Stores compressed, indexed logs optimized for querying |
| Grafana | Web interface for searching and visualizing logs |
| nginx | Proxies external HTTPS requests to Grafana |
Prerequisites
- Docker and Docker Compose installed on the StorageLink instance
- SSH access to the instance
Installation Steps
1. Install Docker and Docker Compose
sudo apt update
sudo apt install -y docker.io docker-compose
sudo systemctl enable docker && sudo systemctl start docker
2. Create the Directory Structure
sudo mkdir -p /opt/observability/{loki,alloy,grafana/provisioning/{datasources,dashboards}}
3. Configure docker-compose.yml
Create /opt/observability/docker-compose.yml:
version: "3"
networks:
observability:
internal: true
services:
loki:
image: grafana/loki:latest
volumes:
- ./loki-config.yaml:/etc/loki/config.yaml
- loki-data:/loki
command: -config.file=/etc/loki/config.yaml
networks:
- observability
alloy:
image: grafana/alloy:latest
volumes:
- ./config.alloy:/etc/alloy/config.alloy
- /opt/swiftgw/log:/var/log/storagelink:ro
command: run /etc/alloy/config.alloy
networks:
- observability
grafana:
image: grafana/grafana:latest
volumes:
- ./grafana/provisioning:/etc/grafana/provisioning
- grafana-data:/var/lib/grafana
environment:
- GF_SERVER_HTTP_ADDR=127.0.0.1
networks:
- observability
volumes:
loki-data:
grafana-data:
4. Configure Loki
Create /opt/observability/loki-config.yaml:
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/cache
filesystem:
directory: /loki/chunks
limits_config:
enforce_metric_name: false
5. Configure Alloy
Create /opt/observability/config.alloy to tail the StorageLink audit log:
local.file_match "storagelink_logs" {
path_targets = [{"__path__" = "/var/log/storagelink/audit*.log"}]
}
loki.source.file "storagelink" {
targets = local.file_match.storagelink_logs.targets
forward_to = [loki.write.default.receiver]
}
loki.write "default" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
6. Start the Stack
cd /opt/observability
sudo docker-compose up -d
7. Configure nginx Reverse Proxy
Add a server block to your nginx configuration to proxy Grafana externally over HTTPS:
server {
listen 3000 ssl;
ssl_certificate /etc/nginx/ssl/website.bundle.crt;
ssl_certificate_key /etc/nginx/ssl/website.key;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Reload nginx:
nginx -t && service nginx reload
Using the Dashboard
Once running, access Grafana at https://<your-instance-ip>:3000. The pre-built StorageLink Overview dashboard provides:
- Log volume over time
- Authentication success/failure metrics
- Data transfer by user
- Failed authentication sources
- Searchable log results
Example LogQL Queries
Search for a specific file transfer:
{job="storagelink"} |= "filename.csv"
Track uploads by a specific user:
{job="storagelink"} | json | user="john.doe"
Find failed login attempts:
{job="storagelink"} |= "authentication failed"
Grafana is bound to localhost only and all external access routes through nginx HTTPS, keeping Loki and Alloy isolated on an internal Docker network.
