This is a learning project to practice setting up and using:
- VictoriaMetrics
- VictoriaLogs
- VictoriaTraces
- OpenTelemetry
- Grafana
- AWS S3 (log archival)
- Terraform (AWS infrastructure provisioning)
- Golang (for instrumented demo app)
The goal is to understand how metrics, logs, and traces flow through a modern observability stack, how to visualize/query them in Grafana, and how to archive logs long-term to S3.
- Learn how to run a local observability stack with Docker Compose.
- Learn how OpenTelemetry can collect/forward telemetry (metrics, logs, and traces).
- Learn how VictoriaMetrics stores and serves time-series metrics.
- Learn how VictoriaLogs stores and serves logs.
- Learn how VictoriaTraces stores and serves distributed traces.
- Learn how Grafana connects to all three backends for dashboards and exploration.
- Learn how to archive logs long-term to AWS S3 with time-based partitioning.
- Learn how to provision cloud infrastructure (S3 bucket, IAM) with Terraform.
- VictoriaMetrics (
victoriametrics/victoria-metrics) - VictoriaLogs (
victoriametrics/victoria-logs) - VictoriaTraces (
victoriametrics/victoria-traces) - OpenTelemetry Collector (
otel/opentelemetry-collector-contrib) - Grafana (
grafana/grafana) - AWS S3 (long-term log archival via OTel Collector
awss3exporter) - Golang (to produce sample app telemetry)
- A Golang app emits metrics/logs/traces via the OpenTelemetry SDK.
- OpenTelemetry Collector receives telemetry on OTLP HTTP (
4318). - Metrics are exported to VictoriaMetrics; traces to VictoriaTraces.
- Logs are exported to both VictoriaLogs (hot/queryable) and AWS S3 (cold archival, partitioned by
YYYY/MM/DD/HH/MM). - Grafana reads from VictoriaMetrics, VictoriaLogs, and VictoriaTraces for dashboards and queries.
From compose.yml:
- VictoriaMetrics:
http://localhost:8428 - VictoriaLogs:
http://localhost:9201 - Grafana:
http://localhost:3000 - OpenTelemetry Collector (OTLP HTTP):
http://localhost:4318
Current retention in this setup is
2dfor VictoriaMetrics and VictoriaLogs.
- Docker + Docker Compose
- AWS account with credentials that have permissions to provision S3 and IAM resources
- Terraform installed (to provision the S3 bucket and IAM resources in
terraform/) - A
.envfile in the project root with your AWS credentials (see Getting Started) - (Optional) Go installed locally if you want to run a sample app outside containers
-
Provision AWS infrastructure with Terraform:
cd terraform terraform init terraform apply -
Create a
.envfile in the project root with your AWS credentials:AWS_ACCESS_KEY_ID=your_access_key_id AWS_SECRET_ACCESS_KEY=your_secret_access_key
The OTel Collector uses these to authenticate the
awss3log exporter. -
Start the stack:
docker compose up -d
-
Check running services:
docker compose ps
-
Open Grafana:
- URL:
http://localhost:3000 - Default credentials (unless changed):
admin/admin
- URL:
-
Stop the stack when done:
docker compose down
View all logs:
docker compose logs -fView a single service logs:
docker compose logs -f victoria-metrics
docker compose logs -f victoria-logs
docker compose logs -f opentelemetry
docker compose logs -f grafanaReset all persisted data (destructive):
docker compose down -v- Provision AWS infrastructure with Terraform (
terraform/). - Bring up the stack and verify all services are healthy.
- Send sample telemetry from the Go app using OpenTelemetry.
- Confirm data ingestion in VictoriaMetrics, VictoriaLogs, and VictoriaTraces.
- Explore data in Grafana (dashboards + query editors).
- Verify logs are being archived in the S3 bucket under
logs/YYYY/MM/DD/HH/MM. - Tune retention and collector pipelines to understand trade-offs.
.
├── compose.yml
├── .env # AWS credentials (not committed)
├── README.md
├── ARCHITECTURE.md
├── config/
│ └── otel-collector-config.yml
├── grafana-datasources.yaml
└── terraform/ # AWS infrastructure (S3 bucket, IAM)
- This is intentionally a dummy/non-production setup.
- Defaults are kept simple for learning and quick iteration.
- For production, add auth, TLS, backup strategy, and hardened configs.