Impact.Instrumentation.Bedrock (Impact v0.0.1)

Copy Markdown

Auto-instrumentation for AWS Bedrock LLM calls made via Req.

Wraps a Req request in an OpenTelemetry LLM span tagged with GenAI semantic convention attributes (gen_ai.system, gen_ai.request.model, token usage, tool-use detection, etc). No span code needed at the call site.

Usage

req =
  Req.new(
    method: :post,
    url: "https://bedrock-runtime.us-east-1.amazonaws.com/model/#{arn}/converse",
    json: body
  )

{:ok, response} = Impact.Instrumentation.Bedrock.request(req)

Drop this in place of Req.request(req) for any AWS Bedrock call. If the URL doesn't match a Bedrock endpoint, the call falls through to plain Req.request/1 with no span overhead.

What's captured

Request-side attributes (read from the URL and JSON body):

  • gen_ai.system = "aws.bedrock"
  • gen_ai.operation.name = "chat" (or "invoke", "converse-stream", ...)
  • gen_ai.request.model — the model ARN extracted from the URL
  • gen_ai.request.max_tokens, gen_ai.request.temperature, gen_ai.request.top_p — from inferenceConfig

Response-side attributes:

  • gen_ai.usage.input_tokens, gen_ai.usage.output_tokens
  • gen_ai.response.finish_reasons — Bedrock's stopReason
  • gen_ai.tool.names — comma-separated names of any tools the model requested in this turn (when stopReason == "tool_use")
  • impact.trace.output — the assistant's text content, when capture is on

Requirements

Add {:req, "~> 0.5"} to your application's mix.exs. Req is declared as an optional dep of :impact so apps that don't use this instrumentor don't pull it in.

Summary

Functions

Run req and emit a Bedrock LLM span. Non-Bedrock URLs pass through unchanged.

Functions

request(req)

@spec request(Req.Request.t()) :: {:ok, Req.Response.t()} | {:error, term()}

Run req and emit a Bedrock LLM span. Non-Bedrock URLs pass through unchanged.