Loading
Log organization_id in integration workers and services
What does this MR do and why?
Adds gl_organization_id to the integration logs, so cross-organization problems are easier to trace.
Integrations::ExecuteWorker: the done-log line now includes the organization.Integrations::UpdateService: logs one line per update (success or failure).Integrations::PropagateService: logs a start and a finish line per run.Integrations::Loggable#build_message: now includes the organization, so everylog_info,log_errorandlog_exceptioncall on an integration gets it too.
Only instance-level integrations store organization_id. Group and project integrations get it from their parent, through a new Integrations::Loggable#organization_id_for_logging helper.
The field uses Labkit::Fields::GL_ORGANIZATION_ID. The plain organization_id name is deprecated in Labkit. The new service logs use build_structured_payload_labkit.
No attribute values are logged, since they can hold secrets.
Related
- Closes #631292 (closed)
- Part of gitlab-org#22859
- Touches the same area as !259050 (merged), but the changes don't overlap.
Validation steps
- In a terminal, watch the log:
tail -f log/integrations_json.log - Then in rails c:
require 'sidekiq/testing'
Sidekiq::Testing.fake! # stops propagation jobs actually running
# Pick existing records instead of creating new ones (or create new ones if needed)
p_int = Integration.where.not(project_id: nil).first
g_int = Integration.where.not(group_id: nil).first # may be nil on a fresh GDK
# build_message / log_info: expect "gl_organization_id" in the log tail
p_int.log_info('console check')
p_int.organization_id_for_logging # equals p_int.project.organization_id
# UpdateService: expect "Integration updated" in the log tail
Integrations::UpdateService.new(
current_user: User.first, integration: p_int, attributes: { active: p_int.active }
).execute
# PropagateService: expect "started" and "finished" lines with integration_level "group"
Integrations::PropagateService.new(g_int).execute if g_int
# ExecuteWorker: this logs to the Sidekiq done-line, not integrations_json.log,
# so inspect the extra metadata directly
w = Integrations::ExecuteWorker.new
w.perform(p_int.id, {})
w.logging_extras
=> {"extra.integrations_execute_worker.integration_class"=>
"Integrations::MockMonitoring",
"extra.integrations_execute_worker.gl_organization_id"=>1}Log output
{"severity":"INFO","time":"2026-10-05T11:01:01.252Z","integration_class":"Integrations::MockMonitoring","integration_id":1,"project_id":4,"project_path":"gnuwget/Wget2","gl_organization_id":1,"message":"console check"}
{"severity":"INFO","time":"2026-10-05T11:01:27.624Z","class_name":"Integrations::UpdateService","message":"Integration updated","integration_id":1,"integration_class":"Integrations::MockMonitoring","gl_organization_id":1}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.
Related to #631292 (closed)