Skip to content

Conversation

@Manuthor
Copy link
Contributor

@Manuthor Manuthor commented Jan 28, 2026

  • Fix SQL Locate request for OpenTelemetry metrics collector:
    • Refactored SQL Locate query building in locate_query.rs to use bound, typed parameters (LocateQuery + LocateParam) instead of interpolating values into SQL (safer + fixes type/cast handling across SQLite/Postgres/MySQL).
    • Updated the SQL backends to consume the new LocateQuery API: crate/server_database/src/stores/sql/{mysql,pgsql,sqlite}.rs.
    • Improved DB test error context in json_access_test.rs to make failures easier to diagnose.
    • OpenTelemetry wiring updates:
      • mod.rs: add OTEL resource attributes (service name/version + optional environment).
      • otel_metrics.rs: ensure active_keys_count time series exists even when 0.
      • cron.rs: fall back to default username if hsm_admin is empty.

Copy link
Contributor

Copilot AI left a 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 LocateQuery and LocateParam types 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 LocateQuery API 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);
Copy link

Copilot AI Jan 28, 2026

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.

Suggested change
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");

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +30
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

Copy link

Copilot AI Jan 28, 2026

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.

Suggested change
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}"

Copilot uses AI. Check for mistakes.
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());
Copy link

Copilot AI Jan 28, 2026

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.

Suggested change
.unwrap_or_else(|| "http://127.0.0.1:14317".to_owned());
.unwrap_or_else(|| "http://127.0.0.1:4317".to_owned());

Copilot uses AI. Check for mistakes.
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());
Copy link

Copilot AI Jan 28, 2026

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.

Suggested change
.unwrap_or_else(|| "http://127.0.0.1:18889/metrics".to_owned());
.unwrap_or_else(|| "http://127.0.0.1:8889/metrics".to_owned());

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants