Skip to content

Vận hành BQL Server ​

Trang này hướng dẫn kiểm tra và sử dụng BQL Server sau khi triển khai: khám phá service bằng grpcurl, gửi truy vấn mẫu, hiểu định dạng phản hồi và xử lý lỗi.

Khám phá service bằng grpcurl ​

BQL Server bật gRPC reflection (v1) — grpcurl có thể tự khám phá mà không cần file proto:

bash
# Liệt kê toàn bộ service
grpcurl -plaintext localhost:9090 list

# Mô tả service Bql
grpcurl -plaintext localhost:9090 describe bql.v1.Bql

# Mô tả message ExecuteRequest
grpcurl -plaintext localhost:9090 describe bql.v1.ExecuteRequest

Kết quả list mong đợi:

text
bql.v1.Bql
transform.v1.TransformService
grpc.reflection.v1.ServerReflection

Truy vấn mẫu ​

Tất cả ví dụ dùng grpcurl -plaintext và giả định BQL Server chạy tại localhost:9090, OpenSearch tại http://localhost:9200.

Tìm kiếm đơn giản ​

bash
grpcurl -plaintext -d '{
  "bql": "from logs-* | head 5",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -3600,
  "latest_unix": 0,
  "pushdown_enabled": true
}' localhost:9090 bql.v1.Bql/Execute

Lọc theo điều kiện ​

bash
grpcurl -plaintext -d '{
  "bql": "from nginx-* where status=500 | head 10",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -86400,
  "latest_unix": 0,
  "opensearch_user": "admin",
  "opensearch_pass": "admin",
  "timeout_ms": 30000
}' localhost:9090 bql.v1.Bql/Execute

Aggregation ​

bash
grpcurl -plaintext -d '{
  "bql": "from metrics-* | stats count by host",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -3600,
  "latest_unix": 0
}' localhost:9090 bql.v1.Bql/Execute

Với lookup table (enrichment) ​

bash
grpcurl -plaintext -d '{
  "bql": "from firewall-* | lookup enrichment ip=src_ip | head 20",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -7200,
  "latest_unix": 0,
  "lookup_tables": {
    "enrichment": "ip,geo_country\n10.0.0.1,US\n10.0.0.2,DE"
  }
}' localhost:9090 bql.v1.Bql/Execute

Với phân quyền index (allowed_indexes) ​

bash
grpcurl -plaintext -d '{
  "bql": "from logs-* | stats count by host",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -3600,
  "latest_unix": 0,
  "allowed_indexes": [
    {"name": "logs-*", "prefix": "tenant_a"}
  ]
}' localhost:9090 bql.v1.Bql/Execute
📝
Truy vấn `from logs-*` ở trên sẽ truy vấn index thực tế `tenant_a_logs-*`. Nếu `from` nhắm tới index không nằm trong `allowed_indexes`, request bị từ chối.

Phân trang bằng cursor (search_after) ​

Trang đầu tiên (giới hạn 100 dòng) trả về search_after trong Completion:

bash
grpcurl -plaintext -d '{
  "bql": "from logs-* | sort ts desc",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -86400,
  "latest_unix": 0,
  "size": 100
}' localhost:9090 bql.v1.Bql/Execute

Lấy giá trị completion.search_after từ phản hồi, rồi gửi tiếp để lấy trang sau:

bash
grpcurl -plaintext -d '{
  "bql": "from logs-* | sort ts desc",
  "opensearch_url": "http://localhost:9200",
  "earliest_unix": -86400,
  "latest_unix": 0,
  "size": 100,
  "search_after": "{\"sort\": [\"2026-08-01T10:00:00Z\", 12345], \"rows_fetched\": 100}"
}' localhost:9090 bql.v1.Bql/Execute
ℹ️
Server cache PIT ID (TTL 300s) theo fingerprint của query để các trang sau dùng chung một point-in-time snapshot. `search_after` rỗng = không còn trang nào.

Định dạng phản hồi ​

Một truy vấn thành công trả về stream QueryResponse (oneof: chunk / completion / aggregation_response), luôn kết thúc bằng đúng một Completion.

Chunk ​

json
{
  "chunk": {
    "columns": ["host", "status", "count"],
    "rows": [
      {"values": {"host": "web-1", "status": "200", "count": "1523"}},
      {"values": {"host": "web-2", "status": "200", "count": "1487"}}
    ]
  }
}

Completion ​

json
{
  "completion": {
    "kind": "FULL",
    "message": "rows_emitted=100",
    "report": {
      "query_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "rows_emitted": 100,
      "source_rows_read": 15000,
      "operator_steps": 5
    }
  }
}

Các loại Completion ​

kindÝ nghĩa
FULLHoàn thành đầy đủ
PARTIALDừng sớm nhưng có lý do rõ ràng (partial_reason)
FAILEDLỗi giữa chừng (sau khi stream đã mở)

partial_reason: LIMIT, CANCELED, TIMEOUT, BACKEND_ERROR, MEMORY_CAP.

⚠️
Khi nhận `PARTIAL`/`FAILED`, kết quả đã nhận trước đó vẫn hợp lệ nhưng **không đầy đủ** — không dùng cho báo cáo/thống kê chính xác.

Transform playground ​

Service transform.v1.TransformService chạy thử pipeline transform (filter, remap, route, throttle, reduce, dedupe) trên dữ liệu mẫu:

bash
grpcurl -plaintext -d '{
  "input": [
    {"fields": {"severity": "error", "msg": "disk full"}},
    {"fields": {"severity": "info", "msg": "boot complete"}}
  ],
  "config": {
    "sources": ["input"],
    "transforms": [
      {
        "id": "filter_errors",
        "type": "TRANSFORM_TYPE_FILTER",
        "filter": {"condition": ".severity == \"error\""}
      }
    ]
  }
}' localhost:9090 transform.v1.TransformService/Transform

Phản hồi:

json
{
  "output": [
    {"fields": {"msg": "disk full", "severity": "error"}}
  ],
  "stats": {
    "inputCount": 2,
    "outputCount": 1,
    "droppedCount": 1,
    "transformCount": 1
  }
}

Xử lý lỗi ​

Lỗi trước khi stream mở (gRPC Status) ​

Lỗi parse, semantic, lowering, phân quyền xảy ra trước khi stream bắt đầu — trả về gRPC Status trực tiếp:

Mã gRPCNguyên nhân
INVALID_ARGUMENTParse/semantic/lowering lỗi, hoặc thiếu mệnh đề from
FAILED_PRECONDITIONThiếu time range (nguy cơ full scan), feature bị tắt, datasource không tồn tại
INTERNALLỗi physical planning, lỗi OpenSearch execution

Ví dụ: truy vấn không có from:

bash
grpcurl -plaintext -d '{
  "bql": "search status=200 | head 10",
  "opensearch_url": "http://localhost:9200"
}' localhost:9090 bql.v1.Bql/Execute

Kết quả: ERROR: Code = InvalidArgument desc = Query must include a 'from' clause...

Lỗi giữa stream (Completion FAILED) ​

Lỗi OpenSearch khi đang chạy (timeout, backend lỗi) xuất hiện dưới dạng Completion { kind: FAILED } ở cuối stream — không phải gRPC Status.

Giám sát cơ bản ​

  • Log: journalctl -u bql-server -f (systemd) hoặc docker logs -f bql-server (Docker).
  • Kiểm tra sống: grpcurl -plaintext localhost:9090 list — server phản hồi tức là đang chạy.
  • Debug sâu: đặt RUST_LOG=debug để xem chunk, index overrides, PIT cache.

Liên kết liên quan ​

Released under the MIT License.