Add API call observability with --summary and --quiet flags

Context

Ports the api_observability monkey-patch plugin from triage-ops into the gem as a native feature. Closes gitlab-org/quality/triage-ops#1752 (closed).

What's in this MR?

Adds an APIObservability::Tracker that instruments all HTTP calls (REST and GraphQL) and prints a per-endpoint summary at the end of a run. A --summary flag enables tracking; a --quiet flag suppresses pagination dots and section headers for cleaner CI output.

Verification

Local dry-run against gitlab-triage

All four flag combinations were run locally in dry-run mode against gitlab-org/ruby/gems/gitlab-triage using the policy below.

Policy used
resource_rules:
  issues:
    rules:
      - name: Ping old open issues
        conditions:
          state: opened
          date:
            attribute: created_at
            condition: older_than
            interval_type: months
            interval: 6
        limits:
          most_recent: 3
        actions:
          comment: "This issue has been open for over 6 months. Please triage it."
  merge_requests:
    rules:
      - name: Ping old open MRs
        conditions:
          state: opened
          date:
            attribute: created_at
            condition: older_than
            interval_type: months
            interval: 3
        limits:
          most_recent: 2
        actions:
          comment: "This MR has been open for over 3 months. Please review or close it."

No flags (baseline) — dots and headers visible, no summary
$ gitlab-triage --dry-run --source projects --source-id gitlab-org/ruby/gems/gitlab-triage --policies-file policy.yml

Performing a dry run.

=========================================================
Triaging the `gitlab-org/ruby/gems/gitlab-triage` project
=========================================================

---------------------------------------
Processing summaries & rules for issues
---------------------------------------

------------------------------------------------------
Gathering resources for rule: **Ping old open issues**
------------------------------------------------------
..

* Found 152 resources...
* Filtering resources...
* Total after filtering: 152 resources
* Limiting resources...
* Total after limiting: 3 resources

The following comments would be posted for the rule **Ping old open issues**:

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/394

This issue has been open for over 6 months. Please triage it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/393

This issue has been open for over 6 months. Please triage it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/392

This issue has been open for over 6 months. Please triage it.


-----------------------------------------------
Processing summaries & rules for merge_requests
-----------------------------------------------

---------------------------------------------------
Gathering resources for rule: **Ping old open MRs**
---------------------------------------------------
.

* Found 2 resources...
* Filtering resources...
* Total after filtering: 2 resources
* Limiting resources...
* Total after limiting: 2 resources

The following comments would be posted for the rule **Ping old open MRs**:

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/merge_requests/354

This MR has been open for over 3 months. Please review or close it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/merge_requests/353

This MR has been open for over 3 months. Please review or close it.


--summary — same output, plus API call summary at the end

The 2 paginated issue requests and 1 MR request are grouped by normalized endpoint. 154 resources counted across 3 calls.

$ gitlab-triage --dry-run --summary --source projects --source-id gitlab-org/ruby/gems/gitlab-triage --policies-file policy.yml

Performing a dry run.

=========================================================
Triaging the `gitlab-org/ruby/gems/gitlab-triage` project
=========================================================

[... same rule output as above ...]

======================================================================
  API Call Summary
======================================================================
  Total HTTP requests:  3
  Resources fetched:    154
  Rate limit waits:     0
  Elapsed time:         2.2s
----------------------------------------------------------------------
      2x  GET /projects/:id/issues?created_before&state
      1x  GET /projects/:id/merge_requests?created_before&state
======================================================================

--quiet — dots, headers, and resource counts suppressed; only action output remains
$ gitlab-triage --dry-run --quiet --source projects --source-id gitlab-org/ruby/gems/gitlab-triage --policies-file policy.yml

Performing a dry run.

The following comments would be posted for the rule **Ping old open issues**:

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/394

This issue has been open for over 6 months. Please triage it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/393

This issue has been open for over 6 months. Please triage it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/392

This issue has been open for over 6 months. Please triage it.


The following comments would be posted for the rule **Ping old open MRs**:

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/merge_requests/354

This MR has been open for over 3 months. Please review or close it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/merge_requests/353

This MR has been open for over 3 months. Please review or close it.


--summary --quiet — no mid-run noise, full call summary at the end

The summary is identical to --summary alone, confirming --quiet only suppresses mid-run output.

$ gitlab-triage --dry-run --summary --quiet --source projects --source-id gitlab-org/ruby/gems/gitlab-triage --policies-file policy.yml

Performing a dry run.

The following comments would be posted for the rule **Ping old open issues**:

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/394

This issue has been open for over 6 months. Please triage it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/393

This issue has been open for over 6 months. Please triage it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/work_items/392

This issue has been open for over 6 months. Please triage it.


The following comments would be posted for the rule **Ping old open MRs**:

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/merge_requests/354

This MR has been open for over 3 months. Please review or close it.

# https://gitlab.com/gitlab-org/ruby/gems/gitlab-triage/-/merge_requests/353

This MR has been open for over 3 months. Please review or close it.


======================================================================
  API Call Summary
======================================================================
  Total HTTP requests:  3
  Resources fetched:    154
  Rate limit waits:     0
  Elapsed time:         2.7s
----------------------------------------------------------------------
      2x  GET /projects/:id/issues?created_before&state
      1x  GET /projects/:id/merge_requests?created_before&state
======================================================================

triage-ops integration test — CI passed ✅

gitlab-org/quality/triage-ops!4147 (merged) removes the monkey-patch and points the Gemfile at this branch. Both jobs ran against the same policy and same source, both finding 877 matching MRs — confirming identical triage behavior with and without --summary.

Without --summary: standard verbose output, no summary block. Job: https://gitlab.com/gitlab-org/quality/triage-ops/-/jobs/15314899627

With --summary: same 877 resources found, plus the API breakdown at the end (908 raw API fetches = 9 paginated MR list pages + 3 metadata calls). Job: https://gitlab.com/gitlab-org/quality/triage-ops/-/jobs/15315295456

Edited by David Dieulivol

Merge request reports

Loading
Loading