Skip to content

Repository files navigation

Sentinel

Docker Container Log Monitoring with Telegram Alerts

Node.jsNestJSDockerTypeScriptLicense

Features | Quick Start | Configuration | API | Deployment | Development


Overview

Sentinel is a log monitoring service that streams Docker container logs in real-time and delivers intelligent notifications to Telegram. Built with NestJS and designed for production environments, it provides reliable alerting with smart batching, rate limiting, and automatic recovery mechanisms.

Why Sentinel?

  • Zero Configuration Complexity - Simple environment variables, no complex setup
  • Intelligent Alerting - Smart batching prevents notification fatigue
  • Production Hardened - Auto-reconnection, graceful shutdown, comprehensive health checks
  • Resource Efficient - Token bucket rate limiting, minimal memory footprint
  • Observable - Built-in health endpoints for Kubernetes/Docker orchestration

Features

Core Capabilities

FeatureDescription
Real-time StreamingDirect connection to Docker daemon via Unix socket
Log Level FilteringFilter by ERROR, WARN, DEBUG, INFO with pattern detection
Smart BatchingConfigurable batch intervals and sizes reduce API calls
Rate LimitingToken bucket algorithm ensures Telegram API compliance
Auto-ReconnectionExponential backoff with configurable retry attempts
Graceful LifecycleStartup/shutdown notifications, signal handling

