mcpField
K
kubesense-logs

kubesense-logs

github.com/kubesense-ai云与 DevOps3101 次安装3 天前更新
代码仓库

关于 kubesense-logs

kubesense-logs 是配合 KubeSense MCP 服务使用的日志查询技能,面向需要读取日志行或分析日志计数、趋势的用户。它区分原始日志检索与聚合分析,并说明字段目录、过滤语法和分页限制。

主要功能

  1. 01查询日志字段目录
  2. 02检索单条日志
  3. 03聚合计数、趋势与百分位数
  4. 04按目录标签和 WHERE 条件筛选
  5. 05说明时间窗口分页限制

适用场景

  1. 01查看特定工作负载的错误日志
  2. 02统计各工作负载的错误趋势
  3. 03计算记录致命错误的 Pod 数
  4. 04搜索超时消息文本

MCP 相关

此技能要求使用 KubeSense MCP 服务,并提供调用其日志字段目录、搜索和分析工具的指南。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kubesense-ai/kubesense-mcp-skills --skill kubesense-logs

安装后在 Claude Code 中输入/kubesense-logs确认已加载。

详细介绍

KubeSense 日志

需要 KubeSense MCP 服务;有关连接、身份验证和通用 WHERE 子句参考,请参阅 kubesense-mcp。此处的工具会根据 logs 模块检查 RBAC。

工具

工具适用场景返回内容
get-trace-or-log-fields (signal: "logs")始终先调用当前时间窗口的字段目录
search-logs需要读取单条日志行最多 page_size 行(默认值为 10)
analyze-logs需要统计数量、频率、趋势、百分位数聚合序列

读取日志行来计算总数是最常见的错误。 如果问题是“有多少”“频率如何”或“哪个最严重”,请使用 analyze-logs——一次调用就能覆盖整个时间窗口,比对原始行分页处理更准确。

字段名称 — 仅使用目录中的标签

对于所有输入位置(where、required_fields、group_by_fields、fields、sort_by),服务端都会拒绝存储列名,并返回:

field "pod_name" is a storage column; use the catalog label "instance" instead
概念使用此标签存储列(拒绝使用)
日志严重级别typelevel
Podinstancepod_name
容器containercontainer_name
节点 / 主机nodehost
工作负载workload—
命名空间namespace—
集群cluster—
日志消息body—
日志格式format—
来源source—
区域region—
应用版本app_version—
环境env_type—

这是 get-trace-or-log-fields 为日志提供的全部 13 个字段。 还有 3 个字段虽能解析,但不会显示在发现结果中:timestamp、pattern_id、body_length。

警告

日志中没有 service 字段。 service 仅存在于追踪中 (→ app_service)。对日志使用 service = checkout 会返回 unknown field "service" for signal=logs。请使用 workload 表示应用名称。

日志使用 node,追踪使用 node_name。 两种信号的字段名称不一致——日志使用 node (→ host),追踪使用 node_name。跨信号沿用字段名称必然会导致失败。

日志中的枚举值均为大写

type 只接受以下值:ERROR、WARN、INFO、DEBUG、TRACE、FATAL、PANIC。 区分大小写——type = error 不会匹配任何内容。

(追踪使用小写的 status = error。这两种信号的字段名称和大小写均不相同。)

format 接受 json、klog、nginx——均为小写。

说明

请根据 get-trace-or-log-fields 的 enum_values 列判断大小写,而不是根据 example 列。示例生成器会漏掉多个枚举字段(包括 type),并为这些字段返回空白单元格。enum_values 始终正确。

WHERE 语法

type = ERROR AND namespace = production
type IN (ERROR, FATAL) AND workload = checkout
NOT (env_type = dev)
body ILIKE "%timeout%"
@user.id = abc-123

WHERE 解析器实际接受的运算符:= != < > <= >= LIKE ILIKE SUBSTR_ILIKE IN,可与 AND / OR / NOT 和括号组合。

警告

get-trace-or-log-fields 的 operators 列宣传过度。图例中出现的 HAS_TOKEN、 HAS_ALL、HAS_ANY、LIKE_AND、ILIKE_LOG、IS_IP_ADDRESS 没有对应的 WHERE 字符串语法—— body HAS_TOKEN oom 会解析失败。请使用上面的列表。

引号。 不带引号的值只能包含字母、数字、_、.、-。包含斜杠、冒号、% 或空格的值 必须用双引号括起来:

body ILIKE "%connection refused%"      ✓
timestamp > "2026-07-30T10:00:00Z"     ✓
body ILIKE %timeout%                   ✗ parse error

NOT IN 不能作为叶节点解析。 请写成 NOT (namespace IN (kube-system, default))。

属性在 WHERE 中带有 @ 前缀,并且可在日志上正常使用:

@user.id = abc-123
@http.status_code > 400

属性运算符:= != IN < > <= >= LIKE ILIKE。不带引号的数值型 属性值会转换为数字,因此 @latency > 100 会进行数值比较。

警告

exist(@field) 在两种信号上都无法使用——它会生成一个带有值的 EXIST 运算符,而验证器会拒绝该运算符(operator "EXIST" takes no values (got 1))。目前没有可用的存在性检查。请改为按具体值筛选。

在 group_by_fields / fields / required_fields / sort_by 中,不要加 @——请改为设置标志:

{ "field": "user.id", "is_attribute": true }

search-logs

