Logs API Reference
All log query APIs are available through the GraphQL endpoint at /query.
Operations use POST with a JSON body containing a query key.
Replace <your-instance> with your Kloudfuse hostname and <sa-token> with a valid Service Account token.
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{"query": "..."}'
For Service Account token setup, see Authentication. See ,graphql for general guidance on using the GraphQL client.
FuseQL queries
FuseQL queries support the full FuseQL operator set including aggregation, parsing, string manipulation, and IP operators.
Use these endpoints when you want to run FuseQL pipelines — parse, where, count, avg, timeslice, lookup, and so on — against your log data.
getLogMetricsResultWithKfuseQl
Returns an aggregated metrics result for the specified time range using the FuseQL engine.
Use this for any FuseQL query that groups, aggregates, or uses timeslice — the full FuseQL operator set is available.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
FuseQL query string. |
|
Time |
Yes |
Start of the time range (RFC 3339 timestamp). |
|
Time |
Yes |
End of the time range (RFC 3339 timestamp). |
|
int |
No |
Query timeout in seconds. Default: 60. |
|
string |
No |
Comma-separated |
Response fields (FuseQLQueryResult):
| Field | Description |
|---|---|
|
List of column names in the result table. |
|
List of aggregation column names (e.g. |
|
List of group-by column names. |
|
The time bucket column name (set when using |
|
Rows returned from the FuseQL query; each row is an ordered array matching |
|
List of URL column names. |
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{
"query": "{ getLogMetricsResultWithKfuseQl(query: \"* | timeslice 5m | count by (_timeslice)\", startTs: \"2026-06-27T03:56:36Z\", endTs: \"2026-06-27T04:56:36Z\") { AggrValues ColumnHeaders GroupKeys TimeKey TableResult UrlValues } }"
}'
{
"data": {
"getLogMetricsResultWithKfuseQl": {
"AggrValues": ["_count"],
"ColumnHeaders": ["_count", "_timeslice"],
"GroupKeys": ["_timeslice"],
"TimeKey": "_timeslice",
"TableResult": [
[11779761, 1782532800000],
[13756819, 1782533100000],
[13890764, 1782533400000],
[14059741, 1782533700000],
[13890680, 1782534000000],
[13917425, 1782534300000],
[13577372, 1782534600000],
[13962963, 1782534900000],
[13437912, 1782535200000],
[13659788, 1782535500000],
[13447777, 1782535800000],
[13889559, 1782536100000],
[1589614, 1782536400000]
],
"UrlValues": null
}
}
}
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{
"query": "{ getLogMetricsResultWithKfuseQl(query: \"level=\\\"error\\\" | count by (source)\", startTs: \"2026-06-27T03:56:36Z\", endTs: \"2026-06-27T04:56:36Z\") { ColumnHeaders TableResult } }"
}'
{
"data": {
"getLogMetricsResultWithKfuseQl": {
"ColumnHeaders": ["_count", "source"],
"TableResult": [
[510042, "grafana"],
[836384, "pinot-server"],
[277099, "zookeeper"],
[23906, "pinot-gclog-broker"],
[6770, "pinot-broker"],
[9687, "rum-query-service"]
]
}
}
}
getLogsWithFuseQlStream
Returns raw log rows for the specified time range using the FuseQL engine.
Results are paginated: the response includes a Cursor value to pass in subsequent requests.
When Cursor is an empty string, there are no more results.
| Window operators and aggregation operators are not supported in this query. |
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
FuseQL query string. Window and aggregation operators are not supported. |
|
Time |
Yes |
Start of the time range (RFC 3339 timestamp). |
|
Time |
Yes |
End of the time range (RFC 3339 timestamp). |
|
string |
No |
Pagination cursor from the previous response. Pass |
|
int |
No |
Query timeout in seconds. Default: 60. |
|
string |
No |
Comma-separated |
Response fields (FuseQLQueryResult):
| Field | Description |
|---|---|
|
List of column names in the result table. |
|
Rows returned from the FuseQL query; each row is an ordered array matching |
|
Opaque pagination cursor. Pass this value in the next request. Empty string when no more results. |
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{
"query": "subscription { getLogsWithFuseQlStream(query: \"source=\\\"grafana\\\" | limit 2\", startTs: \"2026-06-27T03:56:36Z\", endTs: \"2026-06-27T04:56:36Z\", cursor: null) { ColumnHeaders TableResult Cursor } }"
}'
{
"data": {
"getLogsWithFuseQlStream": {
"ColumnHeaders": [
"timestamp",
"source",
"logLine",
"fpString",
"fpHash",
"level",
"labels",
"facets",
"__kf_logid",
"__kf_handle"
],
"TableResult": [
[
1782536160686,
"grafana",
"logger=ngalert.scheduler rule_uid=5342d6af-46e5-4d5a-bfc1-7d05da4c1234 org_id=1 version=11 level=error msg=\"Failed to evaluate rule\" attempt=1 max_attempts=3",
"logger=<v_0> <p_0>=<v_1> <p_1>=<v_2> version=<v_3> level=<v_4> msg=\"<v_5>\" attempt=<v_6> <p_2>=<v_7>",
"dd85a7c7ad9e5580",
"error",
{ "kube_namespace": "kfuse", "pod_name": "kfuse-grafana-5968bdf45d-rksxs" },
[{ "content": "error", "dataType": "STRING", "facetName": "level" }],
"006553500001000000000002",
"..."
]
],
"Cursor": "eyJsb2dfaWRfY3Vyc29yIjoiMDA2NTUzNTBiYTIzMDUwMTAwMDAwMDAwMDJmNzE1ZGIiLCJ0c19jdXJzb3IiOjE3ODI1MzYxNzcwNjZ9"
}
}
}
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{
"query": "subscription { getLogsWithFuseQlStream(query: \"source=\\\"grafana\\\" | limit 2\", startTs: \"2026-06-27T03:56:36Z\", endTs: \"2026-06-27T04:56:36Z\", cursor: \"eyJsb2dfaWRfY3Vyc29yIjoiMDA2NTUzNTBiYTIzMDUwMTAwMDAwMDAwMDJmNzE1ZGIiLCJ0c19jdXJzb3IiOjE3ODI1MzYxNzcwNjZ9\") { ColumnHeaders TableResult Cursor } }"
}'
{
"data": {
"getLogsWithFuseQlStream": {
"ColumnHeaders": ["timestamp", "source", "logLine", "fpString", "fpHash", "level", "labels", "facets", "__kf_logid", "__kf_handle"],
"TableResult": [ ["..."] ],
"Cursor": ""
}
}
}
LogQL queries
The following APIs use the LogQL query engine for log retrieval and facet analysis. Use these when you need to filter logs using LogQL syntax or retrieve facet and label values.
The logQuery parameter in these APIs accepts a structured LogQuery object (not a FuseQL string), and does not support window operators or aggregation operators.
|
Prerequisites
-
Configure a GraphQL client. See GraphQL documentation.
-
Authenticate using the basic HTTP authentication protocol.
getFacetValueCountsStream
Get count facet values for the specified time range, with filter support.
Syntax
subscription { (1)
getFacetValueCountsStream(
facetName: String! (2)
dataType: String (3)
logQuery: LogQuery (4)
timestamp: Time (5)
durationSecs: Int (6)
limit: Int (7)
timeoutSecs: Int (8)
options: String (9)
): ValueCountList! (10)
}
| 1 | subscription: This is a subscription; calls return multiple responses. |
| 2 | facetName: The name of the facet queried. Must be an indexed facet (e.g. @:STRING.requestID), not a label — use getLabelValuesStream for label queries. |
| 3 | dataType: Datatype of facet; defaults to String. |
| 4 | logQuery: Structured log query object. Does not support window or aggregation operators. |
| 5 | timestamp: Beginning of the sampled time frame. |
| 6 | durationSecs: Going back duration in seconds; defaults to 300 seconds. |
| 7 | limit: Limit the number of results; defaults to 1000. |
| 8 | timeoutSecs: Optional query timeout, in seconds; default is 60 seconds. |
| 9 | options: Query options; string of comma-separated k=v key-value pairs. Not implemented — DO NOT USE. |
| 10 | ValueCountList: Object containing valueCounts — a list of ValueCount items, each with value (string), floatValue (float), and count (float) fields. |
getLabelValuesStream
Get label values for the specified label name.
Syntax
subscription { (1)
getLabelValuesStream(
labelName: String! (2)
logQuery: LogQuery (3)
timestamp: Time (4)
durationSecs: Int (5)
includeCount: Boolean (6)
limit: Int (7)
contains: String (8)
timeoutSecs: Int (9)
options: String (10)
): ValueCountList! (11)
| 1 | subscription: This is a subscription; calls return multiple responses. |
| 2 | labelName: The name of the label queried. |
| 3 | logQuery: Structured log query object. Does not support window or aggregation operators. |
| 4 | timestamp: Beginning of the sampled time frame. |
| 5 | durationSecs: Going back duration in seconds; defaults to 300 seconds. |
| 6 | includeCount: Whether to include count of values in result (True or False). |
| 7 | limit: Limit the number of results; defaults to 1000. |
| 8 | contains: Filter label values that contain the specified string. |
| 9 | timeoutSecs: Optional query timeout, in seconds; default is 60 seconds. |
| 10 | options: Query options; string of comma-separated k=v key-value pairs. Not implemented — DO NOT USE. |
| 11 | ValueCountList: Object containing valueCounts — a list of ValueCount items, each with value (string), floatValue (float), and count (float) fields. |
getLogMetricsTimeSeries
Get a time series of metrics derived from logs for a given time range with filter support using the LogQL query engine.
Syntax
{ (1)
getLogMetricsTimeSeries(
logQuery: LogQuery (2)
timestamp: Time (3)
durationMs: Int (4)
stepMs: Int! (5)
lookBackMs: Int! (6)
facetName: String (7)
facetNormalizeFunction: NormalizeFunction (8)
rangeAggregate: String! (9)
rangeAggregateParam: Float (10)
rangeAggregateGrouping: Grouping (11)
vectorAggregate: String (12)
vectorAggregateParam: Float (13)
vectorAggregateGrouping: Grouping (14)
logQL: String (15)
timeoutSecs: Int (16)
options: String (17)
): [TimeSeries] (18)
}
| 1 | This is a query; calls return a single response. |
| 2 | logQuery: Structured log query object. Does not support window or aggregation operators. |
| 3 | timestamp: Beginning of the sampled time frame. |
| 4 | durationMs: The length of the sampled time, in milliseconds. |
| 5 | stepMs: The query resolution that determines the interval between data points in a chart, in milliseconds. |
| 6 | lookBackMs: Specifies how far back in time to search for data points when evaluating a query, in milliseconds. |
| 7 | facetName: The name of the facet queried. |
| 8 | facetNormalizeFunction: The function to apply to the facet value, to normalize to a time duration or data size (in bytes). |
| 9 | rangeAggregate: Either an inner or time range aggregate, such as rate or any *_over_time aggregate. |
| 10 | rangeAggregateParam: The parameter for the range aggregate function. |
| 11 | rangeAggregateGrouping: The grouping for the log range aggregate. |
| 12 | vectorAggregate: The vector aggregate, such as sum, min, max, avg, std_dev, std_var. |
| 13 | vectorAggregateParam: The parameter for the vector aggregate function. |
| 14 | vectorAggregateGrouping: The grouping for the vector aggregate. |
| 15 | logQL: LogQL query string (alternative to structured logQuery). |
| 16 | timeoutSecs: Optional query timeout, in seconds; default is 60 seconds. |
| 17 | options: Query options; string of comma-separated k=v key-value pairs. Not implemented — DO NOT USE. |
| 18 | TimeSeries: The returned time series data, including points (timestamp + float value pairs) and tags (Map). |
getLogMetricsTimeSeriesStream
Get a time series of metrics derived from logs for the specified time range using the LogQL query engine.
Syntax
subscription { (1)
getLogMetricsTimeSeriesStream(
logQuery: LogQuery (2)
timestamp: Time (3)
durationMs: Int (4)
stepMs: Int! (5)
lookBackMs: Int! (6)
facetName: String (7)
facetNormalizeFunction: NormalizeFunction (8)
rangeAggregate: String! (9)
rangeAggregateParam: Float (10)
rangeAggregateGrouping: Grouping (11)
vectorAggregate: String (12)
vectorAggregateParam: Float (13)
vectorAggregateGrouping: Grouping (14)
): [TimeSeries] (15)
}
| 1 | subscription: This is a subscription; calls return multiple responses. |
| 2 | logQuery: Structured log query object. Does not support window or aggregation operators. |
| 3 | timestamp: Beginning of the sampled time frame. |
| 4 | durationMs: The length of the sampled time, in milliseconds. |
| 5 | stepMs: The query resolution that determines the interval between data points in a chart, in milliseconds. |
| 6 | lookBackMs: Specifies how far back in time to search for data points when evaluating a query, in milliseconds. |
| 7 | facetName: The name of the facet queried. |
| 8 | facetNormalizeFunction: The function to apply to the facet value, to normalize to a time duration or data size (in bytes). |
| 9 | rangeAggregate: Either an inner or time range aggregate, such as rate or any *_over_time aggregate. |
| 10 | rangeAggregateParam: The parameter for the range aggregate function. |
| 11 | rangeAggregateGrouping: The grouping for the log range aggregate. |
| 12 | vectorAggregate: The vector aggregate, such as sum, min, max, avg, std_dev, std_var. |
| 13 | vectorAggregateParam: The parameter for the vector aggregate function. |
| 14 | vectorAggregateGrouping: The grouping for the vector aggregate. |
| 15 | TimeSeries: The returned time series data, including points (timestamp + float value pairs) and tags (Map). |
Example
subscription {
getLogMetricsTimeSeriesStream(
durationMs: 300000
lookBackMs: 5000
stepMs: 5000
logQuery: {and: [{ and: [{ eq: { facetName: "level", value: "info" } }{ eq: { facetName: "source", value: "apigateway" } }] }]},
rangeAggregate: "count_over_time"
vectorAggregate: "sum"
vectorAggregateGrouping: {
groups: ["level"]
}
timestamp: "2025-04-08T12:17:13-07:00",
) {
points {
ts
value
}
tags
}
}
getLogsV2Stream
Get logs based on time and log filters, with sorting and limit support.
Syntax
subscription { (1)
getLogsV2Stream(
timestamp: Time (2)
durationSecs: Int (3)
query: LogQuery (4)
limit: Int (5)
cursor: String (6)
sortBy: String (7)
sortOrder: SortOrder (8)
timeoutSecs: Int (9)
options: String (10)
): LogEventV2List! (11)
}
| 1 | subscription: This is a subscription; calls return multiple responses. |
| 2 | timestamp: Beginning of the sampled time frame. |
| 3 | durationSecs: Going back duration in seconds; defaults to 300 seconds. |
| 4 | query: Structured log query object. Does not support window or aggregation operators. |
| 5 | limit: Limit the number of results; defaults to 1000. |
| 6 | cursor: Pagination cursor. Must be null for the first request; subsequent requests must include the value from the previous response. Empty string signals no more results. |
| 7 | sortBy: The property to sort the results by; defaults to count. |
| 8 | sortOrder: Ordering of the returned query; defaults to descending order. |
| 9 | timeoutSecs: Optional query timeout, in seconds; default is 60 seconds. |
| 10 | options: Query options; string of comma-separated k=v key-value pairs. Not implemented — DO NOT USE. |
| 11 | LogEventV2List: The result list of log events, returning events (list of log event objects), cursor (pagination cursor, empty string when no more results), and queryStats. |
Example
subscription{
getLogsV2Stream(
cursor: null,
query: {and: [{ and: [{ eq: { facetName: "level", value: "info" } }{ eq: { facetName: "source", value: "apigateway" } }] }]},
limit: 200,
timestamp: "2025-04-08T12:17:13-07:00",
durationSecs: 300
) {
cursor
events {
timestamp
logLine
fpString
fpHash
level
labels
facets {
name
dataType
content
}
}
}
}
Lookup table queries
Kloudfuse supports lookup tables that can be used with the lookup operator to enrich log data at query time.
getLookupTables
Returns all lookup tables with their schema and folder location.
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{"query": "query { getLookUpTables { TableName Dimensions { Name DataType } PrimaryKeyColumns FolderUid } }"}'
{
"data": {
"getLookUpTables": [
{
"TableName": "UserLocations",
"Dimensions": [
{ "Name": "userID", "DataType": "string" },
{ "Name": "country", "DataType": "string" },
{ "Name": "city", "DataType": "string" },
{ "Name": "latitude", "DataType": "float" },
{ "Name": "longitude", "DataType": "float" }
],
"PrimaryKeyColumns": ["userID"],
"FolderUid": "abc123"
},
{
"TableName": "ErrorCodes",
"Dimensions": [
{ "Name": "errorCode", "DataType": "string" },
{ "Name": "errorDescription", "DataType": "string" },
{ "Name": "severity", "DataType": "string" }
],
"PrimaryKeyColumns": ["errorCode"],
"FolderUid": null
}
]
}
}
Lookup table mutations
createLookupTable
Creates a new lookup table by uploading a CSV file.
The CSV column headers must match the dimensions definitions.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
Unique name for the lookup table. |
|
NameAndDataTypeInput[] |
Yes |
Column definitions. Each entry has |
|
Upload |
Yes |
CSV file containing the data. Maximum size: 50 MB. |
|
string[] |
Yes |
Columns that uniquely identify each row. |
|
string |
No |
Folder to place the table in. Omit for the root location. |
curl -H "Authorization: Bearer <sa-token>" \
-X POST "https://<your-instance>/query" \
-F 'operations={"query":"mutation($tableName:String!,$dimensions:[NameAndDataTypeInput!]!,$file:Upload!,$primaryKeyColumns:[String!]!){createDimensionTable(tableName:$tableName,dimensions:$dimensions,file:$file,primaryKeyColumns:$primaryKeyColumns)}","variables":{"tableName":"cluster_costs","dimensions":[{"Name":"ClusterName","DataType":"STRING"},{"Name":"MonthlyCost","DataType":"STRING"}],"primaryKeyColumns":["ClusterName"],"file":null}}' \
-F 'map={"0":["variables.file"]}' \
-F '0=@cluster_costs.csv;type=text/csv'
{
"data": {
"createDimensionTable": true
}
}
deleteLookupTable
Permanently deletes a lookup table.
Any FuseQL queries using the lookup operator with this table will fail after deletion. Verify the table is not in use before deleting.
|
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{"query": "mutation { deleteDimensionTable(tableName: \"cluster_costs\") }"}'
{
"data": {
"deleteDimensionTable": true
}
}
editLookupTable
Updates an existing lookup table: move it to a different folder, upload new data, or both.
Parameters (editInfo):
| Field | Type | Description |
|---|---|---|
|
string |
Move the table to this folder UID. Optional. |
|
Upload |
New CSV file to load. Must match the existing schema. Optional. |
|
boolean |
If |
curl -H "Authorization: Bearer <sa-token>" \
-H "Content-Type: application/json" \
-X POST "https://<your-instance>/query" \
-d '{
"query": "mutation { editLookupTable(tableName: \"UserLocations\", editInfo: { newFolderUid: \"xyz789\" }) }"
}'
{
"data": {
"editLookupTable": true
}
}
curl -H "Authorization: Bearer <sa-token>" \
-X POST "https://<your-instance>/query" \
-F 'operations={"query":"mutation($tableName:String!,$editInfo:EditLookupTableInput!){editLookupTable(tableName:$tableName,editInfo:$editInfo)}","variables":{"tableName":"ErrorCodes","editInfo":{"overwrite":true,"file":null}}}' \
-F 'map={"0":["variables.editInfo.file"]}' \
-F '0=@error_codes_new.csv;type=text/csv'
{
"data": {
"editLookupTable": true
}
}
Error handling
GraphQL errors are returned with HTTP 200 in an errors array alongside a null data value:
{
"errors": [
{
"message": "syntax error",
"path": ["getLogMetricsResultWithKfuseQl"]
}
],
"data": {
"getLogMetricsResultWithKfuseQl": null
}
}
Common error causes:
| Message | Likely cause |
|---|---|
|
Invalid FuseQL query string — check operator names and quoting. |
|
The Service Account token lacks permission for the requested resource. |
|
Query exceeded |
See Also
-
FuseQL — FuseQL language reference
-
Lookup operators — Using lookup tables in queries
-
Folders API Reference — Folder management API and authentication details