Advanced Features

  • Telegram Forum Support - Route logs to specific topics/threads
  • Rich Formatting - HTML messages with emojis and code blocks
  • Message Truncation - Automatic handling of oversized log entries
  • Processing Statistics - Track processed, filtered, sent, and buffered counts
  • Multi-stream Demux - Proper stdout/stderr separation from Docker

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│ SENTINEL │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ Events ┌──────────────┐ HTTP ┌──────┐ │
│ │ Docker │─────────────▶│ Processor │───────────▶│ TG │ │
│ │ Service │ │ Service │ │ API │ │
│ └──────┬───────┘ └──────────────┘ └──────┘ │
│ │ │ │
│ │ /var/run/docker.sock │ Batching & Filtering │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Docker │ │ Health │◀─── /health/* │
│ │ Daemon │ │ Controller │ │
│ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘

Data Flow

  1. DockerService connects to the Docker daemon and streams container logs
  2. Log entries are parsed and emitted as events via NestJS EventEmitter
  3. ProcessorService receives events, filters by log level, and batches entries
  4. Batched logs are sent to TelegramService with rate limiting
  5. HealthController exposes endpoints for monitoring and orchestration

Quick Start

Prerequisites

  • Docker Engine 20.10+
  • Telegram Bot Token (Create one)
  • Target container to monitor

Installation

# Clone the repository
git clone https://github.com/viminizer/sentinel.git
cd sentinel
# Configure environment
cp .env.example .env

Edit .env with your configuration:

DOCKER_CONTAINER_NAME=your-app-containerTELEGRAM_BOT_TOKEN=123456789:ABCDEFGHIJKLMNOPQRSTUVWxyzTELEGRAM_CHAT_ID=-1001234567890

Deploy

# Production deployment
./deploy.sh
# Or manually with Docker Compose
docker compose up -d

Verify

# Check service health
curl http://localhost:7777/health
# View logs
docker compose logs -f sentinel

Configuration

Environment Variables

VariableRequiredDefaultDescription
DOCKER_CONTAINER_NAMEYes-Name of the container to monitor
TELEGRAM_BOT_TOKENYes-Bot token from @BotFather
TELEGRAM_CHAT_IDYes-Target chat/group ID
TELEGRAM_TOPIC_IDNo-Topic ID for forum-type groups
LOG_LEVELSNoerror,warn,debugComma-separated levels to capture
BATCH_INTERVAL_MSNo5000Batch timeout in milliseconds
MAX_BATCH_SIZENo10Maximum logs per batch
RATE_LIMIT_PER_SECONDNo25Telegram API rate limit
PORTNo7777HTTP server port
NODE_ENVNoproductionEnvironment mode
DOCKER_SOCKET_PATHNo/var/run/docker.sockDocker socket path

Log Levels

Sentinel uses pattern-based detection to classify log levels:

LevelDetection Patterns
errorerror, exception, fatal, critical, fail, failed, failure, stderr output
warnwarn, warning, caution, alert
debugdebug, trace, verbose
infoDefault fallback for unmatched patterns

Example Configurations

Minimal (Errors Only)

DOCKER_CONTAINER_NAME=api-serverTELEGRAM_BOT_TOKEN=your-tokenTELEGRAM_CHAT_ID=-100123456789LOG_LEVELS=error

High-Volume Application

DOCKER_CONTAINER_NAME=web-appTELEGRAM_BOT_TOKEN=your-tokenTELEGRAM_CHAT_ID=-100123456789LOG_LEVELS=error,warnBATCH_INTERVAL_MS=10000MAX_BATCH_SIZE=20RATE_LIMIT_PER_SECOND=15

Forum Group with Topic

DOCKER_CONTAINER_NAME=microserviceTELEGRAM_BOT_TOKEN=your-tokenTELEGRAM_CHAT_ID=-100123456789TELEGRAM_TOPIC_ID=42LOG_LEVELS=error,warn,debug

API Reference

Health Endpoints

All endpoints are served under the /health prefix.

GET /health

Full health check with all component statuses.

Response:

{
"status": "ok",
"info": {
"docker": {
"status": "up",
"streamActive": true,
"containerState": "running",
"containerHealth": "healthy"
},
"telegram": {
"status": "up",
"connected": true
},
"processor": {
"status": "up",
"processed": 1542,
"filtered": 312,
"sent": 1230,
"buffered": 3
}
}
}

GET /health/live

Kubernetes liveness probe. Returns 200 if the process is running.

Response:

{
"status": "ok"
}

GET /health/ready

Kubernetes readiness probe. Returns 200 only when fully operational.

Response:

{
"status": "ready",
"checks": {
"streamActive": true,
"telegramConnected": true
}
}

GET /health/stats

Detailed processing statistics.

Response:

{
"processor": {
"processed": 1542,
"filtered": 312,
"sent": 1230,
"buffered": 3
},
"docker": {
"streamActive": true,
"reconnectAttempts": 0
},
"telegram": {
"connected": true,
"messagesSent": 1230
}
}

Deployment

Docker Compose (Recommended)

# docker-compose.yamlservices:
sentinel:
build: .container_name: sentinelrestart: unless-stoppedenv_file:
- .envvolumes:
- /var/run/docker.sock:/var/run/docker.sock:roports:
- '7777:7777'healthcheck:
test: ['CMD', 'wget', '-q', '--spider', 'http://localhost:7777/health/live']interval: 30stimeout: 10sretries: 3

Kubernetes

apiVersion: apps/v1kind: Deploymentmetadata:
name: sentinelspec:
replicas: 1selector:
matchLabels:
app: sentineltemplate:
metadata:
labels:
app: sentinelspec:
containers:
- name: sentinelimage: your-registry/sentinel:latestports:
- containerPort: 7777envFrom:
- secretRef:
name: sentinel-secretsvolumeMounts:
- name: docker-socketmountPath: /var/run/docker.sockreadOnly: truelivenessProbe:
httpGet:
path: /health/liveport: 7777initialDelaySeconds: 10periodSeconds: 30readinessProbe:
httpGet:
path: /health/readyport: 7777initialDelaySeconds: 5periodSeconds: 10volumes:
- name: docker-sockethostPath:
path: /var/run/docker.sock

Automated Deployment

The included deploy.sh script handles:

  • Docker daemon validation
  • Environment file verification
  • Required variable checks
  • Container lifecycle management
  • Health verification
./deploy.sh

Development

Local Setup

# Install dependencies
pnpm install
# Start in development mode (with hot reload)
pnpm run start:dev
# Or use Docker Compose for development
docker compose -f docker-compose.dev.yaml up

Available Scripts

ScriptDescription
pnpm run buildCompile TypeScript to JavaScript
pnpm run startStart production server
pnpm run start:devStart with hot reload
pnpm run start:debugStart with debugger attached
pnpm run lintRun ESLint with auto-fix
pnpm run formatFormat code with Prettier
pnpm run testRun unit tests
pnpm run test:covRun tests with coverage

Project Structure

src/
├── main.ts # Application entry point
├── app.module.ts # Root module
├── config/ # Configuration management
│ ├── config.service.ts # Config loading & validation
│ └── config.schema.ts # Zod validation schemas
├── docker/ # Docker integration
│ ├── docker.service.ts # Docker daemon interaction
│ └── docker.constants.ts # Event definitions
├── telegram/ # Telegram integration
│ └── telegram.service.ts # Telegram API wrapper
├── processor/ # Log processing
│ └── processor.service.ts # Filtering & batching
├── health/ # Health checks
│ └── health.controller.ts # HTTP endpoints
└── common/ # Shared utilities
├── enums/ # Log level enums
├── interfaces/ # Type definitions
└── utils/ # Helper functions

Development Container

The docker-compose.dev.yaml includes a test container that generates sample logs:

docker compose -f docker-compose.dev.yaml up

This starts:

  • Sentinel in development mode with hot reload
  • A test container emitting INFO, DEBUG, WARN, and ERROR logs

Monitoring

Prometheus Metrics (Coming Soon)

Integration with Prometheus metrics is planned for future releases.

Log Output

Sentinel outputs structured logs suitable for log aggregation:

[Nest] 1 - 01/01/2026, 12:00:00 PM LOG [DockerService] Connected to container: my-app
[Nest] 1 - 01/01/2026, 12:00:00 PM LOG [ProcessorService] Processing log batch (5 entries)
[Nest] 1 - 01/01/2026, 12:00:01 PM LOG [TelegramService] Sent batch to chat -100123456789

Telegram Notifications

Sentinel sends notifications on:

  • Startup - Service initialization complete
  • Shutdown - Graceful termination
  • Container Events - Target container start/stop/restart
  • Log Batches - Filtered logs matching configured levels
  • Errors - Uncaught exceptions and critical failures

Troubleshooting

Common Issues

Container Not Found

Error: Container 'my-app' not found

Solution: Verify the container name matches exactly (case-sensitive) and the container is running.

docker ps --format '{{.Names}}'

Permission Denied on Docker Socket

Error: connect EACCES /var/run/docker.sock

Solution: Ensure the container has access to the Docker socket:

volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro

For rootless Docker, adjust the socket path accordingly.

Telegram Bot Not Sending Messages

Checklist:

  1. Bot token format: 123456789:ABCdef...
  2. Bot added to the target chat/group
  3. For groups, bot must have message permissions
  4. Chat ID format: Negative for groups (-100...)

Test with curl:

curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
-H "Content-Type: application/json" \
-d '{"chat_id": "<CHAT_ID>", "text": "Test"}'

High Memory Usage

Solution: Reduce batch size and interval:

BATCH_INTERVAL_MS=3000MAX_BATCH_SIZE=5

Debug Mode

Enable verbose logging:

NODE_ENV=development

Security Considerations

  • Docker Socket Access - Sentinel requires read-only access to the Docker socket. In production, consider using Docker socket proxies for additional isolation.
  • Telegram Tokens - Store bot tokens securely using environment variables or secrets management.
  • Network Exposure - The health endpoint should be restricted to internal networks or protected by authentication in production.
  • Non-Root User - The production Docker image runs as a non-root user (UID 1001).

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Guidelines

  • Follow the existing code style (ESLint + Prettier)
  • Add tests for new functionality
  • Update documentation as needed
  • Keep commits atomic and well-described

License

This project is licensed under the MIT License - see the LICENSE file for details.


Back to Top

Built with NestJS | Powered by Node.js

About

Docker Container Log Monitoring with Telegram Alerts

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages