Billing events are dropped when product usage data is disabled on self-managed

Summary

Billing events are dropped on online-licensed self-managed and Dedicated instances that have opted out of product usage data, and the client still logs BillingEvents: billing event tracked.

This is the next gate after the billing_event_tracking flag removal in !260610 (merged) (https://gitlab.com/gitlab-org/gitlab/-/issues/632809). It predates that MR and is out of its scope.

Cause

Billing events use their own collector (DestinationConfiguration.billing_configuration, BillingAuthEmitter, /com.snowplowanalytics.snowplow.auth/tp2), but they still go through the shared Gitlab::Tracking::Destinations::Snowplow#event:

def event(category, action, label: nil, property: nil, value: nil, context: nil)
  return unless @event_eligibility_checker.eligible?(action)

Gitlab::Tracking::EventEligibilityChecker#eligible? is a telemetry opt-out check:

def eligible?(_event, _app_id = nil)
  snowplow_enabled? || send_usage_data?
end

The EE override only exempts Duo events (eligible_duo_event?). secrets_read and secrets_stored are not Duo events, so they are dropped. Gitlab::Tracking.billing_event returns no result, so Gitlab::BillingEvents::Client#record_usage logs BillingEvents: billing event tracked regardless.

The client already notes this in a comment: "EventEligibilityChecker checks telemetry settings, not licensing".

Conditions to reproduce

All of the following:

  1. Self-managed or Dedicated instance on an online cloud licence. Offline and legacy licences take the local-persistence path and are not affected.
  2. Snowplow not configured: snowplow_enabled = false, the self-managed default.
  3. Product usage data disabled: GITLAB_PRODUCT_USAGE_DATA_ENABLED=false, or the gitlab_product_usage_data_enabled application setting off. The environment variable takes precedence (Gitlab::Usage::ProductUsageDataSetting.enabled?).
  4. Billing otherwise enabled: !260610 (merged) merged, and secrets_manager_emit_secret_read_events / secrets_manager_emit_secret_stored_events enabled (until !260092 (merged) removes them).
  5. Trigger a CI secret read, or run the secrets stored-count worker.

Actual: BillingEvents: billing event tracked is logged, but nothing reaches the billing collector.

Expected: the event reaches the billing collector, since billing does not depend on the product usage data opt-out.

Proposal

  1. In Gitlab::Tracking::Destinations::Snowplow#event, skip the eligibility check when destination_configuration.billing?. This covers every billing caller, not just Secrets Manager. Listing event names next to the Duo exemption would need an update for each new billable feature.
  2. Make record_usage log what actually happened: log tracked only when the event was handed to the emitter, and a skipped message otherwise, consistent with the existing billing event emission skipped log for offline licences.
  3. Product/privacy confirmation that billing usage may be sent when an instance has opted out of product usage data. The Duo exemption is precedent, but it should be recorded. Update the product usage data docs accordingly.

Acceptance criteria

  • With Snowplow disabled and product usage data disabled, the billing destination emits the event.
  • The regular (non-billing) Snowplow destination still drops events in that state.
  • BillingEvents: billing event tracked is only logged when the event was emitted.
  • Destination-level specs cover both cases (the current client spec stubs Gitlab::Tracking.billing_event, so it cannot catch this).
  • Privacy/product sign-off linked here; docs updated.