尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PostHog logs-count-ranges 工具深度指南:用自适应时间分桶定位日志流量集中点

PostHog logs-count-ranges 工具深度指南:用自适应时间分桶定位日志流量集中点 PostHog logs-count-ranges 工具深度指南用自适应时间分桶定位日志流量集中点【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog本指南围绕 PostHog 日志产品的 MCP 工具logs-count-ranges展开它面向被过滤的日志流返回自适应区间的分桶计数每个桶携带显式的date_from/date_to/count让 AI Agent 在拉取具体日志行之前先低成本地搞清楚流量在窗口内集中在哪个时间段。读完本文你将掌握该工具的参数语义、响应结构、递归收窄模式、底层 HogQL 实现与自适应区间选择算法以及它与logs-count、logs-sparkline-query、query-logs的协同分工。工具定位PostHog 日志 MCP 工具集中的流量分布探针logs-count-ranges是 PostHog 日志 MCP 工具族中的一员。在 products/logs/mcp/tools.yaml 中它被定义为logs-count-ranges: operation: logs_count_ranges_create enabled: true scopes: - logs:read annotations: readOnly: true destructive: false idempotent: true title: Count logs by time bucket description_file: ./prompts/logs-count-ranges.md response: include: - ranges - interval关键信息它是只读readOnly: true、幂等idempotent: true且同步的工具只需logs:read权限响应只包含ranges与interval两个字段工具描述直接来自 logs-count-ranges.md即本文讲解的这份文档。tools.yaml 顶部注明工具条目由 OpenAPI schema 自动脚手架生成pnpm --filterposthog/mcp run scaffold-yaml -- --sync-allMCP 工具目录归属category: Logsurl_prefix: /logs底层对应的 API 端点为POST /api/projects/{project_id}/logs/count-ranges见 api.py 中的count_rangesactionrequired_scopes[logs:read]。与相邻工具的职责分工理解这个工具最好的方式是与它最接近的三个邻居对比工具返回什么开销与定位logs-count窗口内匹配过滤条件的标量总数单个数字极廉价用于量有多大 / 是否值得查行的前置探测logs-count-ranges本文按时间分桶的计数列表每桶带date_from/date_to/count比query-logs便宜回答量集中在什么时候logs-sparkline-query按 severity 或 service 拆分的迷你趋势图适合看整体形态但桶不含可回填的date_from/date_toquery-logs逐条日志行分页单次最多 1000 条最昂贵只在计数确认窗口尺寸合适后调用logs-count-ranges的独特优势在于每个桶携带显式的date_from/date_to可以直接作为下一次调用的dateRange回传实现无需手工推算区间宽度的递归下钻——这正是 logs-count.md 在结尾推荐想看量集中在何时就用 logs-count-ranges 跟进的原因。请求形态所有参数都放进query顶层字段会被拒绝工具要求所有参数位于query对象内部顶层字段一律拒绝{ query: { serviceNames: [api], dateRange: { date_from: -1h } } }服务端在 api.py 的count_ranges中先执行query_data request.data.get(query, {})再调用self._require_dict_query(query_data)校验随后从query中逐项取出dateRange、targetBuckets、severityLevels、serviceNames、searchTerm、filterGroup组装成LogsQuery交给CountRangesQueryRunner执行。递归收窄模式这个工具存在的核心原因logs-count-ranges之所以设计成显式返回每个桶的起止时间而不是像 sparkline 那样只给图形数据是为了支撑一种无需推理区间宽度的递归下钻模式先用用户的窗口如最近 24h调用一次logs-count-ranges挑出感兴趣的桶——最密集的、明显突变的尖峰、或意外空旷的区间把该桶的date_from与date_to作为下一次调用的dateRange再次调用logs-count-ranges重复约 3~4 层直到桶宽小于你的精度目标例如 1 分钟为止收窄到位后再调用query-logs拉取真实日志行。这与 Elasticsearch 用户使用auto_date_histogram的模式完全一致。官方文档与源码均强调保持递归浅层——单次调用都很便宜但递归层数会快速相乘。这一模式在测试用例 test_count_ranges_api.py 的test_recursion_happy_path中被直接验证先对 5 天窗口取 10 个桶选出count最大的桶再以其date_from/date_to作为新窗口继续分桶断言窄窗内桶计数之和 ≤ 父桶计数且 0证明递归下钻不会越界也不会丢数据。参数详解query.dateRange要分桶的时间窗口默认最近一小时-1h格式与query-logs完全一致date_from起点接受 ISO 8601 时间戳或相对格式-1h、-6h、-1d、-7d、-30ddate_to终点同样格式省略或为 null 表示现在。在 api.py 中未提供dateRange时服务端显式构造DateRange(date_from-1h)作为回退。测试test_defaults_date_range_to_last_hour也验证了空请求默认落在最近一小时。query.targetBuckets期望的近似桶数量默认 10上限 100超出会被截断钳制。引擎从一个固定间隔阶梯中自适应挑选区间使实际桶数尽量接近该目标固定阶梯1/5/10 秒1/2/5/10/15/30/60/120/240/360/720/1440 分钟即 1 分钟 ~ 1 天。由于空桶会被丢弃实际返回的行数可能少于targetBuckets这是正常现象。后端在 count_ranges_query_runner.py 定义了DEFAULT_TARGET_BUCKETS 10、MAX_TARGET_BUCKETS 100并用self.BUCKET_TARGET max(1, min(target_buckets, MAX_TARGET_BUCKETS))做双向钳制API 序列化层也声明了min_value1, max_valueMAX_TARGET_BUCKETS。按场景选值10默认——概览、找尖峰、回答这是集中分布还是均匀分布20~30——刻画一个已知的繁忙窗口50——高分辨率下钻仅在你确定窗口本身很小的时候使用。测试test_target_buckets_picks_appropriate_interval给出了确定性映射5 天窗口下targetBuckets5→ 间隔1d20→6h50→2htest_target_buckets_above_max_is_clamped则验证传999与传100得到完全相同的间隔与桶数。query.severityLevels、query.serviceNames、query.searchTerm、query.filterGroup这四个过滤参数与query-logs形状一致severityLevels取值trace/debug/info/warn/error/fatalfilterGroup支持log/log_attribute/log_resource_attribute三类属性过滤但关键语义是它们在分桶之前应用serializer 的 help_text 明确写着 Applied before bucketing.。也就是说桶内计数永远是基于过滤后的日志子集统计的。在 api.py 中这些字段被平铺组装进LogsQuerycount_ranges_query_runner.py的to_query()则通过self.where_with_timestamp_bounds()来自LogsQueryRunnerMixin见 logs_query_runner.py把过滤条件与半开区间时间边界timestamp date_from AND timestamp date_to避免边界双计一起注入 SQL WHERE 子句。响应结构{ ranges: [ { date_from: 2026-04-26T00:00:00Z, date_to: 2026-04-26T02:24:00Z, count: 1024 }, { date_from: 2026-04-26T02:24:00Z, date_to: 2026-04-26T04:48:00Z, count: 47 } ], interval: 2h }ranges按date_from升序排列的桶列表。空桶被省略——推断间隙的方法是比较每个桶的date_to与下一个桶的date_from两者之间的空档即无日志时段。interval所选桶宽的短格式时长如1s/5m/1h/1d仅作信息提示——后续查询请使用每个桶的date_from/date_to不要自己按interval拼时间。两个值得注意的细节来自实现层时间戳统一为 UTC 的 Z 后缀 ISO 8601 格式。count_ranges_query_runner.py的_utc_z()count_ranges_query_runner.py把 ClickHouse 返回的 naive UTC 时间显式格式化为Z后缀字符串注释明确写道这是为了让桶的date_from/date_to能直接回填进query-logs而不产生时区漂移。测试test_bucket_timestamps_are_utc_z_suffixed逐桶断言了两个时间字段都以Z结尾。间隔短格式做了规整化。_interval_short()count_ranges_query_runner.py会把分钟数按可整除性归一化为天/小时/分钟如 1440 分钟 →1d120 分钟 →2h秒数则直接输出s后缀。底层实现自适应区间选择器与 HogQL 查询区间是怎么自适应选出来的核心逻辑在LogsQueryRunnerMixin.query_date_rangelogs_query_runner.py用step (date_to - date_from) / BUCKET_TARGET算出把窗口切成目标桶数时每桶的理论时长从固定阶梯[1, 5, 10] [x*60 for x in [1, 2, 5, 10, 15, 30, 60, 120, 240, 360, 720, 1440]]单位秒中用find_closest找到绝对差值最小的整数间隔源码注释解释13 分钟这种间隔很难直观估算日志速率所以要取整若 step 达到 1 分钟以上则切换为分钟级区间并把计数换算成分钟最终构造的QueryDateRange使用exact_timerangeTrue与 UTC 时区确保分桶严格对齐窗口边界。CountRangesQueryRunner正是通过把target_buckets塞进BUCKET_TARGET来驱动上述选择器且注释强调必须在super().__init__之前设置以保证首次读取缓存属性query_date_range时就生效。生成的 HogQL 长什么样to_query()count_ranges_query_runner.py构造了如下查询结构SELECT toStartOfInterval(timestamp, {one_interval_period}) AS bucket_start, bucket_start {one_interval_period} AS bucket_end, count() AS event_count FROM logs WHERE {where} GROUP BY bucket_start ORDER BY bucket_start ASC即按区间起点toStartOfInterval分桶聚合计数桶终点 起点 区间长度按bucket_start升序排列。这正是响应中ranges有序、且桶与桶之间date_to无缝衔接date_from的实现来源测试test_buckets_ordered_ascending_and_aligned验证了升序与对齐。大查询保护快速失败而不是扫描无界数据CountRangesQueryRunner.settings使用了fail_fast_aggregate_settings(max_bytes_to_read1_000_000_000)count_ranges_query_runner.py定义见 logs_query_runner.py单次执行最多 30 秒、最多读取 1GB 数据超出即read_overflow_modethrow抛错。这解释了为什么文档建议保持递归浅层、先把窗口切小——在极端大窗口上直接分桶可能触发快速失败。示例两种典型用法找过去一天的错误尖峰{ query: { dateRange: { date_from: -1d }, targetBuckets: 24, serviceNames: [api-gateway], severityLevels: [error, fatal] } }用 24 个桶观察api-gateway过去 24 小时的error/fatal分布——每桶约 1 小时既能看到尖峰所在的小时又不会过度碎片化。测试test_filter_sum_matches_count_endpoint验证了同一过滤条件下各桶计数之和与logs-count端点返回的标量总数严格相等说明分桶不会引入重复计数或遗漏。从上次调用钻取最密集的小时假设上一步响应中最密的桶是{date_from: 2026-04-26T15:00:00Z, date_to: 2026-04-26T16:00:00Z, count: 894}{ query: { dateRange: { date_from: 2026-04-26T15:00:00Z, date_to: 2026-04-26T16:00:00Z }, targetBuckets: 12, serviceNames: [api-gateway], severityLevels: [error, fatal] } }把桶的边界原样回填为dateRangetargetBuckets: 12会把这一小时切成约 5 分钟一个的细粒度桶从而把某个小时有 894 条错误细化到这 894 条错误集中在哪几分钟——这正是递归收窄模式的第二步到第三步。测试即文档行为契约一览test_count_ranges_api.py 用 10 个用例固化了该工具的全部关键行为可作为使用时的契约参考测试验证的行为test_default_target_buckets_picks_12h_interval5 天窗口 默认 10 桶 → 间隔12h返回桶数 ≤ 10test_target_buckets_picks_appropriate_intervaltarget 5/20/50 → 间隔1d/6h/2h确定性映射test_target_buckets_above_max_is_clampedtargetBuckets: 999与100结果一致上限钳制test_empty_window_returns_no_ranges空窗口返回ranges: []不是错误test_filter_sum_matches_count_endpoint各桶计数之和 logs-count标量总数test_buckets_ordered_ascending_and_aligned桶按date_from升序、date_to date_fromtest_bucket_timestamps_are_utc_z_suffixed时间戳均为 UTC Z 后缀test_recursion_happy_path递归下钻窄窗桶和 ≤ 父桶计数且 0test_no_filtergroup_does_not_crash无 filterGroup 也能正常返回test_defaults_date_range_to_last_hour空请求默认窗口为最近一小时最佳实践与提醒递归最多 3~4 层。当桶宽低于精度目标如 1 分钟时就停止转而调用query-logs拉取行数据。空窗口不是错误。它返回{ranges: [], interval: ...}——语义是查过了没有匹配项。始终带serviceNames或资源属性过滤与query-logs的要求一致——不要把整个团队/项目的日志流全部拿来分桶。不要靠interval推算后续窗口。后续查询一律使用桶自带的date_from/date_to这是响应设计的首要意图。放在完整工作流中理解。query-logs的说明文档query-logs.md给出了推荐顺序先发现服务与属性 → 用logs-count估总量 → 用logs-count-ranges定位繁忙窗口 → 最后才用query-logs拉行。许多廉价调用属性/计数/count-ranges胜过一次昂贵的query-logs——先充分探索再精准查询。【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表