Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add counters to Metric #784

Merged
merged 5 commits into from
Sep 4, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.xebia.functional.xef.metrics

interface CounterMetric {
fun increment(n: Long)

fun increment(n: Long, attributes: Map<String, String>)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.xebia.functional.xef.metrics

import arrow.atomic.AtomicLong
import io.github.oshai.kotlinlogging.KLogger

class InMemoryCounterMetric(val name: String, val logger: KLogger) : CounterMetric {
private val count = AtomicLong(0)

override fun increment(n: Long) {
count.incrementAndGet()
logger.info { "Counter $name incremented to ${count.get()}" }
}

override fun increment(n: Long, attributes: Map<String, String>) {
count.addAndGet(n)
logger.info {
"Counter $name incremented to ${count.get()} with those attributes: ${attributes.entries.joinToString( ",")}"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class LogsMetric(private val level: Level = Level.INFO) : Metric {

private val logger = KotlinLogging.logger {}

private val countersMap: MutableMap<String, CounterMetric> = mutableMapOf()

override suspend fun <A> customSpan(
name: String,
parameters: Map<String, String>,
Expand Down Expand Up @@ -111,5 +113,17 @@ class LogsMetric(private val level: Level = Level.INFO) : Metric {
logger.at(level) { message = "${writeIndent(numberOfBlocks.get())}|-- $key = $values" }
}

private fun writeIndent(times: Int = 1) = (1..indentSize * times).fold("") { a, b -> "$a " }
override suspend fun createCounter(name: String): CounterMetric {
logger.at(level) { message = "${writeIndent(numberOfBlocks.get())}> Created counter: $name" }
val counter = InMemoryCounterMetric(name, logger)
countersMap[name] = counter
return counter
}

override suspend fun getCounter(name: String): CounterMetric {
logger.at(level) { message = "${writeIndent(numberOfBlocks.get())}> Get counter: $name" }
return countersMap[name] ?: InMemoryCounterMetric(name, logger)
}

private fun writeIndent(times: Int = 1) = (1..indentSize * times).fold("") { a, _ -> "$a " }
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ interface Metric {

suspend fun assistantCreatedMessage(messageObject: MessageObject, source: String)

suspend fun createCounter(name: String): CounterMetric?

suspend fun getCounter(name: String): CounterMetric?

companion object {
val EMPTY: Metric =
object : Metric {
Expand All @@ -52,6 +56,10 @@ interface Metric {
override suspend fun parameter(key: String, value: String) {}

override suspend fun parameter(key: String, values: List<String>) {}

override suspend fun createCounter(name: String): CounterMetric? = null

override suspend fun getCounter(name: String): CounterMetric? = null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ suspend fun main() {
// - # docker-compose up

val metric = com.xebia.functional.xef.metrics.Metric.EMPTY
// val metric = com.xebia.functional.xef.opentelemetry.OpenTelemetryMetric()
val questionsCounter = metric.createCounter("questions-counter")

val assistant =
Assistant(
Expand All @@ -54,6 +54,7 @@ suspend fun main() {
while (true) {
println()
val userInput = readln()
questionsCounter?.increment(1)
thread.createMessage(userInput)
runAssistantAndDisplayResults(thread, assistant)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.xebia.functional.xef.opentelemetry

import com.xebia.functional.xef.metrics.CounterMetric
import io.opentelemetry.api.common.Attributes

class OpenTelemetryCounter(private val longCounter: io.opentelemetry.api.metrics.LongCounter) :
CounterMetric {
override fun increment(n: Long) {
longCounter.add(n)
}

override fun increment(n: Long, attributes: Map<String, String>) {
val attributesBuilder = Attributes.builder()
attributes.forEach { (k, v) -> attributesBuilder.put(k, v) }
longCounter.add(n, attributesBuilder.build())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.xebia.functional.xef.opentelemetry
import com.xebia.functional.openai.generated.model.MessageObject
import com.xebia.functional.openai.generated.model.RunObject
import com.xebia.functional.openai.generated.model.RunStepObject
import com.xebia.functional.xef.metrics.CounterMetric
import com.xebia.functional.xef.metrics.Metric
import com.xebia.functional.xef.prompt.Prompt
import com.xebia.functional.xef.prompt.contentAsString
import io.opentelemetry.api.metrics.Meter
import io.opentelemetry.api.trace.*

class OpenTelemetryMetric(
Expand All @@ -18,6 +20,10 @@ class OpenTelemetryMetric(

private val assistantState = OpenTelemetryAssistantState(getTracer())

private val meter = getMeter()

private val countersMap: MutableMap<String, OpenTelemetryCounter> = mutableMapOf()

override suspend fun <A> customSpan(
name: String,
parameters: Map<String, String>,
Expand All @@ -37,6 +43,14 @@ class OpenTelemetryMetric(
block()
}

override suspend fun createCounter(counterName: String): CounterMetric {
val counter = OpenTelemetryCounter(meter.counterBuilder(counterName).build())
countersMap[counterName] = counter
return counter
}

override suspend fun getCounter(counterName: String): CounterMetric? = countersMap[counterName]

override suspend fun event(message: String) {
state.event(message)
}
Expand All @@ -61,4 +75,7 @@ class OpenTelemetryMetric(

private fun getTracer(scopeName: String? = null): Tracer =
openTelemetry.getTracer(scopeName ?: config.defaultScopeName)

private fun getMeter(scopeName: String? = null): Meter =
openTelemetry.getMeter(scopeName ?: config.defaultScopeName)
}
Loading