Skip to content

copilot --acp emits no OpenTelemetry traces or metrics (no per-session OTel tracker is created in ACP mode) #5376

Open

Description

@pkkid

Describe the bug

When the CLI runs as an ACP server (copilot --acp), it exports no OpenTelemetry signals at all: no traces, no metrics, nothing. This happens even though OTel is enabled and server-managed settings force it on. The same machine, account, and policy export normally in copilot -p and interactive mode.

The CLI log shows OTel being configured in ACP mode, but the per-session tracker is never created:

Mode OpenTelemetry configured from managed settings OpenTelemetry tracker created for session <id> Spans/metrics received
copilot -p "…" yes yes yes (2 traces + ~14 metrics within seconds)
copilot --acp (session/new + session/prompt) yes never none, not even after a clean shutdown

This means that any tool hosting Copilot through ACP (editor integrations, third-party ACP clients) is invisible to an organization's OTel monitoring, even when the enterprise telemetry policy is enforced. This is the same class of gap as #4169 (fixed for -p in v1.0.91), but ACP mode still isn't covered.

Affected version

GitHub Copilot CLI 1.0.107.

Steps to reproduce the behavior

  1. Enable OTel. I used server-managed settings (telemetry.enabled: true, exporter: otlp-http, capture_prompts: true), and I also tried COPILOT_OTEL_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:14318 and COPILOT_OTEL_FILE_EXPORTER_PATH=/tmp/otel.jsonl.

  2. Start any OTLP/HTTP receiver, or watch the file exporter path.

  3. Control: copilot -p "Reply with just: hi". Traces and metrics arrive within seconds, and the log contains [rust:otel] OpenTelemetry tracker created for session <id>.

  4. Drive one ACP turn with this minimal client (Python 3, stdlib only):

    import json, subprocess, threading, time
    p = subprocess.Popen(['copilot', '--acp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                         stderr=subprocess.DEVNULL, text=True, bufsize=1, cwd='/tmp')
    pending, nid = {}, [0]
    def send(m): p.stdin.write(json.dumps(m) + '\n'); p.stdin.flush()
    def reader():
        for line in p.stdout:
            msg = json.loads(line)
            if 'method' in msg and 'id' in msg:  # agent -> client request
                send({'jsonrpc': '2.0', 'id': msg['id'], 'result': {'outcome': {'outcome': 'cancelled'}}})
            elif msg.get('id') in pending:
                pending[msg['id']]['r'] = msg; pending[msg['id']]['e'].set()
    threading.Thread(target=reader, daemon=True).start()
    def call(method, params):
        nid[0] += 1; i = nid[0]; pending[i] = {'e': threading.Event()}
        send({'jsonrpc': '2.0', 'id': i, 'method': method, 'params': params})
        pending[i]['e'].wait(120); return pending[i]['r']
    call('initialize', {'protocolVersion': 1, 'clientCapabilities': {}})
    sid = call('session/new', {'cwd': '/tmp', 'mcpServers': []})['result']['sessionId']
    print(call('session/prompt', {'sessionId': sid, 'prompt': [{'type': 'text', 'text': 'Reply with just: hi'}]}))
    time.sleep(20)          # leave the process alive past the export interval
    p.stdin.close(); p.wait(15)  # clean shutdown, which should flush
  5. The turn completes normally (stopReason: end_turn, usage reported), but the receiver or file gets nothing: no spans and no metrics, either during the 20-second idle or after the process exits. The process never opens a connection to the OTLP endpoint.

  6. The log (~/.copilot/logs/process-*.log) shows Starting ACP server (stdio), OpenTelemetry configured from managed settings: exporter=otlp-http … and OTel session policy applied, but never OpenTelemetry tracker created for session <id>.

Expected behavior

ACP sessions emit the same OTel signals as -p and interactive sessions (invoke_agent and chat spans, github.copilot.user.message, the GenAI metrics, and so on), following the same managed-settings telemetry policy. As #4169 put it: "OTEL telemetry gets emitted no matter how copilot is triggered when OTEL is forced on in managed settings."

Additional context

  • OS: Fedora Linux 45, kernel 7.2.15, x86_64.
  • ACP client in real use: a third-party desktop app that drives copilot --acp over stdio. I reproduced it with the standalone client above, so it isn't specific to that host.
  • The ACP log also has Failed to reload managed hooks … no hook session for session id … and event was not delivered to its registered session host … no session host is registered for session …. Those warnings appear in -p mode too, so they probably aren't the cause. The one difference I found is the missing OpenTelemetry tracker created line.
  • The session's local events.jsonl is written normally in ACP mode (turns, tool calls, session.usage_record), so the session events exist; they just never reach the OTel tracker or exporter.
  • Related: copilot -p does not emit OTEL telemetry even with server-managed settings overrides #4169 (same gap in -p mode, fixed in v1.0.91).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:enterpriseGitHub Enterprise (GHE/GHES) support, org policies, and enterprise settingsarea:non-interactiveNon-interactive mode (-p), CI/CD, ACP protocol, and headless automation

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions