From accfc6ecfb8c00b880e0899d0d0fe24e18d47a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Monta=C3=B1ez?= Date: Tue, 3 Sep 2024 16:05:03 +0200 Subject: [PATCH 1/5] added metrics --- .../functional/xef/metrics/CounterMetric.kt | 7 +++++++ .../xef/metrics/InMemoryCounterMetric.kt | 15 +++++++++++++++ .../xebia/functional/xef/metrics/LogsMetric.kt | 16 +++++++++++++++- .../com/xebia/functional/xef/metrics/Metric.kt | 8 ++++++++ .../com/xebia/functional/xef/assistants/DSL.kt | 5 ++++- .../opentelemetry/docker}/docker-compose.yml | 0 .../docker}/otel-collector-config.yaml | 0 .../opentelemetry/docker}/prometheus.yaml | 0 .../xef/opentelemetry/OpenTelemetryCounter.kt | 14 ++++++++++++++ .../xef/opentelemetry/OpenTelemetryMetric.kt | 17 +++++++++++++++++ 10 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt create mode 100644 core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt rename {server/docker/opentelemetry => integrations/opentelemetry/docker}/docker-compose.yml (100%) rename {server/docker/opentelemetry => integrations/opentelemetry/docker}/otel-collector-config.yaml (100%) rename {server/docker/opentelemetry => integrations/opentelemetry/docker}/prometheus.yaml (100%) create mode 100644 integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt new file mode 100644 index 000000000..78e6bb060 --- /dev/null +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt @@ -0,0 +1,7 @@ +package com.xebia.functional.xef.metrics + +interface CounterMetric { + fun increment(n: Long) + + fun decrement(n: Long) +} diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt new file mode 100644 index 000000000..dcd03c898 --- /dev/null +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt @@ -0,0 +1,15 @@ +package com.xebia.functional.xef.metrics + +import arrow.atomic.AtomicLong + +class InMemoryCounterMetric : CounterMetric { + private val count = AtomicLong(0) + + override fun increment(n: Long) { + count.incrementAndGet() + } + + override fun decrement(n: Long) { + count.decrementAndGet() + } +} diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt index c64c4d194..9304df7bc 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt @@ -18,6 +18,8 @@ class LogsMetric(private val level: Level = Level.INFO) : Metric { private val logger = KotlinLogging.logger {} + private val countersMap: MutableMap = mutableMapOf() + override suspend fun customSpan( name: String, parameters: Map, @@ -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() + 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() + } + + private fun writeIndent(times: Int = 1) = (1..indentSize * times).fold("") { a, _ -> "$a " } } diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/Metric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/Metric.kt index e7a1f47f0..3a38359af 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/Metric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/Metric.kt @@ -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 { @@ -52,6 +56,10 @@ interface Metric { override suspend fun parameter(key: String, value: String) {} override suspend fun parameter(key: String, values: List) {} + + override suspend fun createCounter(name: String): CounterMetric? = null + + override suspend fun getCounter(name: String): CounterMetric? = null } } } diff --git a/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt b/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt index 04c13c081..3a83692be 100644 --- a/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt +++ b/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt @@ -42,7 +42,9 @@ suspend fun main() { // - # docker-compose up val metric = com.xebia.functional.xef.metrics.Metric.EMPTY - // val metric = com.xebia.functional.xef.opentelemetry.OpenTelemetryMetric() + // val metric = com.xebia.functional.xef.opentelemetry.OpenTelemetryMetric() + // val metric = com.xebia.functional.xef.metrics.LogsMetric() + val questionsCounter = metric.createCounter("questions-counter") val assistant = Assistant( @@ -54,6 +56,7 @@ suspend fun main() { while (true) { println() val userInput = readln() + questionsCounter?.increment(1) thread.createMessage(userInput) runAssistantAndDisplayResults(thread, assistant) } diff --git a/server/docker/opentelemetry/docker-compose.yml b/integrations/opentelemetry/docker/docker-compose.yml similarity index 100% rename from server/docker/opentelemetry/docker-compose.yml rename to integrations/opentelemetry/docker/docker-compose.yml diff --git a/server/docker/opentelemetry/otel-collector-config.yaml b/integrations/opentelemetry/docker/otel-collector-config.yaml similarity index 100% rename from server/docker/opentelemetry/otel-collector-config.yaml rename to integrations/opentelemetry/docker/otel-collector-config.yaml diff --git a/server/docker/opentelemetry/prometheus.yaml b/integrations/opentelemetry/docker/prometheus.yaml similarity index 100% rename from server/docker/opentelemetry/prometheus.yaml rename to integrations/opentelemetry/docker/prometheus.yaml diff --git a/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt b/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt new file mode 100644 index 000000000..8c3a9dfef --- /dev/null +++ b/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt @@ -0,0 +1,14 @@ +package com.xebia.functional.xef.opentelemetry + +import com.xebia.functional.xef.metrics.CounterMetric + +class OpenTelemetryCounter(private val longCounter: io.opentelemetry.api.metrics.LongCounter) : + CounterMetric { + override fun increment(n: Long) { + longCounter.add(n) + } + + override fun decrement(n: Long) { + longCounter.add(n) + } +} diff --git a/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryMetric.kt b/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryMetric.kt index 34f859818..a6bdbd7f0 100644 --- a/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryMetric.kt +++ b/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryMetric.kt @@ -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( @@ -18,6 +20,10 @@ class OpenTelemetryMetric( private val assistantState = OpenTelemetryAssistantState(getTracer()) + private val meter = getMeter() + + private val countersMap: MutableMap = mutableMapOf() + override suspend fun customSpan( name: String, parameters: Map, @@ -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) } @@ -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) } From e908824d8255a4e7be454049ae3933eb65e053a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Monta=C3=B1ez?= Date: Wed, 4 Sep 2024 14:21:46 +0200 Subject: [PATCH 2/5] added logger in in-memory-metrics --- .../xebia/functional/xef/metrics/InMemoryCounterMetric.kt | 5 ++++- .../kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt index dcd03c898..f032e95b1 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt @@ -1,15 +1,18 @@ package com.xebia.functional.xef.metrics import arrow.atomic.AtomicLong +import io.github.oshai.kotlinlogging.KLogger -class InMemoryCounterMetric : CounterMetric { +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 decrement(n: Long) { count.decrementAndGet() + logger.info { "Counter $name decremented to ${count.get()}" } } } diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt index 9304df7bc..ac18ca81f 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/LogsMetric.kt @@ -115,14 +115,14 @@ class LogsMetric(private val level: Level = Level.INFO) : Metric { override suspend fun createCounter(name: String): CounterMetric { logger.at(level) { message = "${writeIndent(numberOfBlocks.get())}> Created counter: $name" } - val counter = InMemoryCounterMetric() + 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() + return countersMap[name] ?: InMemoryCounterMetric(name, logger) } private fun writeIndent(times: Int = 1) = (1..indentSize * times).fold("") { a, _ -> "$a " } From 22bc441f95670b9c2647093114c211eaf9780786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Monta=C3=B1ez?= Date: Wed, 4 Sep 2024 15:39:53 +0200 Subject: [PATCH 3/5] removed decrement and added attributes --- .../com/xebia/functional/xef/metrics/CounterMetric.kt | 2 +- .../xebia/functional/xef/metrics/InMemoryCounterMetric.kt | 6 +++--- .../functional/xef/opentelemetry/OpenTelemetryCounter.kt | 7 +++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt index 78e6bb060..bf74f12a3 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/CounterMetric.kt @@ -3,5 +3,5 @@ package com.xebia.functional.xef.metrics interface CounterMetric { fun increment(n: Long) - fun decrement(n: Long) + fun increment(n: Long, attributes: Map) } diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt index f032e95b1..7e7924cde 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt @@ -11,8 +11,8 @@ class InMemoryCounterMetric(val name: String, val logger: KLogger) : CounterMetr logger.info { "Counter $name incremented to ${count.get()}" } } - override fun decrement(n: Long) { - count.decrementAndGet() - logger.info { "Counter $name decremented to ${count.get()}" } + override fun increment(n: Long, attributes: Map) { + count.addAndGet(n) + logger.info { "Counter $name incremented to ${count.get()} with those attributes: ${attributes.entries.joinToString( ",")}" } } } diff --git a/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt b/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt index 8c3a9dfef..45899bcda 100644 --- a/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt +++ b/integrations/opentelemetry/src/main/kotlin/com/xebia/functional/xef/opentelemetry/OpenTelemetryCounter.kt @@ -1,6 +1,7 @@ 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 { @@ -8,7 +9,9 @@ class OpenTelemetryCounter(private val longCounter: io.opentelemetry.api.metrics longCounter.add(n) } - override fun decrement(n: Long) { - longCounter.add(n) + override fun increment(n: Long, attributes: Map) { + val attributesBuilder = Attributes.builder() + attributes.forEach { (k, v) -> attributesBuilder.put(k, v) } + longCounter.add(n, attributesBuilder.build()) } } From 14d49737da70af7a152e277f3b987a4dcddb1509 Mon Sep 17 00:00:00 2001 From: Montagon Date: Wed, 4 Sep 2024 13:41:20 +0000 Subject: [PATCH 4/5] Apply spotless formatting --- .../com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt index 7e7924cde..7cd302fb3 100644 --- a/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt +++ b/core/src/commonMain/kotlin/com/xebia/functional/xef/metrics/InMemoryCounterMetric.kt @@ -13,6 +13,8 @@ class InMemoryCounterMetric(val name: String, val logger: KLogger) : CounterMetr override fun increment(n: Long, attributes: Map) { count.addAndGet(n) - logger.info { "Counter $name incremented to ${count.get()} with those attributes: ${attributes.entries.joinToString( ",")}" } + logger.info { + "Counter $name incremented to ${count.get()} with those attributes: ${attributes.entries.joinToString( ",")}" + } } } From cff5c6ea8e611d02a0e0e7716fbd3b3733c2a925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Monta=C3=B1ez?= Date: Wed, 4 Sep 2024 15:53:07 +0200 Subject: [PATCH 5/5] Update examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt Co-authored-by: Francisco Diaz --- .../src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt b/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt index 3a83692be..849c9f5af 100644 --- a/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt +++ b/examples/src/main/kotlin/com/xebia/functional/xef/assistants/DSL.kt @@ -42,8 +42,6 @@ suspend fun main() { // - # docker-compose up val metric = com.xebia.functional.xef.metrics.Metric.EMPTY - // val metric = com.xebia.functional.xef.opentelemetry.OpenTelemetryMetric() - // val metric = com.xebia.functional.xef.metrics.LogsMetric() val questionsCounter = metric.createCounter("questions-counter") val assistant =