Gemini.Telemetry (GeminiEx v0.0.1)

View Source

Telemetry instrumentation helpers for Gemini library.

This module provides functions to emit telemetry events for requests, streaming, and other operations throughout the library. It supports the standard telemetry events defined in the Gemini library specification:

  • [:gemini, :request, :start] - HTTP request started
  • [:gemini, :request, :stop] - HTTP request completed successfully
  • [:gemini, :request, :exception] - HTTP request failed with exception
  • [:gemini, :stream, :start] - Streaming request started
  • [:gemini, :stream, :chunk] - Streaming chunk received
  • [:gemini, :stream, :stop] - Streaming request completed
  • [:gemini, :stream, :exception] - Streaming request failed with exception

All telemetry events respect the global telemetry configuration and can be disabled by setting telemetry_enabled: false in the application config.

Types

The module works with several key data types for telemetry metadata and measurements.

Summary

Functions

Build base metadata for HTTP requests with additional context.

Build base metadata for streaming requests with additional context.

Calculate duration in milliseconds from start time.

Classify content types for telemetry metadata.

Execute a telemetry event if telemetry is enabled.

Extract model name from options or use default.

Generate unique stream IDs for telemetry tracking.

Check if content has non-text parts (for multimodal classification).

Types

content_type()

@type content_type() :: :text | :multimodal | :unknown

http_method()

@type http_method() :: :get | :post | :put | :delete | :patch | atom()

stream_id()

@type stream_id() :: binary()

telemetry_event()

@type telemetry_event() :: [atom()]

telemetry_measurements()

@type telemetry_measurements() :: map()

telemetry_metadata()

@type telemetry_metadata() :: map()

Functions

build_request_metadata(url, method, opts \\ [])

@spec build_request_metadata(binary(), http_method(), keyword()) ::
  telemetry_metadata()

Build base metadata for HTTP requests with additional context.

Creates a standardized metadata map for telemetry events related to HTTP requests, including URL, method, model, and other contextual information.

Parameters

  • url - The request URL
  • method - The HTTP method (atom)
  • opts - Optional keyword list with additional metadata

Returns

A map containing standardized request metadata.

Examples

iex> metadata = Gemini.Telemetry.build_request_metadata("/api/generate", :post, model: "gemini-pro")
iex> metadata.url
"/api/generate"
iex> metadata.method
:post
iex> metadata.model
"gemini-pro"

build_stream_metadata(url, method, stream_id, opts \\ [])

@spec build_stream_metadata(binary(), http_method(), stream_id(), keyword()) ::
  telemetry_metadata()

Build base metadata for streaming requests with additional context.

Creates a standardized metadata map for telemetry events related to streaming requests, including all standard request metadata plus stream-specific information like stream ID.

Parameters

  • url - The request URL
  • method - The HTTP method (atom)
  • stream_id - Unique identifier for the stream
  • opts - Optional keyword list with additional metadata

Returns

A map containing standardized streaming metadata.

Examples

iex> stream_id = "abc123def456"
iex> metadata = Gemini.Telemetry.build_stream_metadata("/api/stream", :post, stream_id)
iex> metadata.stream_id
"abc123def456"
iex> metadata.url
"/api/stream"

calculate_duration(start_time)

@spec calculate_duration(integer()) :: non_neg_integer()

Calculate duration in milliseconds from start time.

Computes the elapsed time between a start time (in native units) and the current time, returning the duration in milliseconds.

Parameters

Returns

Duration in milliseconds as an integer.

Examples

iex> start_time = System.monotonic_time()
iex> :timer.sleep(10)  # Sleep for 10ms
iex> duration = Gemini.Telemetry.calculate_duration(start_time)
iex> duration >= 10
true

classify_contents(contents)

@spec classify_contents(term()) :: content_type()

Classify content types for telemetry metadata.

Analyzes the content structure to determine if it contains only text, multimodal data (text + images/other media), or unknown content types. This classification helps with telemetry analysis and monitoring.

Parameters

  • contents - The content to classify (string, list, or other)

Returns

  • :text - For plain text content
  • :multimodal - For content containing non-text elements
  • :unknown - For unrecognized content types

Examples

iex> Gemini.Telemetry.classify_contents("Hello world")
:text

iex> Gemini.Telemetry.classify_contents([%{parts: [%{text: "Hello"}]}])
:text

iex> Gemini.Telemetry.classify_contents([%{parts: [%{text: "Hello"}, %{image: "data"}]}])
:multimodal

iex> Gemini.Telemetry.classify_contents(%{unknown: "format"})
:unknown

execute(event, measurements, metadata)

Execute a telemetry event if telemetry is enabled.

This function conditionally emits telemetry events based on the global telemetry configuration. If telemetry is disabled, the function returns immediately without executing the event.

Parameters

  • event - A list of atoms representing the telemetry event name
  • measurements - A map of numeric measurements (e.g., duration, size)
  • metadata - A map of contextual information about the event

Examples

iex> Gemini.Telemetry.execute([:gemini, :request, :start], %{}, %{url: "/api"})
:ok

iex> # When telemetry is disabled, no event is emitted
iex> Application.put_env(:gemini, :telemetry_enabled, false)
iex> Gemini.Telemetry.execute([:gemini, :request, :start], %{}, %{})
:ok

extract_model(opts)

@spec extract_model(keyword() | term()) :: binary()

Extract model name from options or use default.

Retrieves the model name from a keyword list of options, falling back to the system default model if not specified.

Parameters

  • opts - Keyword list of options that may contain a :model key

Returns

The model name as a string.

Examples

iex> Gemini.Telemetry.extract_model(model: "gemini-pro")
"gemini-pro"

iex> Gemini.Telemetry.extract_model([])
"gemini-2.0-flash"  # default model

iex> Gemini.Telemetry.extract_model("not a keyword list")
"gemini-2.0-flash"  # fallback to default

generate_stream_id()

@spec generate_stream_id() :: stream_id()

Generate unique stream IDs for telemetry tracking.

Creates a cryptographically secure random identifier for tracking streaming operations across multiple telemetry events.

Returns

A 16-character lowercase hexadecimal string representing a unique stream ID.

Examples

iex> stream_id = Gemini.Telemetry.generate_stream_id()
iex> is_binary(stream_id) and byte_size(stream_id) == 16
true

iex> # Stream IDs should be unique
iex> id1 = Gemini.Telemetry.generate_stream_id()
iex> id2 = Gemini.Telemetry.generate_stream_id()
iex> id1 != id2
true

has_non_text_parts?(arg1)

@spec has_non_text_parts?(term()) :: boolean()

Check if content has non-text parts (for multimodal classification).

Examines a content structure to determine if it contains any non-text elements such as images, audio, or other media types.

Parameters

  • content - A content structure with parts to examine

Returns

  • true - If the content contains non-text parts
  • false - If the content contains only text or is not recognized

Examples

iex> Gemini.Telemetry.has_non_text_parts?(%{parts: [%{text: "Hello"}]})
false

iex> Gemini.Telemetry.has_non_text_parts?(%{parts: [%{text: "Hello"}, %{image: "data"}]})
true

iex> Gemini.Telemetry.has_non_text_parts?("not a content structure")
false