An open-source incident management system with multi-channel alerting capabilities. Designed for modern DevOps teams to quickly respond to production incidents.
- Features
- Getting Started
- Configuration
- Environment Variables
- Custom Alert Templates
- Development
- API Usage
- Advanced API Usage
- SNS Usage
- Example
- Template Syntax
- Template Example
- Roadmap
- Contributing
- License
- Acknowledgments
- π¨ Multi-channel Alerts: Send incident notifications to Slack (more channels coming!)
- π Custom Templates: Define your own alert messages using Go templates
- π§ Easy Configuration: YAML-based configuration with environment variables support
- π‘ REST API: Simple HTTP interface to receive alerts
- Go 1.20+
- Docker 20.10+ (optional)
- Slack workspace (for Slack notifications)
docker run -p 3000:3000 \
-e SLACK_ENABLE=true \
-e SLACK_TOKEN=your_token \
-e SLACK_CHANNEL_ID=your_channel \
ghcr.io/versuscontrol/versus-incident
# Clone the repository
git clone https://github.com/sprysky/versus-incident.git
cd versus-incident
# Build with Go
go build -o versus-incident ./cmd/main.go
chmod +x versus-incident
Create run.sh
:
#!/bin/bash
export SLACK_ENABLE=true
export SLACK_TOKEN=your_token
export SLACK_CHANNEL_ID=your_channel
./versus-incident
Or run with Docker:
docker build -t versus-incident .
docker run -p 3000:3000 \
-e SLACK_ENABLE=true \
-e SLACK_TOKEN=your_token \
-e SLACK_CHANNEL_ID=your_channel \
versus-incident
A sample configuration file is located at config/config.yaml
:
name: versus
host: 0.0.0.0
port: 3000
alert:
debug_body: true # Default value, will be overridden by DEBUG_BODY env var
slack:
enable: false # Default value, will be overridden by SLACK_ENABLE env var
token: ${SLACK_TOKEN} # From environment
channel_id: ${SLACK_CHANNEL_ID} # From environment
template_path: "config/slack_message.tmpl"
telegram:
enable: false # Default value, will be overridden by TELEGRAM_ENABLE env var
bot_token: ${TELEGRAM_BOT_TOKEN} # From environment
chat_id: ${TELEGRAM_CHAT_ID} # From environment
template_path: "config/telegram_message.tmpl"
email:
enable: false # Default value, will be overridden by EMAIL_ENABLE env var
smtp_host: ${SMTP_HOST} # From environment
smtp_port: ${SMTP_PORT} # From environment
username: ${SMTP_USERNAME} # From environment
password: ${SMTP_PASSWORD} # From environment
to: ${EMAIL_TO} # From environment
subject: ${EMAIL_SUBJECT} # From environment
template_path: "config/email_message.tmpl"
queue:
enable: true
# AWS SNS
sns:
enable: false
https_endpoint_subscription_path: /sns # URI to receive SNS messages, e.g. ${host}:${port}/sns or ${https_endpoint_subscription}/sns
# Options If you want to automatically create an sns subscription
https_endpoint_subscription: ${SNS_HTTPS_ENDPOINT_SUBSCRIPTION} # If the user configures an HTTPS endpoint, then an SNS subscription will be automatically created, e.g. https://your-domain.com
topic_arn: ${SNS_TOPIC_ARN}
The application relies on several environment variables to configure alerting services. Below is an explanation of each variable:
Variable | Description |
---|---|
DEBUG_BODY |
Set to true to enable print body send to Versus Incident. |
Variable | Description |
---|---|
SLACK_ENABLE |
Set to true to enable Slack notifications. |
SLACK_TOKEN |
The authentication token for your Slack bot. |
SLACK_CHANNEL_ID |
The ID of the Slack channel where alerts will be sent. |
Variable | Description |
---|---|
TELEGRAM_ENABLE |
Set to true to enable Telegram notifications. |
TELEGRAM_BOT_TOKEN |
The authentication token for your Telegram bot. |
TELEGRAM_CHAT_ID |
The chat ID where alerts will be sent. |
Variable | Description |
---|---|
EMAIL_ENABLE |
Set to true to enable email notifications. |
SMTP_HOST |
The SMTP server hostname (e.g., smtp.gmail.com). |
SMTP_PORT |
The SMTP server port (e.g., 587 for TLS). |
SMTP_USERNAME |
The username/email for SMTP authentication. |
SMTP_PASSWORD |
The password or app-specific password for SMTP authentication. |
EMAIL_TO |
The recipient email address for incident notifications. |
EMAIL_SUBJECT |
The subject line for email notifications. |
Variable | Description |
---|---|
SNS_ENABLE |
Set to true to enable receive Alert Messages from SNS. |
SNS_HTTPS_ENDPOINT_SUBSCRIPTION |
This specifies the HTTPS endpoint to which SNS sends messages. When an HTTPS endpoint is configured, an SNS subscription is automatically created. If no endpoint is configured, you must create the SNS subscription manually using the CLI or AWS Console. E.g. https://your-domain.com |
SNS_TOPIC_ARN |
AWS ARN of the SNS topic to subscribe to |
Ensure these environment variables are properly set before running the application. You can configure them in your .env
file, Docker environment variables, or Kubernetes secrets.
Create your Slack message template, for example config/slack_message.tmpl
:
*Critical Error in {{.ServiceName}}*
----------
Error Details:
{{.Logs}}
----------
Owner <@{{.UserID}}> please investigate
For Telegram, you can use HTML formatting. Create your Telegram message template, for example config/telegram_message.tmpl
:
π¨ <b>Critical Error Detected!</b> π¨
π <b>Service:</b> {{.ServiceName}}
β οΈ <b>Error Details:</b>
{{.Logs}}
This template will be parsed with HTML tags when sending the alert to Telegram.
Create your email message template, for example config/email_message.tmpl
:
Subject: Critical Error Alert - {{.ServiceName}}
Critical Error Detected in {{.ServiceName}}
----------------------------------------
Error Details:
{{.Logs}}
Please investigate this issue immediately.
Best regards,
Versus Incident Management System
This template supports both plain text and HTML formatting for email notifications.
docker run -d \
-p 3000:3000 \
-e SLACK_ENABLE=true \
-e SLACK_TOKEN=your_slack_token \
-e SLACK_CHANNEL_ID=your_channel_id \
--name versus \
ghcr.io/versuscontrol/versus-incident
Configuration Notes
- Ensure
template_path
in config.yaml matches container path:alert: slack: template_path: "/app/config/slack_message.tmpl" # For containerized env
- File permissions: Templates must be readable by the app user (UID 1000 in Dockerfile)
- Create local config directory with your templates:
mkdir -p ./config
cp your-custom-template.tmpl ./config/slack_message.tmpl
- Run with volume mount:
docker run -d \
-p 3000:3000 \
-v $(pwd)/config:/app/config \
-e SLACK_ENABLE=true \
-e SLACK_TOKEN=your_slack_token \
-e SLACK_CHANNEL_ID=your_channel_id \
--name versus \
ghcr.io/versuscontrol/versus-incident
- Verify template mounting:
docker exec versus ls -l /app/config
- Create a secret for Slack:
# Create secret
kubectl create secret generic versus-secrets \
--from-literal=slack_token=$SLACK_TOKEN \
--from-literal=slack_channel_id=$SLACK_CHANNEL_ID
- Create ConfigMap for config and template file, for example
versus-config.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: versus-config
data:
config.yaml: |
name: versus
host: 0.0.0.0
port: 3000
alert:
slack:
enable: true
token: ${SLACK_TOKEN}
channel_id: ${SLACK_CHANNEL_ID}
template_path: "/app/config/slack_message.tmpl"
telegram:
enable: false
slack_message.tmpl: |
*Critical Error in {{.ServiceName}}*
----------
Error Details:
```
{{.Logs}}
```
----------
Owner <@{{.UserID}}> please investigate
kubectl apply -f versus-config.yaml
- Create
versus-deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: versus-incident
spec:
replicas: 2
selector:
matchLabels:
app: versus-incident
template:
metadata:
labels:
app: versus-incident
spec:
containers:
- name: versus-incident
image: ghcr.io/versuscontrol/versus-incident
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /healthz
port: 3000
env:
- name: SLACK_CHANNEL_ID
valueFrom:
secretKeyRef:
name: versus-secrets
key: slack_channel_id
- name: SLACK_TOKEN
valueFrom:
secretKeyRef:
name: versus-secrets
key: slack_token
volumeMounts:
- name: versus-config
mountPath: /app/config/config.yaml
subPath: config.yaml
- name: versus-config
mountPath: /app/config/slack_message.tmpl
subPath: slack_message.tmpl
volumes:
- name: versus-config
configMap:
name: versus-config
---
apiVersion: v1
kind: Service
metadata:
name: versus-service
spec:
selector:
app: versus
ports:
- protocol: TCP
port: 3000
targetPort: 3000
- Apply changes:
kubectl apply -f versus-deployment.yaml
- Verify template mounting:
kubectl exec -it <pod-name> -- ls -l /app/config
Create an incident:
curl -X POST http://localhost:3000/api/incidents \
-H "Content-Type: application/json" \
-d '{
"Logs": "[ERROR] This is an error log from User Service that we can obtain using Fluent Bit.",
"ServiceName": "order-service",
"UserID": "SLACK_USER_ID"
}'
Response:
{
"status":"Incident created"
}
We provide a way to overwrite configuration values using query parameters, allowing you to send alerts to different channel IDs based on the service.
Query | Description |
---|---|
slack_channel_id |
The ID of the Slack channel where alerts will be sent. Use: /api/incidents?slack_channel_id=<your_vaule> |
docker run -d \
-p 3000:3000 \
-e SLACK_ENABLE=true \
-e SLACK_TOKEN=your_slack_token \
-e SLACK_CHANNEL_ID=your_channel_id \
-e SNS_ENABLE=true \
-e SNS_TOPIC_ARN=$SNS_TOPIC_ARN \
-e SNS_HTTPS_ENDPOINT_SUBSCRIPTION=https://your-domain.com \
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY \
--name versus \
ghcr.io/versuscontrol/versus-incident
Send test message using AWS CLI:
aws sns publish \
--topic-arn $SNS_TOPIC_ARN \
--message '{"ServiceName":"test-service","Logs":"[ERROR] Test error","UserID":"U12345"}' \
--region $AWS_REGION
A key real-world application of Amazon SNS involves integrating it with CloudWatch Alarms. This allows CloudWatch to publish messages to an SNS topic when an alarm state changes (e.g., from OK to ALARM), which can then trigger notifications to Slack, Telegram, or Email via Versus Incident with a custom template
- Configuring Fluent Bit to Send Error Logs to Versus Incident
- Configuring AWS CloudWatch to Send Alerts to Slack and Telegram
- Add Telegram support
- Add Email support
- Add SNS subscription
- Add MS Team support
- Add Viber support
- Add Lark support
- Add support error logs for listeners from the queue (AWS SQS, GCP Cloud Pub/Sub, Azure Service Bus)
- Support multiple templates
- API Server for Incident Management
- Web UI
- On-call integrations (AWS Incident Manager)
- Prometheus metrics
Complete Project Diagram
We welcome contributions! Please follow these steps:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.