diff --git a/apps/server/otel/grafana/dashboards/airi-server-overview-cloud.json b/apps/server/otel/grafana/dashboards/airi-server-overview-cloud.json index 2cd967697..f0226c83a 100644 --- a/apps/server/otel/grafana/dashboards/airi-server-overview-cloud.json +++ b/apps/server/otel/grafana/dashboards/airi-server-overview-cloud.json @@ -561,8 +561,8 @@ "type": "timeseries", "targets": [ { - "expr": "sum by (model) (rate(llm_request_count_total{service_name=~\"$service\", deployment_environment=~\"$env\"}[$__rate_interval]))", - "legendFormat": "{{model}}" + "expr": "sum by (gen_ai_request_model) (rate(llm_request_count_total{service_name=~\"$service\", deployment_environment=~\"$env\", gen_ai_request_model!=\"\"}[$__rate_interval]))", + "legendFormat": "{{gen_ai_request_model}}" } ] }, @@ -584,8 +584,12 @@ "type": "timeseries", "targets": [ { - "expr": "sum by (type) (rate(llm_request_count_total{service_name=~\"$service\", deployment_environment=~\"$env\"}[$__rate_interval]))", - "legendFormat": "{{type}}" + "expr": "sum by (gen_ai_operation_name) (rate(llm_request_count_total{service_name=~\"$service\", deployment_environment=~\"$env\", gen_ai_operation_name!=\"\"}[$__rate_interval]))", + "legendFormat": "{{gen_ai_operation_name}}" + }, + { + "expr": "sum by (airi_gen_ai_operation_kind) (rate(llm_request_count_total{service_name=~\"$service\", deployment_environment=~\"$env\", airi_gen_ai_operation_kind!=\"\"}[$__rate_interval]))", + "legendFormat": "{{airi_gen_ai_operation_kind}}" } ] }, @@ -607,8 +611,8 @@ "type": "timeseries", "targets": [ { - "expr": "histogram_quantile(0.95, sum by (le, model) (rate(llm_request_duration_milliseconds_bucket{service_name=~\"$service\", deployment_environment=~\"$env\"}[$__rate_interval])))", - "legendFormat": "{{model}}" + "expr": "histogram_quantile(0.95, sum by (le, gen_ai_request_model) (rate(llm_request_duration_milliseconds_bucket{service_name=~\"$service\", deployment_environment=~\"$env\", gen_ai_request_model!=\"\"}[$__rate_interval])))", + "legendFormat": "{{gen_ai_request_model}}" } ] }, @@ -630,8 +634,8 @@ "type": "timeseries", "targets": [ { - "expr": "sum by (model) (rate(flux_consumed_total{service_name=~\"$service\", deployment_environment=~\"$env\"}[$__rate_interval]))", - "legendFormat": "{{model}}" + "expr": "sum by (gen_ai_request_model) (rate(flux_consumed_total{service_name=~\"$service\", deployment_environment=~\"$env\", gen_ai_request_model!=\"\"}[$__rate_interval]))", + "legendFormat": "{{gen_ai_request_model}}" } ] }, @@ -653,8 +657,8 @@ "type": "timeseries", "targets": [ { - "expr": "sum by (model) (rate(llm_tokens_prompt_total{service_name=~\"$service\", deployment_environment=~\"$env\"}[$__rate_interval]))", - "legendFormat": "{{model}}" + "expr": "sum by (gen_ai_request_model) (rate(llm_tokens_prompt_total{service_name=~\"$service\", deployment_environment=~\"$env\", gen_ai_request_model!=\"\"}[$__rate_interval]))", + "legendFormat": "{{gen_ai_request_model}}" } ] }, @@ -676,8 +680,8 @@ "type": "timeseries", "targets": [ { - "expr": "sum by (model) (rate(llm_tokens_completion_total{service_name=~\"$service\", deployment_environment=~\"$env\"}[$__rate_interval]))", - "legendFormat": "{{model}}" + "expr": "sum by (gen_ai_request_model) (rate(llm_tokens_completion_total{service_name=~\"$service\", deployment_environment=~\"$env\", gen_ai_request_model!=\"\"}[$__rate_interval]))", + "legendFormat": "{{gen_ai_request_model}}" } ] }, diff --git a/apps/server/src/utils/observability.ts b/apps/server/src/utils/observability.ts new file mode 100644 index 000000000..6b4844d8e --- /dev/null +++ b/apps/server/src/utils/observability.ts @@ -0,0 +1,30 @@ +export const GEN_AI_ATTR_OPERATION_NAME = 'gen_ai.operation.name' +export const GEN_AI_ATTR_REQUEST_MODEL = 'gen_ai.request.model' +export const GEN_AI_ATTR_USAGE_INPUT_TOKENS = 'gen_ai.usage.input_tokens' +export const GEN_AI_ATTR_USAGE_OUTPUT_TOKENS = 'gen_ai.usage.output_tokens' + +export const AIRI_ATTR_BILLING_FLUX_CONSUMED = 'airi.billing.flux_consumed' +export const AIRI_ATTR_GEN_AI_INPUT_MESSAGES = 'airi.gen_ai.input.messages' +export const AIRI_ATTR_GEN_AI_INPUT_TEXT = 'airi.gen_ai.input.text' +export const AIRI_ATTR_GEN_AI_OPERATION_KIND = 'airi.gen_ai.operation.kind' +export const AIRI_ATTR_GEN_AI_OLLAMA_THINK = 'airi.gen_ai.ollama.think' +export const AIRI_ATTR_GEN_AI_OUTPUT_FULL_TEXT = 'airi.gen_ai.output.full_text' +export const AIRI_ATTR_GEN_AI_OUTPUT_TEXT = 'airi.gen_ai.output.text' +export const AIRI_ATTR_GEN_AI_STREAM = 'airi.gen_ai.stream' +export const AIRI_ATTR_GEN_AI_STREAM_INTERRUPTED = 'airi.gen_ai.stream_interrupted' + +export const SERVER_ATTR_ADDRESS = 'server.address' +export const SERVER_ATTR_PORT = 'server.port' + +export function getServerConnectionAttributes(baseUrl: string): Record { + const url = new URL(baseUrl) + const attributes: Record = { + [SERVER_ATTR_ADDRESS]: url.hostname, + } + + if (url.port) { + attributes[SERVER_ATTR_PORT] = Number.parseInt(url.port, 10) + } + + return attributes +}