Observer is a service that monitors HTTP endpoints for health and availability. It periodically checks configured HTTP endpoints and records their status, response time, and content validation results.
Observer is designed to provide reliable monitoring of HTTP endpoints with the following features:
- Configurable Health Checks: Monitor multiple HTTP endpoints with customizable check intervals and timeouts
- Response Validation: Validate responses using status codes and regex patterns
- Metrics Exposure: Expose Prometheus metrics for monitoring and alerting
- Persistent Storage: Store observation results in a PostgreSQL database
- Buffered Processing: Efficiently process and store observations using a configurable buffer
- Graceful Shutdown: Handle shutdowns gracefully to ensure no data loss
- Automatic Reload: Reloads target in an interval automatically and pick up new changes
The project is structured into several packages:
-
cmd: Contains the main entry points for the application
main.go: Sets up the application and command-line interfaceobserve.go: Implements the observe command to start monitoringmigrate.go: Implements the migrate command for database migrations
-
internal: Contains internal application code
- config: Configuration loading and validation
- observer: Core monitoring functionality
registry.go: Manages targets and observersobserver.go: Implements the health check looptarget.go: Defines target configuration and validationbuffer.go: Buffers observations before storage
-
pkg: Reusable packages
- backoff: Implements retry with backoff functionality
- buffer: Generic buffer implementation
- domain: Core domain models
- logger: Logging functionality
- metrics: Prometheus metrics
- storage: Storage interfaces and implementations
- The application loads configuration from a YAML file
- The registry loads targets from a targets YAML file
- For each target, an observer is created to periodically check the endpoint
- Observations are collected in a buffer
- When the buffer reaches a threshold (items count or time), observations are stored in the database
- Metrics are exposed via an HTTP endpoint for Prometheus scraping
- Go 1.24 or later
- PostgreSQL database
- Docker and Docker Compose (optional)
-
Copy the sample configuration files:
cp config.sample.yml config.yml cp targets.sample.yml targets.yml -
Edit the configuration files to match your environment:
config.yml: Main application configurationtargets.yml: HTTP endpoints to monitor
The config.yml file contains the following configuration parameters:
environment: Specifies the current running environment (e.g., development, production)
http.addr: Address and port the HTTP server will listen on (default: ":8080")http.readTimeout: Maximum duration for reading the entire request, including the body (default: 1m)http.readHeaderTimeout: Amount of time allowed to read request headers (default: 10s)http.writeTimeout: Maximum duration before timing out writes of the response (default: 2m)http.idleTimeout: Maximum amount of time to wait for the next request when keep-alives are enabled (default: 2m)http.requestTimeout: Maximum time allowed for processing a single request (default: 10s)http.maxHeaderBytes: Maximum number of bytes the server will read parsing the request header (default: 0, no limit)http.metricsPath: URL path where metrics are exposed (default: "/metrics")
database.username: Database authentication usernamedatabase.password: Database authentication passworddatabase.host: Database server hostname or IP addressdatabase.port: Database server portdatabase.sslMode: SSL mode for database connection (e.g., disable, require)database.name: Database namedatabase.maxOpenConnections: Maximum number of open connections to the database (default: 10)database.maxIdleConnections: Maximum number of idle connections in the connection pool (default: 8)database.connMaxLifetime: Maximum amount of time a connection may be reused (default: 3m)database.connMaxIdleTime: Maximum amount of time a connection may be idle (default: 3m)
gracefulShutdownTimeout: Maximum duration to wait for ongoing requests to complete during shutdown (default: 30s)
observer.targetsFilePath: Path to the file containing target configurations (default: targets.yml)observer.targetsReloadInterval: How often the targets file should be checked for changes (default: 10s)observer.bufferItemsThreshold: Number of items that triggers a buffer flush (default: 100)observer.bufferTimeThreshold: Maximum time before a buffer flush is triggered (default: 10s)observer.bufferMaxLength: Maximum number of items the buffer can hold (default: 10000)
Example configuration:
environment: production
http:
addr: ":9090"
readTimeout: 30s
metricsPath: /prometheus/metrics
database:
username: dbuser
password: securepassword
host: db.example.com
port: 5432
name: observer_db
maxOpenConnections: 20
gracefulShutdownTimeout: 1m
observer:
targetsFilePath: /etc/observer/targets.yml
bufferItemsThreshold: 200
bufferTimeThreshold: 5s-
Start the PostgreSQL database:
make start-docker-compose -
Run the application:
make migrate-up # Run database migrations go run cmd/* -c config.yml observe # Start monitoring
-
Build the Docker image:
docker build -t observer . -
Run the container:
docker run -v /path/to/config:/app/configs -p 8080:8080 observer
The project includes several make commands to help with development:
make dependency: Install required development toolsmake install-mockgen: Install mockgen for generating mocksmake install-golangci-lint: Install golangci-lint for lintingmake install-goimports: Install goimports for import formatting
make fix-imports: Fix import formattingmake lint: Run lintingmake test: Run testsmake generate: Generate code (mocks, etc.)make install-hooks: Install git hooksmake uninstall-hooks: Uninstall git hooks
make start-docker-compose: Start PostgreSQL with Docker Composemake stop-docker-compose: Stop Docker Compose servicesmake remove-docker-compose: Remove Docker Compose containersmake clean: Clean up the environment
make create-migration name=<NAME>: Create a new database migrationmake migrate-up: Run database migrations
Targets are configured in the targets.yml file with the following properties:
url: (required) The HTTP endpoint to checkinterval: (optional) Time between checks (default: 30s)timeout: (optional) Maximum time for a request (default: 5s)regexPattern: (optional) Regular expression to validate the response bodyvalidStatusCodes: (optional) HTTP status codes considered successful (default: 200-205)
Example:
- url: https://example.com
interval: 15s
timeout: 3s
regexPattern: ".*status.*:.*ok.*"
validStatusCodes: ["200", "2xx"]