# `ScoutApm.Logging.ContextExtractor`

Extracts Scout APM context from the current process for log enrichment.

Reads from Process.get(:scout_apm_request) to extract:
- scout_transaction_id - TrackedRequest.id
- scout_start_time - Root layer start time (ISO 8601)
- scout_end_time - Root layer end time (ISO 8601, if completed)
- scout_duration - Request duration in seconds (if completed)
- scout_current_operation - Current span's type/name
- controller_entrypoint / job_entrypoint / custom_entrypoint - Entrypoint name
- scout_tag_{key} - Custom tags from ScoutApm.Context
- user.{key} - User context (excluding ip)
- service.name - From config

# `extract`

```elixir
@spec extract() :: [{String.t(), any()}]
```

Extracts Scout APM context from the current process.
Returns a list of {key, value} tuples suitable for log enrichment.

# `extract_from_tracked_request`

```elixir
@spec extract_from_tracked_request(ScoutApm.TrackedRequest.t()) :: [
  {String.t(), any()}
]
```

Extracts context from a specific TrackedRequest struct.

# `stash_context`

```elixir
@spec stash_context(String.t(), String.t()) :: :ok
```

Stashes Scout context into Logger metadata so it survives TrackedRequest cleanup.

Call this when a Controller or Job layer starts. The metadata persists on the
process for the entire request lifetime, so logs emitted after TrackedRequest
is cleaned up (e.g., Phoenix endpoint stop logs) still get Scout context.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