{
  "from_time": "2026-07-30T10:00:00Z",
  "to_time": "2026-07-30T11:00:00Z",
  "where": "type = ERROR AND namespace = production",
  "required_fields": [
    { "field": "instance", "is_attribute": false },
    { "field": "body", "is_attribute": false }
  ],
  "page_size": 50
}

输出为 TSV:第一行是 # total_count=<N> error_count=<N> is_free_search=<bool>,接着是表头行,然后每条日志占一行。total_count 统计的是整个时间窗口,不受 page_size 影响——将它与收到的行数比较,即可判断是否还有更多结果。

基于时间窗口分页

没有 page 或 offset 参数。 时间窗口为左闭右开 (from_time <= timestamp < to_time),因此分页时要缩小 to_time:

  1. 查询实际时间窗口。
  2. 取返回行中 timestamp 的最小值——不要假定最后一行最早。
  3. 使用相同的 from_time 和 where 再次调用,并将 to_time 设为该最小值, 原样复制。
  4. 当某次调用返回的行数少于 page_size,或已获得所需答案时停止。

时间戳为 RFC3339 UTC 格式,精度为毫秒。请原样复制单元格中的值—— 截断到整秒会导致重新读取或跳过该秒内的行。

重要

分页扫描得到的是样本,而非完整普查。 行按 toStartOfHour(timestamp) DESC, cluster DESC, timestamp DESC 排序——先按小时分桶,再按 集群排序。如果某个小时内,多个集群的匹配行数超过 page_size,缩小 to_time 可能会跳过扫描尚未处理到的集群中的行。若要穷尽读取,请将 clusters 固定为单个集群,并使用较大的 page_size。 否则,与其增加分页次数,不如增大 page_size;对于任何聚合类需求,优先使用 analyze-logs。

is_free_search

查询涉及 body、trace_id、span_id 或任何属性时,会改用原始表,而非预聚合汇总表——速度较慢,但这是查看消息文本的唯一方式。系统会自动计算该值,并在输出表头中报告。仅按列筛选时仍会走快速汇总表路径。

此处的 body ILIKE "…" 会在服务端重写,以使用正文文本索引。原始 SQL 不会进行这种重写,因此除非查询结构有此需求,否则不要将消息搜索移到 execute-sql 中;如果确实需要,请参阅 kubesense-sql 中的 Searching Log Text。

分析日志

{
  "from_time": "2026-07-30T10:00:00Z",
  "to_time": "2026-07-30T11:00:00Z",
  "query_type": "range",
  "where": "type = ERROR",
  "group_by_fields": [ { "field": "workload", "is_attribute": false } ],
  "value_operation": "row_count",
  "sort_direction": "DESC",
  "limit": 10
}
  • query_type:时间序列使用 range,每个序列返回一个数值时使用 instant。
  • value_operation:row_count、unique_count、avg、sum、min、max、p50、 p90、p95、p99。
  • 除 row_count 外,fields 用于提供操作数: 统计 pod 的 unique_count → value_operation: "unique_count", fields: [{"field": "instance"}]。
  • limit 限制 range 查询的序列数(按最大值取前 N 个,默认 20);对 instant 查询无效。

警告

value_operation: "count" 无效——正确名称是 row_count。工具 schema 自带的摘要行写着“Common: count, avg, …”,这是错误的。

body 不能用于 group_by_fields(汇总表中没有此字段)。它只能用于筛选。若要对相似消息进行聚类,请按 pattern_id 分组。

输出格式

按查询标签("A")为键的列式 JSON。对于 range,会输出一个共享的 timestamps 数组(Unix 秒),且每个序列都包含一个按位置对齐的 values 数组(null = 此时间桶中没有数据)。对于 instant,每个序列都包含一个标量 value。total_series/truncated 会报告在应用前 N 个的上限前存在的非零序列数。

示例

过去一小时内各 workload 的错误数趋势 query_type: range,where: "type = ERROR", group_by_fields: [{"field":"workload"}],value_operation: row_count

此刻记录过致命错误的不同 pod 数量 query_type: instant,where: "type = FATAL",value_operation: unique_count, fields: [{"field":"instance"}]

读取实际的超时消息 search-logs,where: 'body ILIKE "%timeout%" AND workload = checkout', required_fields: [{"field":"instance"},{"field":"body"}],page_size: 50

错误率百分比——需要两个查询和一个公式,因此请使用 analyze-telemetry;参见 kubesense-mcp。

规则

  1. 首先调用 get-trace-or-log-fields 并传入 signal: "logs",同时传入你要查询的同一时间窗口——属性键的作用范围限定于时间窗口。
  2. 使用目录中的标签:type、instance、container、node。绝不要使用 level、pod_name、 container_name、host。
  3. 日志中没有 service 字段——请使用 workload。
  4. type 值为大写(ERROR,而不是 error)。从 enum_values 读取大小写,绝不要依据 example。
  5. 包含 /、:、% 或空格的值都要加引号。
  6. 使用 NOT (x IN (...)),不要使用 x NOT IN (...)。
  7. 仅使用 = != < > <= >= LIKE ILIKE SUBSTR_ILIKE IN——文档中提到的 token/index 运算符没有对应的 WHERE 语法。
  8. value_operation 是 row_count,不是 count。
  9. 使用 analyze-logs 进行计数和趋势分析;search-logs 仅用于读取消息。绝不要通过翻页来计算聚合值。
  10. 通过将 to_time 缩小到返回的最小时间戳来翻页;没有 offset。 除非固定到一个集群,否则将多集群分页扫描视为抽样。
  11. body 仅用于筛选,不能用于分组。

评论

支持 Markdown