search_values
Retrieve distinct field values from OpenObserve log streams within specified time ranges. Use filter queries to narrow results and analyze field data patterns.
Instructions
Get distinct field values for a stream over a time range. filter_query uses OpenObserve's _values filter syntax, e.g. kubernetes_pod_namespace=litellm. Simple SQL-like equality such as kubernetes_pod_namespace='litellm' is normalized automatically. Time values are Unix timestamps in microseconds. Tip: 1 hour = 3_600_000_000 us, 1 day = 86_400_000_000 us. In this tool, total means the number of field groups returned, not the total number of matching log records.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| stream_name | Yes | ||
| fields | Yes | ||
| start_time | Yes | ||
| end_time | Yes | ||
| size | No | ||
| offset | No | ||
| filter_query | No | ||
| keyword | No | ||
| regions | No | ||
| timeout | No | ||
| no_count | No | ||
| include_raw | No |
Implementation Reference
- openobserve_mcp/server.py:153-189 (handler)The tool definition for `search_values` in the MCP server, which orchestrates calling the client and formatting the result.
@server.tool() def search_values( stream_name: str, fields: str, start_time: int, end_time: int, size: int = 100, offset: int = 0, filter_query: str | None = None, keyword: str | None = None, regions: str | None = None, timeout: int | None = None, no_count: bool = False, include_raw: bool = False, ) -> dict[str, Any]: """Get distinct field values for a stream over a time range. filter_query uses OpenObserve's _values filter syntax, e.g. kubernetes_pod_namespace=litellm. Simple SQL-like equality such as kubernetes_pod_namespace='litellm' is normalized automatically. Time values are Unix timestamps in microseconds. Tip: 1 hour = 3_600_000_000 us, 1 day = 86_400_000_000 us. In this tool, total means the number of field groups returned, not the total number of matching log records.""" client = client_provider.get() raw = client.search_values( stream_name=stream_name, fields=fields, start_time=start_time, end_time=end_time, size=size, offset=offset, filter_query=filter_query, keyword=keyword, regions=regions, timeout=timeout, no_count=no_count, ) return build_search_values_result( org_id=client.resolve_org_id(), stream_name=stream_name, fields=fields, raw=raw, include_raw=include_raw, ) - The underlying API client method that performs the HTTP request to the OpenObserve `_values` endpoint.
def search_values( self, *, stream_name: str, fields: str, start_time: int, end_time: int, offset: int = 0, size: int = 100, filter_query: str | None = None, keyword: str | None = None, regions: str | None = None, timeout: int | None = None, no_count: bool = False, ) -> Any: query: dict[str, str | int | float | bool] = { "fields": fields, "size": size, "from": offset, "start_time": start_time, "end_time": end_time, "no_count": no_count, } if filter_query: query["filter"] = _normalize_values_filter_query(filter_query) if keyword: query["keyword"] = keyword if regions: query["regions"] = regions if timeout is not None: query["timeout"] = timeout try: return self.request_json( "GET", self._org_path("/api/{org_id}/{stream_name}/_values", stream_name=stream_name), query=query, ) except OpenObserveApiError as exc: if filter_query and exc.status_code == 500: raise OpenObserveApiError( exc.status_code, f"{exc} filter_query is passed directly to OpenObserve's _values filter parser " "and may not match normal SQL WHERE syntax.", body=exc.body, ) from exc raise