Add monitoring and observability for namespace transfers

What does this MR do and why?

Implements Part 9 of the group/project async transfer epic (#586550 (closed)): adds Prometheus metrics and structured logging for group and project transfers.

Structured logging — Namespaces::TransferLogging concern

A new Namespaces::TransferLogging concern (in app/workers/concerns/namespaces/transfer_logging.rb) provides a shared build_transfer_log_payload helper that produces a standardised, stringified log payload for every transfer event. The payload includes:

Field Source
class_name Gitlab::Loggable#build_structured_payload_labkit
correlation_id Labkit::Correlation::CorrelationId.current_or_new_id
gl_namespace_id namespace being transferred
namespace_type 'group' or 'project'
transfer_state state-machine state of the namespace
error_type exception class name on failure
error_message exception message on failure
duration_s elapsed seconds (float, microsecond precision)
queue_wait_s optional: time spent waiting in Sidekiq queue
retry_count optional: Sidekiq retry count
initiated_via optional: caller context (REST/GraphQL/UI)

The concern is included in:

  • Groups::TransferService
  • Projects::TransferService
  • Namespaces::TransferWorkerHelper (shared by both workers)
  • Namespaces::Groups::TransferWorker (via the helper)
  • Projects::TransferWorker (via the helper)

All existing Gitlab::AppLogger calls in these classes are updated to use build_transfer_log_payload, replacing ad-hoc symbol-keyed hashes with the standardised stringified payload.

Prometheus metrics — Gitlab::Metrics::Transfers

A new Gitlab::Metrics::Transfers module (in lib/gitlab/metrics/transfers.rb) exposes two metrics:

gitlab_namespace_transfer_total (counter) Labels: namespace_type (group/project), result (success/failure) Incremented on every terminal outcome (success or failure), from both Groups::TransferService/Projects::TransferService and their workers.

gitlab_namespace_transfer_duration_seconds (histogram) Labels: namespace_type Observed only on the success path, in Groups::TransferService#execute and Projects::TransferService#execute. Not observed on failure: the gitlab_namespace_transfer_total{result="failure"} counter and the duration_s field in the structured failure log entry capture failed transfers instead, since failure duration isn't directly comparable across differing failure causes and would skew the success-latency distribution.

There is no transfer_type (sync/async) label: transfers are always asynchronous going forward, so the distinction is unnecessary.

The closed MR !238654 (closed) ([skip ci] Standardise transfer log payload with correlation_id) was reviewed for context. This implementation follows the same approach but also adds the Prometheus metrics layer and is complete (not a draft/placeholder).

References

Screenshots or screen recordings

N/A — backend-only change.

How to set up and validate locally

  1. Enable Prometheus metrics in your GDK.
  2. Transfer a group or project (via UI, REST API, or GraphQL).
  3. Check /metrics for gitlab_namespace_transfer_total and gitlab_namespace_transfer_duration_seconds.
  4. Check log/application_json.log for structured entries with gl_namespace_id, namespace_type, correlation_id, etc.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Edited by Shubham Kumar

Merge request reports

Loading
Loading