关于 kubesense-logs
kubesense-logs 是配合 KubeSense MCP 服务使用的日志查询技能,面向需要读取日志行或分析日志计数、趋势的用户。它区分原始日志检索与聚合分析,并说明字段目录、过滤语法和分页限制。
主要功能
- 01查询日志字段目录
- 02检索单条日志
- 03聚合计数、趋势与百分位数
- 04按目录标签和 WHERE 条件筛选
- 05说明时间窗口分页限制
适用场景
- 01查看特定工作负载的错误日志
- 02统计各工作负载的错误趋势
- 03计算记录致命错误的 Pod 数
- 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
| 概念 | 使用此标签 | 存储列(拒绝使用) |
|---|---|---|
| 日志严重级别 | type | level |
| Pod | instance | pod_name |
| 容器 | container | container_name |
| 节点 / 主机 | node | host |
| 工作负载 | 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:
- 查询实际时间窗口。
- 取返回行中
timestamp的最小值——不要假定最后一行最早。 - 使用相同的
from_time和where再次调用,并将to_time设为该最小值, 原样复制。 - 当某次调用返回的行数少于
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。
规则
- 首先调用
get-trace-or-log-fields并传入signal: "logs",同时传入你要查询的同一时间窗口——属性键的作用范围限定于时间窗口。 - 使用目录中的标签:
type、instance、container、node。绝不要使用level、pod_name、container_name、host。 - 日志中没有
service字段——请使用workload。 type值为大写(ERROR,而不是error)。从enum_values读取大小写,绝不要依据example。- 包含
/、:、%或空格的值都要加引号。 - 使用
NOT (x IN (...)),不要使用x NOT IN (...)。 - 仅使用
= != < > <= >= LIKE ILIKE SUBSTR_ILIKE IN——文档中提到的 token/index 运算符没有对应的 WHERE 语法。 value_operation是row_count,不是count。- 使用
analyze-logs进行计数和趋势分析;search-logs仅用于读取消息。绝不要通过翻页来计算聚合值。 - 通过将
to_time缩小到返回的最小时间戳来翻页;没有 offset。 除非固定到一个集群,否则将多集群分页扫描视为抽样。 body仅用于筛选,不能用于分组。