https://github.com/rhobs/rhobs-synthetics-agent
RHOBS Synthetic Monitoring Agent
https://github.com/rhobs/rhobs-synthetics-agent
Last synced: 6 months ago
JSON representation
RHOBS Synthetic Monitoring Agent
- Host: GitHub
- URL: https://github.com/rhobs/rhobs-synthetics-agent
- Owner: rhobs
- License: apache-2.0
- Created: 2025-06-18T19:01:03.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-01-14T22:37:17.000Z (6 months ago)
- Last Synced: 2026-01-15T04:39:07.161Z (6 months ago)
- Language: Go
- Size: 318 KB
- Stars: 2
- Watchers: 0
- Forks: 7
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RHOBS Synthetics Agent
A synthetic monitoring agent for the Red Hat Observability Service (RHOBS) ecosystem that retrieves synthetic probe configurations from the RHOBS Probes API and reconciles them locally by creating `probe.monitoring.rhobs` Custom Resources for automated instantiation of synthetic monitoring probes.
## Overview
The RHOBS Synthetics Agent provides:
- **Multi-API Integration**: Polls multiple RHOBS Probes APIs simultaneously to retrieve probe configurations
- **URL Validation**: Validates target URLs before creating monitoring resources
- **Custom Resource Management**: Creates Probe CRs in Kubernetes (auto-detects `monitoring.rhobs/v1` or `monitoring.coreos.com/v1`)
- **Status Tracking**: Updates probe status (active/failed) via API calls across all configured APIs
- **Label-based Filtering**: Uses configurable label selectors to target specific probes
- **Probe Deduplication**: Automatically removes duplicate probes when fetching from multiple APIs
## Quick Start
### Building the Application
```bash
# Build the binary
make build
# Build and run immediately
make run
# Build with specific configuration
./rhobs-synthetics-agent start --config example-config.yaml
```
### Running Tests
```bash
# Run all tests with coverage
make test
# Generate detailed coverage report (creates coverage.html)
make coverage
# Run tests with race detection
make test-race
```
### Code Quality
```bash
# Run linter (auto-installs golangci-lint if needed)
make lint
# Auto-fix linting issues
make lint-fix
# Run linter for CI environments
make lint-ci
```
## Core Functionality
### Probe Reconciliation Workflow
1. **Poll APIs**: Retrieves probe configurations from multiple `/api/metrics/v1/{tenant}/probes` endpoints
2. **Deduplicate**: Removes duplicate probes by URL when multiple APIs return probes monitoring the same endpoint
3. **Filter Probes**: Uses label selectors (e.g., `private=false,`)
4. **Validate URLs**: Checks if target URLs are ready for monitoring
5. **Create Resources**: Generates Probe Custom Resources (auto-detects API group)
6. **Update Status**: Reports success/failure back to all relevant APIs via PATCH calls
### Label Selector Support
The agent uses configurable label selectors to filter probes:
```bash
# Example: Only process non-private, pending probes
LABEL_SELECTOR="private=false,"
```
### URL Validation
Before creating monitoring resources, the agent validates target URLs to prevent false positive alerts:
- Checks URL format and scheme (HTTP/HTTPS only)
- Performs HEAD requests to verify accessibility
- Handles server errors appropriately (5xx = validation failure, 4xx = acceptable)
## Configuration
### Full Configuration Example
```yaml
# config.yaml
log_level: debug
log_format: json
polling_interval: 30s
graceful_timeout: 60s
# API Configuration
api_base_urls:
- "https://observatorium-api-1.example.com"
- "https://observatorium-api-2.example.com"
- "https://observatorium-api-3.example.com"
api_tenant: "my-rhobs-tenant"
label_selector: "private=false,"
# Kubernetes Configuration
namespace: "monitoring"
# Prometheus Configuration
# remote_write_url defaults to http://thanos-receive-router-rhobs..svc.cluster.local:19291/api/v1/receive
prometheus:
remote_write_url: "" # Uses namespace-aware default, or set explicitly for cross-cluster
remote_write_tenant: "my-tenant"
cpu_requests: "200m"
cpu_limits: "1000m"
memory_requests: "512Mi"
memory_limits: "1Gi"
managed_by_operator: "observability-operator"
```
### Environment Variables
```bash
# Core settings
export LOG_LEVEL=debug
export LOG_FORMAT=json
export POLLING_INTERVAL=30s
export GRACEFUL_TIMEOUT=60s
# API configuration - comma-separated list of complete URLs
export API_URLS="https://api1.example.com/api/metrics/v1/my-rhobs-tenant/probes,https://api2.example.com/api/metrics/v1/my-rhobs-tenant/probes,https://api3.example.com/api/metrics/v1/my-rhobs-tenant/probes"
export LABEL_SELECTOR="private=false,"
# Kubernetes settings
export NAMESPACE="monitoring"
# Prometheus configuration
# PROMETHEUS_REMOTE_WRITE_URL defaults to http://thanos-receive-router-rhobs..svc.cluster.local:19291/api/v1/receive
# Only set explicitly for cross-cluster deployments:
# export PROMETHEUS_REMOTE_WRITE_URL="https://rhobs.example.com/api/metrics/v1/tenant/api/v1/receive"
export PROMETHEUS_REMOTE_WRITE_TENANT="my-tenant"
export PROMETHEUS_CPU_REQUESTS="200m"
export PROMETHEUS_CPU_LIMITS="1000m"
export PROMETHEUS_MEMORY_REQUESTS="512Mi"
export PROMETHEUS_MEMORY_LIMITS="1Gi"
export PROMETHEUS_MANAGED_BY_OPERATOR="observability-operator"
./rhobs-synthetics-agent start
```
### Command Line Flags
```bash
# Basic usage (uses namespace-aware default for remote write URL)
./rhobs-synthetics-agent start \
--config /path/to/config.yaml \
--log-level debug \
--interval 30s \
--graceful-timeout 60s \
--namespace "rhobs-stage" \
--api-urls "https://api1.example.com/api/metrics/v1/my-tenant/probes" \
--prometheus-remote-write-tenant "my-tenant"
# Cross-cluster deployment (explicit remote write URL)
./rhobs-synthetics-agent start \
--config /path/to/config.yaml \
--api-urls "https://rhobs.example.com/api/metrics/v1/my-tenant/probes" \
--prometheus-remote-write-url "https://rhobs.example.com/api/metrics/v1/my-tenant/api/v1/receive" \
--prometheus-remote-write-tenant "my-tenant"
```
## Prometheus Configuration
The agent can automatically create and manage a Prometheus instance for synthetic monitoring when running in a Kubernetes cluster. This Prometheus instance will scrape probe resources and send metrics to a remote write endpoint (typically Thanos).
### Configuration Options
| Flag | Environment Variable | Config File Key | Default | Description |
|------|---------------------|----------------|---------|-------------|
| `--prometheus-remote-write-url` | `PROMETHEUS_REMOTE_WRITE_URL` | `prometheus.remote_write_url` | `""` (uses `http://thanos-receive-router-rhobs..svc.cluster.local:19291/api/v1/receive`) | Thanos remote write endpoint URL |
| `--prometheus-remote-write-tenant` | `PROMETHEUS_REMOTE_WRITE_TENANT` | `prometheus.remote_write_tenant` | `hcp` | Thanos tenant identifier |
| `--prometheus-cpu-requests` | `PROMETHEUS_CPU_REQUESTS` | `prometheus.cpu_requests` | `100m` | CPU requests for Prometheus pod |
| `--prometheus-cpu-limits` | `PROMETHEUS_CPU_LIMITS` | `prometheus.cpu_limits` | `500m` | CPU limits for Prometheus pod |
| `--prometheus-memory-requests` | `PROMETHEUS_MEMORY_REQUESTS` | `prometheus.memory_requests` | `256Mi` | Memory requests for Prometheus pod |
| `--prometheus-memory-limits` | `PROMETHEUS_MEMORY_LIMITS` | `prometheus.memory_limits` | `512Mi` | Memory limits for Prometheus pod |
| `--prometheus-managed-by-operator` | `PROMETHEUS_MANAGED_BY_OPERATOR` | `prometheus.managed_by_operator` | `observability-operator` | Value for app.kubernetes.io/managed-by label on Prometheus resources |
## Architecture
### Components
- **API Client** (`internal/api`): Handles communication with RHOBS Probes API
- **Probe Manager** (`internal/k8s`): Manages Custom Resource creation and URL validation
- **Worker** (`internal/agent`): Orchestrates the reconciliation process
- **Configuration** (`internal/agent`): Handles all configuration sources
### Data Flow
```
Multiple APIs → Agent → Deduplication → URL Validation → Custom Resource Creation → Status Update
```
### Custom Resource Format
Generated Probe resources include (example shows `monitoring.rhobs/v1`, but `monitoring.coreos.com/v1` is also supported):
```yaml
apiVersion: monitoring.rhobs/v1
kind: Probe
metadata:
name: probe-{id}
namespace: monitoring
labels:
rhobs.monitoring/probe-id: "{id}"
rhobs.monitoring/cluster-id: "{cluster_id}"
rhobs.monitoring/management-cluster: "{management_cluster_id}"
rhobs.monitoring/managed-by: "rhobs-synthetics-agent"
spec:
interval: "30s"
module: "http_2xx"
prober_url: "synthetics-blackbox-prober-default-service:9115"
targets:
staticConfig:
static:
- "{target_url}"
labels:
apiserver_url: "{target_url}"
cluster_id: "{cluster_id}"
management_cluster_id: "{management_cluster_id}"
private: "{private_flag}"
```
## Development
### Setup Dependencies
```bash
# Download Go modules
make go-mod-download
# Clean up dependencies
make go-mod-tidy
```
### Development Cycle
```bash
# Make your changes, then run quality checks
make lint-fix
make test
make build
# Run with development settings
./rhobs-synthetics-agent start --log-level debug --interval 10s
```
### Testing
```bash
# Run all tests
make test
# Run with coverage report
make coverage
# Run specific package tests
go test -v ./internal/api -run TestClient
# Run integration tests
go test -v ./internal/agent -run TestWorker_FullIntegration
# Test with race detection
make test-race
```
### Test Coverage
Current test coverage:
- **Internal/Agent**: 67.3% (core functionality, worker processes)
- **Internal/API**: 90.9% (API client, error handling)
- **Internal/K8s**: 93.1% (resource creation, validation)
See `TEST_COVERAGE_SUMMARY.md` for detailed coverage information.
## API Reference
### RHOBS Probes API Endpoints
- `GET /api/metrics/v1/{tenant}/probes?label_selector={selectors}` - Retrieve probes
- `PATCH /api/metrics/v1/{tenant}/probes/{id}` - Update probe status
### Probe Data Model
```json
{
"id": "probe-123",
"static_url": "https://api.example.com/health",
"labels": {
"cluster_id": "cluster-456",
"management_cluster_id": "mgmt-789",
"private": "false"
},
"status": "pending"
}
```
## Deployment
### Docker Build
```bash
# Build Docker image
make docker-build
# Push to registry
make docker-push
```
### Kubernetes Deployment
The agent is designed to run as a Kubernetes Deployment with:
- Service account with permissions to create Custom Resources
- ConfigMap or Secret for API credentials
- Appropriate RBAC for Probe resources (monitoring.rhobs/v1 and/or monitoring.coreos.com/v1)
## Troubleshooting
### Common Issues
1. **API Connection Failures**
- Verify `API_URLS` and network connectivity
- Check API credentials and ensure URLs include the correct tenant
2. **URL Validation Failures**
- Review target URLs in probe configurations
- Check firewall/network policies for outbound requests
3. **Custom Resource Creation Issues**
- Verify Kubernetes permissions and RBAC
- Check if CRDs are installed: `kubectl get crd probes.monitoring.rhobs probes.monitoring.coreos.com`
### Debug Mode
```bash
# Enable debug logging
./rhobs-synthetics-agent start --log-level debug
# Use shorter polling interval for testing
./rhobs-synthetics-agent start --interval 10s --log-level debug
```
## Contributing
### Code Style
- Follow Go conventions and best practices
- Run `make lint-fix` before submitting changes
- Ensure all tests pass: `make test`
- Add tests for new functionality
### Pull Request Process
1. Fork the repository
2. Create a feature branch
3. Make changes with appropriate tests
4. Run quality checks: `make lint test`
5. Submit pull request with clear description
## License
This project follows the same license as the RHOBS ecosystem.