Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 85 additions & 54 deletions agents/agents-features/agents-features-opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,31 @@ install(OpenTelemetry) {

The example includes the following configuration methods:

| Name | Data type | Required | Description |
|--------------------|-----------|----------|----------------------------------------------------------------------------------------------------------------------|
| `setServiceInfo` | Unit | No | Sets the information about the service being instrumented, including service name, version and namespace (optional). |
| `addSpanExporter` | Unit | No | Adds a span exporter to send telemetry data to external systems or for logging purposes. |
| Name | Data type | Required | Description |
|--------------------|-----------|----------|-------------------------------------------------------------------------------------------------|
| `setServiceInfo` | Unit | No | Sets the information about the service being instrumented, including service name and version. |
| `addSpanExporter` | Unit | No | Adds a span exporter to send telemetry data to external systems or for logging purposes. |

Please see below the full list of available configuration properties:

| Name | Data type | Default value | Description |
|--------------------|--------------------|---------------|------------------------------------------------------------------------------|
| `serviceName` | `String` | `ai.koog` | The name of the service being instrumented. |
| `serviceVersion` | `String` | `` | The version of the service being instrumented. |
| `serviceNamespace` | `String?` | `null` | The namespace of the service being instrumented (optional). |
| `serviceVersion` | `String` | `0.0.0` | The version of the service being instrumented. |
| `sdk` | `OpenTelemetrySdk` | | The OpenTelemetry SDK instance to use for telemetry collection. |
| `isVerbose` | `Boolean` | `false` | Whether to enable verbose logging for debugging OpenTelemetry configuration. |
| `tracer` | `Tracer` | | The OpenTelemetry tracer instance used for creating spans. |

Configuration API:

| Name | Arguments | Description |
|-------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| `setServiceInfo` | `serviceName: String, serviceVersion: String, serviceNamespace: String?` | Sets the service information including name, version and optional namespace. |
| `addSpanExporter` | `exporter: SpanExporter` | Adds a span exporter to send telemetry data to external systems. |
| `addSpanProcessor` | `processor: SpanProcessor` | Adds a span processor to process spans before they are exported. |
| `addResourceAttributes` | `attributes: Map<String, String>` | Adds resource attributes to provide additional context about the service. |
| `setSampler` | `sampler: Sampler` | Sets the sampling strategy to control which spans are collected. |
| `setVerbose` | `verbose: Boolean` | Enables or disables verbose logging for debugging OpenTelemetry configuration. |
| Name | Arguments | Description |
|-------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------|
| `setServiceInfo` | `serviceName: String, serviceVersion: String` | Sets the service information including name and version. |
| `addSpanExporter` | `exporter: SpanExporter` | Adds a span exporter to send telemetry data to external systems. |
| `addSpanProcessor` | `processor: (SpanExporter) -> SpanProcessor` | Adds a span processor creator function to process spans before they are exported. |
| `addResourceAttributes` | `attributes: Map<AttributeKey<T>, T> where T : Any` | Adds resource attributes to provide additional context about the service. |
| `setSampler` | `sampler: Sampler` | Sets the sampling strategy to control which spans are collected. |
| `setVerbose` | `verbose: Boolean` | Enables or disables verbose logging for debugging OpenTelemetry configuration. |


### Advanced configuration
Expand All @@ -99,9 +98,9 @@ install(OpenTelemetry) {

// Add resource attributes
addResourceAttributes(mapOf(
AttributeKey.stringKey(OpenTelemetryConfig.DEPLOYMENT_ENVIRONMENT to "production"),
AttributeKey.stringKey("custom.attribute") to "custom-value")
)
AttributeKey.stringKey("deployment.environment") to "production",
AttributeKey.stringKey("custom.attribute") to "custom-value"
))
}
```

Expand All @@ -115,49 +114,78 @@ to use. The available method is:
#### Resource attributes

Resource attributes represent additional information about a process producing telemetry. This information can be
included in an OpenTelemetry configuration in Koog using the `addResourceAttribute()` method that takes a key and
a string value as its arguments. Standard resource attribute keys are provided as constants such as `OpenTelemetryConfig.DEPLOYMENT_ENVIRONMENT` and are as follows:
included in an OpenTelemetry configuration in Koog using the `addResourceAttributes()` method that takes a map of
`AttributeKey<T>` to values of type `T`.

The following default resource attributes are automatically added:

- `service.name`: The name of the service being instrumented. Set to the value of `serviceName`.
- `service.version`: The version of the service being instrumented. Set to the value of `serviceVersion`.
- `service.instance.time`: The timestamp when the service instance was created.
- `os.type`: The operating system type.
- `os.version`: The operating system version.
- `os.arch`: The operating system architecture.

The OpenTelemetry feature automatically adds various attributes to spans following the [OpenTelemetry Semantic Convention for GenAI](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/):

### Common Attributes

- `gen_ai.operation.name`: the type of operation being performed (e.g., "create_agent", "invoke_agent", "chat", "execute_tool")
- `gen_ai.system`: the LLM provider being used
- `gen_ai.agent.id`: the ID of the agent
- `gen_ai.agent.name`: the name of the agent (when available)
- `gen_ai.conversation.id`: the ID of the conversation/run
- `gen_ai.request.model`: the LLM model being used
- `gen_ai.request.temperature`: the temperature parameter for the LLM request
- `error.type`: the type of error that occurred (when applicable)

### Custom Attributes

Some custom attributes specific to Koog are also added:

- `koog.agent.strategy.name`: the name of the agent strategy
- `koog.node.name`: the name of the node being executed

### Span Types

- `SERVICE_NAME`: The name of the service being instrumented. Automatically inferred from the `serviceName` property, if set.
- `SERVICE_VERSION`: The version of the service being instrumented. Automatically inferred from the `serviceVersion` property, if set.
- `DEPLOYMENT_ENVIRONMENT`: The label for the deployment environment where the process is running. For example, `production`.
The OpenTelemetry feature creates different types of spans for various operations:

The OpenTelemetry feature automatically adds various attributes to spans:
1. **Create Agent Span**: Represents the creation of an agent
- Key attributes: `gen_ai.operation.name` (create_agent), `gen_ai.agent.id`, `gen_ai.request.model`

- `koog.event.strategy.name`: the name of the agent strategy
- `koog.event.eventId`: the ID of the event
- `koog.event.result`: the result of the agent execution
- `koog.llm.call.prompt`: the prompt sent to the LLM
- `koog.llm.call.responses`: the responses received from the LLM
- `koog.tool.name`: the name of the tool being called
- `koog.tool.args`: the arguments passed to the tool
- `koog.tool.call.result`: indicates a successful tool call result
2. **Invoke Agent Span**: Represents a specific agent run
- Key attributes: `gen_ai.operation.name` (invoke_agent), `gen_ai.agent.id`, `gen_ai.conversation.id`

3. **Node Execute Span**: Represents the execution of a node in the agent strategy
- Key attributes: `gen_ai.conversation.id`, `koog.node.name`

4. **Inference Span**: Represents an LLM call
- Key attributes: `gen_ai.operation.name` (chat), `gen_ai.conversation.id`, `gen_ai.request.model`, `gen_ai.request.temperature`

5. **Execute Tool Span**: Represents a tool call
- Key attributes: `gen_ai.tool.name`, `gen_ai.tool.description`

## Exporters

Exporters send collected telemetry data to an OpenTelemetry Collector or other types of destinations or backend implementations.

### OTLP Exporter
### OTLP Exporter example

The OTLP (OpenTelemetry Protocol) exporter sends telemetry data to an OpenTelemetry Collector. This is useful for integrating with systems like Jaeger, Zipkin, or Prometheus.

To add an OpenTelemetry Exporter, use the `addOtlpExporter` function. The function takes a single argument:

| Name | Data type | Required | Default | Description |
|------------|-----------|----------|-------------------------|-----------------------------------------------------------------------------------------|
| `endpoint` | String | No | `http://localhost:4317` | The address of the OpenTelemetry backend or Collector for the collected telemetry data. |

