Add internal event tracking and logging for runner token expiry params

What does this MR do and why?

Adds internal event tracking and structured logging for the runner token expiration parameters introduced in !226128 (merged) and !226232 (merged). This is an EE-only feature.

Without observability into how these parameters are used, we can't make informed decisions about the feature's rollout or detect misuse patterns. This MR adds:

  1. Internal event tracking -- extends the existing create_ci_runner event with two custom additional_properties:
    • has_token_expiration -- set to 'true' when token_expires_at is explicitly provided
    • has_rotation_deadline -- set to 'true' when token_rotation_deadline is provided
  2. Filtered usage metrics -- 4 new metric definitions that use filter on the custom properties to count runners created with each parameter (total count + unique users, 7d/28d)
  3. Structured logging -- all token expiration validation failures are logged via Gitlab::AppLogger.info with user ID and runner type for debugging and audit purposes

Key changes

  • app/services/ci/runners/create_runner_service.rb -- adds extra_tracking_properties hook (returns {} in CE), merged into the existing create_ci_runner event's additional_properties
  • ee/app/services/ee/ci/runners/create_runner_service.rb -- overrides extra_tracking_properties to report has_token_expiration and has_rotation_deadline; wraps all validation error paths with log_token_expiration_validation_failure for structured logging
  • config/events/create_ci_runner.yml -- adds has_token_expiration and has_rotation_deadline to additional_properties
  • ee/config/metrics/counts_all/ -- 4 new filtered metric definitions (total + unique users for each property)
  • ee/spec/services/ci/runners/create_runner_service_spec.rb -- tests for tracking properties across all runner types (instance, group, project) and logging on validation failure

References

Screenshots or screen recordings

How to set up and validate locally

Prerequisites: Set up Snowplow Micro in GDK to observe Snowplow events in real time.

  1. Start the internal events monitor in one terminal:
    bin/rails runner scripts/internal_events/monitor.rb create_ci_runner
  2. In another terminal, create a runner with token expiration via the Rails console:
    user = User.find_by(admin: true)
    service = Ci::Runners::CreateRunnerService.new(
      user: user,
      params: {
        runner_type: 'instance_type',
        token_expires_at: 10.minutes.from_now,
        token_rotation_deadline: 5.minutes.from_now
      }
    )
    service.execute
  3. Observe the create_ci_runner event in the monitor with has_token_expiration: 'true' and has_rotation_deadline: 'true' in the additional properties.
  4. Verify logging on validation failure:
    service = Ci::Runners::CreateRunnerService.new(
      user: User.find_by(admin: true),
      params: { runner_type: 'instance_type', token_expires_at: 1.minute.from_now }
    )
    service.execute
    # Check log/application.json for "Token expiration validation failed" entry
  5. Run specs:
    bundle exec rspec ee/spec/services/ci/runners/create_runner_service_spec.rb \
      spec/services/ci/runners/create_runner_service_spec.rb

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Pedro Pombeiro

Merge request reports

Loading