feat: add metrics query API

This commit is contained in:
Dinesh Yeduguru 2025-02-28 12:21:27 -08:00 committed by Ashwin Bharambe
parent d27a0f276c
commit ba6334475f
2 changed files with 64 additions and 0 deletions

View file

@ -203,6 +203,45 @@ class QuerySpanTreeResponse(BaseModel):
data: dict[str, SpanWithStatus] data: dict[str, SpanWithStatus]
@json_schema_type
class MetricQueryType(Enum):
RANGE = "range"
INSTANT = "instant"
@json_schema_type
class MetricLabelOperator(Enum):
EQUALS = "="
NOT_EQUALS = "!="
REGEX_MATCH = "=~"
REGEX_NOT_MATCH = "!~"
@json_schema_type
class MetricLabelMatcher(BaseModel):
name: str
value: str
operator: MetricLabelOperator = MetricLabelOperator.EQUALS
@json_schema_type
class MetricDataPoint(BaseModel):
timestamp: datetime
value: float
@json_schema_type
class MetricSeries(BaseModel):
metric: str
labels: Dict[str, str]
values: List[MetricDataPoint]
@json_schema_type
class GetMetricsResponse(BaseModel):
data: List[MetricSeries]
@runtime_checkable @runtime_checkable
class Telemetry(Protocol): class Telemetry(Protocol):
@webmethod(route="/telemetry/events", method="POST") @webmethod(route="/telemetry/events", method="POST")
@ -247,3 +286,14 @@ class Telemetry(Protocol):
dataset_id: str, dataset_id: str,
max_depth: int | None = None, max_depth: int | None = None,
) -> None: ... ) -> None: ...
@webmethod(route="/telemetry/metrics/{metric_name}", method="POST")
async def get_metrics(
self,
metric_name: str,
start_time: int,
end_time: Optional[int] = None,
step: Optional[str] = "1d",
query_type: MetricQueryType = MetricQueryType.RANGE,
label_matchers: Optional[List[MetricLabelMatcher]] = None,
) -> GetMetricsResponse: ...

View file

@ -19,7 +19,10 @@ from opentelemetry.semconv.resource import ResourceAttributes
from llama_stack.apis.telemetry import ( from llama_stack.apis.telemetry import (
Event, Event,
GetMetricsResponse,
MetricEvent, MetricEvent,
MetricLabelMatcher,
MetricQueryType,
QueryCondition, QueryCondition,
QuerySpanTreeResponse, QuerySpanTreeResponse,
QueryTracesResponse, QueryTracesResponse,
@ -123,6 +126,17 @@ class TelemetryAdapter(TelemetryDatasetMixin, Telemetry):
else: else:
raise ValueError(f"Unknown event type: {event}") raise ValueError(f"Unknown event type: {event}")
async def get_metrics(
self,
metric_name: str,
start_time: int,
end_time: Optional[int] = None,
step: Optional[str] = "1d",
query_type: MetricQueryType = MetricQueryType.RANGE,
label_matchers: Optional[List[MetricLabelMatcher]] = None,
) -> GetMetricsResponse:
pass
def _log_unstructured(self, event: UnstructuredLogEvent, ttl_seconds: int) -> None: def _log_unstructured(self, event: UnstructuredLogEvent, ttl_seconds: int) -> None:
with self._lock: with self._lock:
# Use global storage instead of instance storage # Use global storage instead of instance storage