From 2ee632d4988a0292f72aebf65f2b2a8c64c8190c Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 14 Dec 2023 10:54:01 +0200 Subject: [PATCH] Restructure recorded metrics We now use tags in order to reduce the number of keys --- .../deployment/AiServicesProcessor.java | 18 +++++++++++------- .../aiservice/AiServiceMethodCreateInfo.java | 4 ---- .../AssistantResourceWithMetricsTest.java | 7 ++++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java b/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java index 9b379695d..9dbdd2afc 100644 --- a/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java +++ b/core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/AiServicesProcessor.java @@ -111,6 +111,7 @@ public class AiServicesProcessor { private static final MethodDescriptor QUARKUS_AI_SERVICES_CONTEXT_REMOVE_CHAT_MEMORY_IDS = MethodDescriptor.ofMethod( QuarkusAiServiceContext.class, "removeChatMemoryIds", void.class, Object[].class); public static final DotName CDI_INSTANCE = DotName.createSimple(Instance.class); + private static final String[] EMPTY_STRING_ARRAY = new String[0]; @BuildStep public void nativeSupport(CombinedIndexBuildItem indexBuildItem, @@ -775,7 +776,12 @@ private Optional gatherMetricsInfo(Method return Optional.empty(); } - String name = defaultAiServiceMetricName(method); + String name = "langchain4j.aiservices"; + List tags = new ArrayList<>(); + tags.add("aiservice"); + tags.add(method.declaringClass().name().withoutPackagePrefix()); + tags.add("method"); + tags.add(method.name()); AnnotationInstance timedInstance = method.annotation(MICROMETER_TIMED); if (timedInstance == null) { @@ -784,7 +790,8 @@ private Optional gatherMetricsInfo(Method if (timedInstance == null) { // we default to having all AiServices being timed - return Optional.of(new AiServiceMethodCreateInfo.MetricsInfo.Builder(name).build()); + return Optional.of(new AiServiceMethodCreateInfo.MetricsInfo.Builder(name) + .setExtraTags(tags.toArray(EMPTY_STRING_ARRAY)).build()); } AnnotationValue nameValue = timedInstance.value(); @@ -799,8 +806,9 @@ private Optional gatherMetricsInfo(Method AnnotationValue extraTagsValue = timedInstance.value("extraTags"); if (extraTagsValue != null) { - builder.setExtraTags(extraTagsValue.asStringArray()); + tags.addAll(Arrays.asList(extraTagsValue.asStringArray())); } + builder.setExtraTags(tags.toArray(EMPTY_STRING_ARRAY)); AnnotationValue longTaskValue = timedInstance.value("longTask"); if (longTaskValue != null) { @@ -838,10 +846,6 @@ private Optional gatherSpanInfo(MethodInfo m return Optional.of(new AiServiceMethodCreateInfo.SpanInfo(name)); } - private String defaultAiServiceMetricName(MethodInfo method) { - return "langchain4j.aiservices." + method.declaringClass().name().withoutPackagePrefix() + "." + method.name(); - } - private String defaultAiServiceSpanName(MethodInfo method) { return "langchain4j.aiservices." + method.declaringClass().name().withoutPackagePrefix() + "." + method.name(); } diff --git a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java index 6b2921bf9..a23d7d0f8 100644 --- a/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java +++ b/core/runtime/src/main/java/io/quarkiverse/langchain4j/runtime/aiservice/AiServiceMethodCreateInfo.java @@ -146,10 +146,6 @@ public static class MetricsInfo { private final boolean histogram; private final String description; - public MetricsInfo(String name) { - this(name, false, null, null, false, null); - } - @RecordableConstructor public MetricsInfo(String name, boolean longTask, String[] extraTags, double[] percentiles, boolean histogram, String description) { diff --git a/integration-tests/openai/src/test/java/org/acme/example/openai/aiservices/AssistantResourceWithMetricsTest.java b/integration-tests/openai/src/test/java/org/acme/example/openai/aiservices/AssistantResourceWithMetricsTest.java index 0834089a7..11c385540 100644 --- a/integration-tests/openai/src/test/java/org/acme/example/openai/aiservices/AssistantResourceWithMetricsTest.java +++ b/integration-tests/openai/src/test/java/org/acme/example/openai/aiservices/AssistantResourceWithMetricsTest.java @@ -43,7 +43,8 @@ public void noTimedAnnotations() throws InterruptedException { .statusCode(200) .body(containsString("MockGPT")); - waitForMeters(registry.find("langchain4j.aiservices.AssistantResourceWithMetrics$Assistant1.chat").timers(), 1); + waitForMeters(registry.find("langchain4j.aiservices").tag("aiservice", "AssistantResourceWithMetrics$Assistant1") + .tag("method", "chat").timers(), 1); } @Test @@ -55,8 +56,8 @@ public void timedAnnotationOnClass() throws InterruptedException { .statusCode(200) .body(containsString("MockGPT")); - waitForMeters(registry.find("langchain4j.aiservices.AssistantResourceWithMetrics$Assistant2.chat").tag("key", "value") - .timers(), 1); + waitForMeters(registry.find("langchain4j.aiservices").tag("aiservice", "AssistantResourceWithMetrics$Assistant2") + .tag("method", "chat").tag("key", "value").timers(), 1); } @Test