To add an OpenTelemetry Exporter, use the `addSpanExporter` function to a custom exporter:
```kotlin
install(OpenTelemetry) {
// The default endpoint is http://localhost:4317
addOtlpExporter()

// Specify a custom endpoint
addOtlpExporter("http://my-otel-collector:4317")
addSpanExporter(
OtlpGrpcSpanExporter.builder()
.setEndpoint("http://localhost:4317")
.build()
)
}
```

### Logging Exporter
### Logging Exporter example

A logging exporter that outputs trace information to the console is included by default. This type of export is useful
for development and debugging purposes.
Expand All @@ -166,7 +194,6 @@ for development and debugging purposes.
install(OpenTelemetry) {
// The logging exporter is added by default
addSpanExporter(LoggingSpanExporter.create())
// You can add additional exporters as needed
}
```

Expand All @@ -191,8 +218,11 @@ services:
2. Configure your agent to use the OTLP exporter:
```kotlin
install(OpenTelemetry) {
serviceName = "my-agent-service"
addOtlpExporter() // The default endpoint is http://localhost:4317
addSpanExporter(
OtlpGrpcSpanExporter.builder()
.setEndpoint("http://localhost:4317")
.build()
)
}
```

Expand All @@ -215,8 +245,8 @@ suspend fun main() {
systemPrompt = "You are a code assistant. Provide concise code examples.",
installFeatures = {
install(OpenTelemetry) {
serviceName = "my-otlp-agent"
addOtlpExporter()
setServiceInfo("my-otlp-agent", "1.0.0")
addSpanExporter(LoggingSpanExporter.create())
}
}
)
Expand All @@ -240,18 +270,19 @@ suspend fun main() {
systemPrompt = "You are a helpful assistant.",
installFeatures = {
install(OpenTelemetry) {
serviceName = "advanced-agent"
serviceVersion = "2.0.0"
// Configure service info
setServiceInfo("advanced-agent", "2.0.0")

// Configure sampling
sampler = Sampler.alwaysOn()
setSampler(Sampler.alwaysOn())

// Add resource attributes
addResourceAttribute(OpenTelemetryConfig.DEPLOYMENT_ENVIRONMENT, "staging")
addResourceAttribute("code.source", "documentation-example")
addResourceAttributes(mapOf(
AttributeKey.stringKey("deployment.environment") to "production",
AttributeKey.stringKey("custom.attribute") to "custom-value"
))

// Add exporters
addOtlpExporter("http://otel-collector:4317")
addSpanExporter(LoggingSpanExporter.create())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ val generateProductProperties = tasks.register("generateProductProperties") {
propertiesFile.asFile.parentFile.mkdirs()
propertiesFile.asFile.writeText("""
version=$rootProjectVersion
serviceName=$rootProjectGroup
name=$rootProjectGroup
""".trimIndent())
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
* - gen_ai.tool.description (recommended)
* - gen_ai.tool.name (recommended)
*/
internal object SpanAttributes {

Check warning on line 39 in agents/agents-features/agents-features-opentelemetry/src/jvmMain/kotlin/ai/koog/agents/features/opentelemetry/attribute/SpanAttributes.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Class `SpanAttributes` coverage is below the threshold 50%

Check warning on line 39 in agents/agents-features/agents-features-opentelemetry/src/jvmMain/kotlin/ai/koog/agents/features/opentelemetry/attribute/SpanAttributes.kt

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Check Kotlin and Java source code coverage

Constructor `SpanAttributes` coverage is below the threshold 50%

// gen_ai.operation
sealed interface Operation : GenAIAttribute {
Expand Down Expand Up @@ -145,7 +145,7 @@
}

// gen_ai.request.model
data class Model(private val model: LLModel, ) : Request {
data class Model(private val model: LLModel) : Request {
override val key: String = super.key.concatKey("model")
override val value: String = model.id
}
Expand Down
Loading
Loading