-
Notifications
You must be signed in to change notification settings - Fork 30
fix: OpenTelemetry metrics collector - fix Locate query #694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
80c40f0 to
e3dd293
Compare
e3dd293 to
b7d54a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes SQL Locate queries for the OpenTelemetry metrics collector by refactoring the query building logic to use bound, typed parameters instead of interpolating values directly into SQL strings. This change addresses both security concerns (SQL injection prevention) and type handling issues across different database backends (SQLite, PostgreSQL, MySQL).
Changes:
- Introduced
LocateQueryandLocateParamtypes to separate SQL query strings from parameter values, ensuring all user-controlled values are bound as typed parameters rather than interpolated - Updated all three SQL backend implementations (SQLite, PostgreSQL, MySQL) to consume the new
LocateQueryAPI and properly bind parameters - Enhanced OpenTelemetry integration with resource attributes (service name/version/environment), ensured active_keys_count metric exists even when 0, and added username fallback logic in the metrics cron
- Added integration test for OTEL export with docker-compose setup and improved error context in existing database tests
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
crate/server_database/src/stores/sql/locate_query.rs |
Core refactoring: added LocateQuery/LocateParam types and query builder to bind all parameters instead of string interpolation |
crate/server_database/src/stores/sql/sqlite.rs |
Adapted SQLite backend to use LocateQuery and convert parameters to rusqlite::types::Value |
crate/server_database/src/stores/sql/pgsql.rs |
Adapted PostgreSQL backend to use LocateQuery with proper ToSql parameter binding |
crate/server_database/src/stores/sql/mysql.rs |
Adapted MySQL backend to use LocateQuery with mysql_async::Value parameter conversion |
crate/server/src/cron.rs |
Added fallback to default_username when hsm_admin is empty for metrics cron |
crate/server/src/core/otel_metrics.rs |
Initialize active_keys_count with 0 to ensure time series exists |
crate/server/src/core/kms/mod.rs |
Added OTEL resource attributes (service.name, service.version, deployment.environment) |
crate/server/src/tests/otel_export_integration.rs |
New integration test for OTEL metrics export via Prometheus scraping |
crate/server_database/src/tests/json_access_test.rs |
Added .context() calls to improve error diagnostics in DB tests |
docker-compose.yml |
Added otel-collector service with pinned image versions for databases and observability stack |
otel-collector-config.yaml |
Updated collector config with prometheus, otlphttp exporters |
docker-compose.otel.yml |
Removed (consolidated into main docker-compose.yml) |
.github/scripts/test_otel_export.sh |
New test script for OTEL export integration |
| Various CI scripts | Updated to integrate OTEL tests, pin wasm-pack version, improve cleanup |
README.md, OTLP_METRICS.md, CHANGELOG.md |
Documentation updates reflecting the changes |
| .map(|t| qb.bind_text(t.clone())) | ||
| .collect::<Vec<String>>() | ||
| .join(", "); | ||
| let tags_len_i64 = i64::try_from(tags_len).unwrap_or(0); |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unwrap_or(0) here could silently convert a conversion failure to 0, which would produce an incorrect SQL query. If tags_len exceeds i64::MAX, the query would match objects with zero tags instead of producing an error. Consider using .expect("tags count should fit in i64") or returning a proper error instead of silently defaulting to 0.
| let tags_len_i64 = i64::try_from(tags_len).unwrap_or(0); | |
| let tags_len_i64 = | |
| i64::try_from(tags_len).expect("tags count should fit in i64"); |
| OTLP_GRPC_PORT=4317 | ||
| PROM_PORT=8889 | ||
|
|
||
| if [[ -z "$OTLP_GRPC_PORT" || -z "$PROM_PORT" ]]; then | ||
| echo "Failed to determine published ports from docker compose." | ||
| docker compose --project-directory "$REPO_ROOT" -p "$COMPOSE_PROJECT_NAME" ps || true | ||
| exit 1 | ||
| fi | ||
|
|
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition if [[ -z "$OTLP_GRPC_PORT" || -z "$PROM_PORT" ]] will never be true because these variables are hardcoded on lines 22-23. This check appears to be dead code. If the intent was to allow these ports to be configurable via environment variables, use: OTLP_GRPC_PORT="${OTLP_GRPC_PORT:-4317}" and PROM_PORT="${PROM_PORT:-8889}" instead.
| OTLP_GRPC_PORT=4317 | |
| PROM_PORT=8889 | |
| if [[ -z "$OTLP_GRPC_PORT" || -z "$PROM_PORT" ]]; then | |
| echo "Failed to determine published ports from docker compose." | |
| docker compose --project-directory "$REPO_ROOT" -p "$COMPOSE_PROJECT_NAME" ps || true | |
| exit 1 | |
| fi | |
| OTLP_GRPC_PORT="${OTLP_GRPC_PORT:-4317}" | |
| PROM_PORT="${PROM_PORT:-8889}" |
| let otlp_endpoint = std::env::var("OTEL_EXPORT_OTLP_ENDPOINT") | ||
| .ok() | ||
| .filter(|s| !s.trim().is_empty()) | ||
| .unwrap_or_else(|| "http://127.0.0.1:14317".to_owned()); |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default OTLP endpoint port is incorrect. According to docker-compose.yml line 121, the OTLP gRPC receiver is exposed on host port 4317, not 14317. This should be "http://127.0.0.1:4317" to match the actual docker-compose configuration.
| .unwrap_or_else(|| "http://127.0.0.1:14317".to_owned()); | |
| .unwrap_or_else(|| "http://127.0.0.1:4317".to_owned()); |
| let scrape_url = std::env::var("OTEL_EXPORT_SCRAPE_URL") | ||
| .ok() | ||
| .filter(|s| !s.trim().is_empty()) | ||
| .unwrap_or_else(|| "http://127.0.0.1:18889/metrics".to_owned()); |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default Prometheus scrape endpoint port is incorrect. According to docker-compose.yml line 123, the Prometheus metrics endpoint is exposed on host port 8889, not 18889. This should be "http://127.0.0.1:8889/metrics" to match the actual docker-compose configuration.
| .unwrap_or_else(|| "http://127.0.0.1:18889/metrics".to_owned()); | |
| .unwrap_or_else(|| "http://127.0.0.1:8889/metrics".to_owned()); |
Uh oh!
There was an error while loading. Please reload this page.