TelemetryFlow Core includes built-in observability features with OpenTelemetry, Prometheus, and comprehensive logging.
graph TB
subgraph "Application"
App[NestJS Backend]
OTEL_SDK[OTEL SDK<br/>Auto-Instrumentation]
Winston[Winston Logger]
end
subgraph "TelemetryFlow Collector"
Collector[TFO-Collector v1.1.1<br/>:4317 gRPC / :4318 HTTP]
Processor[Processors<br/>Batch, Memory Limiter, Resource]
Connectors[Connectors<br/>SpanMetrics, ServiceGraph]
end
subgraph "Storage & Visualization"
Jaeger[Jaeger V2<br/>:16686<br/>Traces]
Prometheus[Prometheus<br/>:9090<br/>Metrics]
Files[Log Files<br/>logs/*.log]
end
subgraph "Access Points"
Swagger[Swagger UI<br/>:3000/api]
JaegerUI[Jaeger UI<br/>Trace Viewer]
PromUI[Prometheus UI<br/>Metrics Query]
Grafana[Grafana<br/>:3001<br/>Dashboards]
end
App --> OTEL_SDK
App --> Winston
OTEL_SDK -->|OTLP HTTP :4318| Collector
Winston -->|Logs| Collector
Winston -->|Write| Files
Collector --> Processor
Processor --> Connectors
Connectors -->|SpanMetrics| Prometheus
Processor -->|OTLP gRPC :4317| Jaeger
Processor -->|Scrape :8889| Prometheus
Jaeger --> JaegerUI
Prometheus --> PromUI
Prometheus --> Grafana
App --> Swagger
style App fill:#e1f5ff
style Collector fill:#fff4e1
style Jaeger fill:#90EE90
style Prometheus fill:#FFD700
style Grafana fill:#FF6B6B
- URL: http://localhost:3000/api
- Features: Interactive API documentation, request testing
- Tags: IAM, Users, Roles, Permissions, Tenants, Organizations, Workspaces, Groups, Regions
- Export: Use
scripts/export-swagger-docs.shto export OpenAPI spec
- Location:
docs/postman/ - Files: Collection and environment with default credentials
- Requests: 30+ API requests covering all IAM endpoints
- Documentation: See
docs/postman/README.md
- Tracing: Distributed tracing for all HTTP requests
- Auto-instrumentation: HTTP, Express, NestJS, PostgreSQL
- Export: OTLP HTTP protocol
- Endpoints:
- OTLP gRPC:
http://localhost:4317 - OTLP HTTP:
http://localhost:4318 - Health Check:
http://localhost:13133 - zPages:
http://localhost:55679/debug/tracez
- OTLP gRPC:
- URL: http://localhost:9090
- Metrics Endpoint: http://localhost:8889/metrics (OTEL Collector)
- Scrape Targets: OTEL Collector, OTEL internal metrics
- Features: Time-series metrics, PromQL queries, alerting
- Structured logs: JSON format for production
- Pretty logs: Colored output for development
- Log levels: error, warn, info, debug, verbose
- Documentation: See
docs/WINSTON_LOGGER.md
# .env
OTEL_ENABLED=true
OTEL_SERVICE_NAME=telemetryflow-core
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318OTEL_ENABLED=falseTelemetryFlow uses TFO-Collector v1.1.1+ - a custom OpenTelemetry Collector with 100% OTLP compliance.
Key Features:
- OTLP gRPC (port 4317) and HTTP (port 4318) receivers/exporters
- SpanMetrics connector with exemplars support
- ServiceGraph connector for dependency visualization
- Native Jaeger V2 integration via OTLP
- Start with Docker Compose:
# Start with monitoring profile (includes TFO-Collector, Jaeger, Prometheus, Grafana)
docker-compose --profile core --profile monitoring up -d- Or manually configure TFO-Collector:
# docker-compose.yml
otel-collector:
image: telemetryflow/telemetryflow-collector:latest
command: ["--config=/etc/tfo-collector/tfo-collector.yaml"]
volumes:
- ./config/otel/tfo-collector.yaml:/etc/tfo-collector/tfo-collector.yaml:ro
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "8889:8889" # Prometheus metrics
- "13133:13133" # Health check- Configure Core Application:
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318- Start Application:
pnpm run devFor standard OpenTelemetry Collector format, use the OCB build:
otel-collector:
image: telemetryflow/telemetryflow-collector-ocb:latest
command: ["--config=/etc/tfo-collector/otel-collector.yaml"]
volumes:
- ./config/otel/otel-collector.yaml:/etc/tfo-collector/otel-collector.yaml:roExport traces directly to observability backend:
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-backend.comSupported backends:
- Jaeger (V2 with native OTLP)
- Zipkin
- Grafana Tempo
- Honeycomb
- New Relic
- Datadog
http://localhost:9090
- OTEL Collector Metrics: http://localhost:8889/metrics
- OTEL Internal Metrics: http://localhost:8888/metrics
otelcol_receiver_accepted_spans- Accepted trace spansotelcol_receiver_refused_spans- Refused trace spansotelcol_exporter_sent_spans- Exported trace spansotelcol_processor_batch_batch_send_size- Batch sizesprocess_runtime_go_mem_heap_alloc_bytes- Memory usage
Request Rate (5m average):
rate(telemetryflow_core_requests_total[5m])
Memory Usage:
process_resident_memory_bytes{job="otel-collector"}
Error Rate:
rate(telemetryflow_core_errors_total[5m])
See config/prometheus/prometheus.yml for scrape configuration.
http://localhost:3000/api
- Interactive UI: Test APIs directly from browser
- Authentication: Bearer token support
- Request/Response: See examples and schemas
- Tags: Organized by module
IAM- Identity and Access ManagementUsers- User management endpointsRoles- Role management endpointsPermissions- Permission management endpointsTenants- Tenant management endpointsOrganizations- Organization management endpointsWorkspaces- Workspace management endpointsGroups- Group management endpointsRegions- Region management endpoints
curl http://localhost:3000/api-json > openapi.json- ✅ HTTP requests (incoming/outgoing)
- ✅ Database queries (PostgreSQL)
- ✅ NestJS controllers
- ✅ Express middleware
- ✅ Custom spans (if added)
service.name: telemetryflow-coreservice.version: 1.0.0http.method: GET, POST, etc.http.url: Request URLhttp.status_code: Response statusdb.system: postgresqldb.statement: SQL query
telemetryflow-core
└─ GET /api/users
├─ PostgreSQL: SELECT * FROM users
└─ Response: 200 OK
LOG_LEVEL=info # error, warn, info, debug, verboseLOG_PRETTY_PRINT=trueOutput:
[2025-12-02T08:38:06.886Z] INFO [Bootstrap]: Application running on: http://localhost:3000
[2025-12-02T08:38:06.887Z] INFO [Bootstrap]: Swagger UI: http://localhost:3000/api
[2025-12-02T08:38:06.888Z] INFO [Bootstrap]: OpenTelemetry: Disabled
LOG_PRETTY_PRINT=falseOutput (JSON):
{"level":"info","message":"Application running on: http://localhost:3000","context":"Bootstrap","timestamp":"2025-12-02T08:38:06.886Z"}TelemetryFlow Core
└─ Swagger UI (built-in)
TelemetryFlow Core
└─ TFO-Collector v1.1.1+
├─ Jaeger V2 (traces via OTLP)
└─ SpanMetrics (derived metrics)
TelemetryFlow Core
└─ TFO-Collector v1.1.1+
├─ Jaeger V2 (traces via OTLP gRPC :4317)
├─ Prometheus (metrics via :8889)
├─ Grafana (dashboards)
└─ ServiceGraph (dependency visualization)
The project includes a ready-to-use TFO-Collector configuration at config/otel/tfo-collector.yaml.
Key Pipeline Configuration:
# Traces flow: App → TFO-Collector → Jaeger V2
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch, resource]
exporters: [otlp/jaeger, debug, spanmetrics, servicegraph]
# Derived metrics from traces (with exemplars)
metrics/spanmetrics:
receivers: [spanmetrics]
processors: [memory_limiter, batch]
exporters: [prometheus]# Start core + monitoring (recommended)
docker-compose --profile core --profile monitoring up -d
# Or start everything
docker-compose --profile all up -dThis starts:
- TFO-Collector (telemetryflow/telemetryflow-collector:latest)
- Jaeger V2 (jaegertracing/jaeger:2.13.0) with native OTLP support
- Prometheus for metrics collection
- Grafana for dashboards
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318pnpm run dev- Swagger: http://localhost:3000/api
- Jaeger: http://localhost:16686
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3001 (admin/admin)
-
Development: Disable OTEL for faster startup
OTEL_ENABLED=false
-
Production: Enable OTEL with collector
OTEL_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
-
Logging: Use structured logs in production
LOG_PRETTY_PRINT=false
-
Swagger: Disable in production (optional)
- Remove Swagger setup from main.ts
- Or add authentication guard
# Check OTEL is enabled
echo $OTEL_ENABLED
# Check endpoint is reachable
curl http://localhost:4318/v1/traces
# Check logs
pnpm run dev
# Should see: "OpenTelemetry tracing started"# Check application is running
curl http://localhost:3000/health
# Access Swagger
open http://localhost:3000/api- Check OTEL Collector is running
- Check endpoint configuration
- Check Jaeger is receiving data
- Make some API requests to generate traces
- ✅ Swagger/OpenAPI - Built-in, always available at
/api - ✅ OpenTelemetry - Optional, enable with
OTEL_ENABLED=true - ✅ Winston Logging - Always enabled, configurable levels
- ✅ Production Ready - All features production-tested
- ✅ Easy Setup - Minimal configuration required
The observability stack is complete and ready to use! 🎉