其他
写/修/优化 Dynatrace DQL…
在 Dynatrace 中编写、修复或优化 DQL 查询时,用本经验快速选对 fetch/timeseries、匹配语法、时间对齐、rollup 与采样,避免静默错误并减少扫描成本。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 38/100 ×0.15
适用场景
写/修/优化 Dynatrace DQL特定
解决思路
- 在写、构建、修复或优化 DQL 查询前加载 dt-dql-essentials;按任务读取 reference:发现数据读 references/discovery.md;字段名/命名空间/数据模型/稳定性/查询模式读 references/semantic-dictionary.md;优化性能与成本读 references/optimization.md;Smartscape 拓扑导航读 references/smartscape-topology-navigation.md;summarize 和 makeTimeseries 模式读 references/summarization.md;数组和 timeseries 操作读 references/iterative-expressions.md;条件逻辑/coalesce/字符串/日期助手读 references/useful-expressions.md;in 操作符子查询和 @ 时间对齐单位表读 references/operators.md;字符串模式匹配读 references/string-matching.md。
- 把 DQL 当作管道式查询语言:用 | 链式连接命令来过滤、转换和聚合数据,不要套用 SQL 语法。
- 静态数组字面量用 {} 或 array(),不要用 [];例如过滤值集合时用 in(field, {值1, 值2})。
- 当 in() 右侧是执行块/子查询时,使用 in 操作符写 field in [子查询];不要写成 in(field, [子查询])。
- 在 by: 子句(summarize、makeTimeseries 等)中,字段列表用花括号包裹,例如 by: {severity, status}。
- 大小写不敏感的子串匹配用 contains(field, 值, false);不要外面包 lower(),contains() 第三个位置参数 caseSensitive 默认 true。
- == 不支持通配符;需要通配符时用 matchesValue(field, 模式),通配符 * 只能出现在模式开头和/或结尾;中段通配符拆成多个 matchesValue 调用并用 and 组合。
- 无通配符的 matchesValue 是精确(大小写不敏感)匹配;要子串匹配用 contains(field, 值),或用 matchesValue(field, *值*) 做通配符匹配。
- 对数组字段匹配多个值用 matchesValue(arr, {值1, 值2}),不要用 iAny(matchesValue(arr[], 值) OR ...);同一字段多个 contains(f, x) OR contains(f, y) 合并为 matchesValue(f, {*x*, *y*})。
- matchesPhrase 原生迭代数组字段:直接写 matchesPhrase(arr, 短语),不要 iAny 或 [];第二个参数必须是静态字符串,不能是数组。
- 短或常见 token 用 matchesPhrase(field, 单词) 做整词匹配,避免 contains 对 pipenv、gripping 等误报。
- 大小写不敏感的数组值匹配用 matchesValue(arr, {值1, 值2}, caseSensitive: false),不要 iAny(in(lower(arr[]), array(值1, 值2)))。
- 多数组迭代时 iAny 是逐对 pairwise,不是笛卡尔积;数组长度不同时结果为 null;独立检查用 in(f1, 值) AND in(f2, 值)。
- 小写字符串函数是 lower(field),不是 toLowercase(field);to 前缀只用于类型转换如 toString()、toLong()。
- arrayAvg(field) 将数组折叠为标量;field[] 是逐元素迭代表达式(数组→数组);不要混用成 arrayAvg(field[]);arraySum 同理,用 arraySum(field) 或 field[]。
- lookup 添加的字段默认加 lookup. 前缀(可用 prefix: 配置);join 右侧字段加 right. 前缀;引用时用 lookup.my_field / right.my_field。
- substring 用 substring(field, from: 0, to: 200):表达式参数是位置参数,from: 和 to: 是命名可选参数,必须写参数名。
- 等值比较用 ==,不是 =;单 = 用于赋值(fieldsAdd、summarize 别名)。
- from: / to: 接受 duration 字面量(如 -24h、-7d)或 now() 表达式,不接受 toTimestamp();绝对范围用 timeframe: 起止时间(ISO 8601)。
- 日志严重级别字段是 loglevel(无点),不是 log.level。
- 含特殊字符的字段(如 count())用反引号包裹再排序,例如 sort `count()` desc。
- 字符串长度用 stringLength(field),没有 length(field)。
- metrics 加载指标元数据,不加载值;查询指标值用 timeseries avg(dt.host.cpu.usage)。
- join/lookup 条件中有点号的字段名用方括号加反引号,例如 left[`a.b`] == right[`a.b`]。
- fieldsSummary 至少需要一个字段参数,例如 fieldsSummary field1, field2;不能无参数调用。
- timeseries 中使用 percentile/median/percentRank 时必须给 rollup:(avg/min/max/sum),否则静默返回空。
- rollup: 只用于 timeseries 中的指标聚合;summarize 对 logs/spans/events 的 percentile 不要加 rollup:,否则 UNKNOWN_PARAMETER_DEFINED;summarize 用 percentile(duration, 95)。
- 不要使用 array.contains 或 arrayContains,它们不存在;数组字段包含用 in(field, {值})。
- 对数组类型字段(如 dt.davis.problems 上的 k8s.namespace.name)不要用 == 判等,会静默返回零行;用 in(k8s.namespace.name, {值}) 或 matchesValue(field, {值})。
- 不要用 parseJson(field) 或 extractJsonField(field, jsonPath: $.x);用 parse field, JSON:parsed 后 parsed[x] 访问。
- 没有 hour()/minute();用 getHour(timestamp)/getMinute(timestamp),返回数字;不要用 formatTimestamp(timestamp, format: HH) 然后 == 4,因为返回字符串会静默不匹配。
- 经典实体对象不暴露 Entities REST API 的属性名;先 describe dt.entity.<type> 发现真实字段,再选择字段;不要猜 fromRelationships、toRelationships、containerImageTag。
- 用 bin(timestamp, 1h) 分组时始终别名:by: {t = bin(timestamp, 1h)},然后 sort t;DQL 自动生成 group-key 名称会带逗号后空格,反引号引用不带空格会 FIELD_DOES_NOT_EXIST。
- spans 没有 timestamp 字段;时间字段是 start_time 和 end_time;用 by: {t = bin(start_time, 1h)}。
- lookup 的 fields: 参数内不要给点号字段名加反引号:lookup [...], fields: {dotted.name};否则 PARSE_ERROR。
- data record 使用 = 表示命名字段:data record(key = 值);: 用于命令参数如 rollup:。
- getNodeField(dt.smartscape.host, tags)[tag.key] 访问 tag-map:方括号键用未加引号的标识符语法;加引号会解析错误。
- 新查询中用 dt.smartscape.* 或 smartscapeNodes,不要用已废弃的 dt.entity.*。
- DQL 查询从 fetch <data_object> 或 timeseries 开始;没有 fetch dt.metric;指标用 timeseries。
- 按数据类型选择 fetch:fetch spans 是分布式追踪,字段 span.*、service.*、http.*、db.*、code.*、exception.*;fetch logs 是日志事件,字段 log.*、k8s.*、host.*,消息体 content,严重级别 loglevel;fetch events 是 DAVIS/基础设施事件,字段 event.*、dt.smartscape.*;fetch bizevents 是业务事件,字段 event.* 和自定义字段;fetch security.events 是安全事件,字段 vulnerability.*、event.*;fetch user.sessions 是 RUM 会话,字段 dt.rum.*、browser.*、geo.*;fetch user.events 是 RUM 单个事件(页面浏览、点击、请求、错误);fetch user.replays 是会话回放;fetch application.snapshots 是应用快照;fetch dt.davis.events 是 Davis 检测事件;fetch dt.davis.problems 是 Davis 检测问题;timeseries avg(metric.key) 是指标,多横线键用反引号如 timeseries sum(`my.metric-name`);smartscapeNodes "HOST" 是拓扑,类型如 HOST、SERVICE、K8S_CLUSTER。
- 发现所有可用数据对象:fetch dt.system.data_objects | fields name, display_name, type。
- fetch 支持 samplingRatio: 减少读取数据量;如 fetch spans, samplingRatio:100 读取约 1% 数据;允许值取决于数据对象,范围为 1、10、100、1000、10000 到 100000,最高级仅 logs 和 spans 可用。
- 采样对 spans、user.events、user.sessions 是分层的:高 ratio 包含的记录保证也出现在低 ratio,但反之不然;其他非指标数据对象按记录独立采样,不同 ratio 结果不是子集。
- 实际采样比例可通过 dt.system.sampling_ratio 字段获取;外推真实总数:fetch logs, samplingRatio:10 | summarize count_extrapolated = sum(dt.system.sampling_ratio)。
- timeseries 仅支持这些聚合函数:sum、avg、min、max、count、percentile(metric,N)、median(metric)、percentRank(metric,value)、countDistinct(metric);辅助函数 start()、end()。
- timeseries 不支持 countIf、collectArray、stddev、variance、takeAny、takeFirst、takeLast;这些用 summarize 或 makeTimeseries。
- rollup: 控制每个时间槽如何合并原始数据点;percentile、median、percentRank 必须指定 rollup: 否则静默无结果;avg/min/max/sum/count 可不加。
- 单个 timeseries 聚合时 rollup: 放在命令级;多个聚合用 {} 时 rollup: 必须放在每个函数调用内;命令级 rollup: 会导致 UNKNOWN_PARAMETER_DEFINED。
- rollup: 取值:avg(gauge)、min、max、sum(counter)、total。
- timeseries 转标量优先用聚合函数上的 scalar:true,避免物化数组;如 timeseries avg_cpu = avg(dt.host.cpu.usage, scalar:true), by:{dt.smartscape.host};多个聚合时每个函数都加 scalar:true。
- 当需要完整时间序列数组并派生标量时,在后续 | fieldsAdd 用数组函数:arrayAvg(arr)、arraySum(arr)、arrayMin(arr)、arrayMax(arr)、arrayMedian(arr)、arrayPercentile(arr,N)、arrayLast(arr)、arrayFirst(arr)。
- @ 操作符对齐时间戳:now()@h 当前时刻对齐到小时边界;now()@d 今天午夜;now()@w1 本周一;now()-2h@h 先偏移 2 小时再对齐到小时。
- @ 规则:先偏移后对齐(now()-2h@h,不是 now()@h-2h);@ 与单位之间无空格(now()@h,不是 now() @h);m 是分钟,M 是月份,不要混淆。
- 实体字段按类型作用域,entity.id 不存在;拓扑查询用 smartscapeNodes。
- 实体 ID 字段和 smartscapeNodes 类型:Host 用 dt.smartscape.host / HOST;Service 用 dt.smartscape.service / SERVICE;Process 用 dt.smartscape.process / PROCESS;K8s cluster 用 dt.smartscape.k8s_cluster / K8S_CLUSTER。
- 从字符串转换 ID 用 toSmartscapeId()(必需)。
- 用 makeTimeseries 从事件数据(logs、spans、bizevents)构建时间分桶序列;不要直接把 timeseries 管道到 makeTimeseries,否则 INVALID_IMPLICIT_TIME_DEFAULT;重新聚合指标数据用 start() + expand。
- makeTimeseries 示例:fetch logs | makeTimeseries {total = count(), errors = countIf(loglevel == ERROR)}, interval: 5m, by: {k8s.cluster.name} | fieldsAdd error_rate = errors[] * 100.0 / total[]。
- makeTimeseries 关键参数:interval:、by:{}、from:/to:、bins:、time:(时间戳字段)、spread:(仅 count/countIf)、nonempty:。
- 用 spread: 构建实体存在时间线:smartscapeNodes "HOST" | makeTimeseries concurrently_existing_hosts = count(), spread: lifetime。
- 字符串匹配函数:matchesValue(field, {模式1, 模式2}) 通配符匹配,第一参数可接受数组字段,第二参数可接受数组字面量 {},无需 iAny 或 [];默认大小写不敏感,caseSensitive: true 强制大小写敏感;替代 contains()+iAny 链和 lower() 变通。
- matchesPhrase(field, token) 会分词并匹配整词;第一参数原生接受数组字段;第二参数必须是静态字符串,数组展开会导致运行时错误。
- in(field, array(值1, 值2)) 做集合成员关系;两个参数都接受数组,因此是重叠/交集检查。
- 每个不使用 fields 参数的 lookup 命令会先删除所有以该前缀(默认 lookup.)开头的现有字段,再添加新字段;链式 lookup 必须用 fields 参数或自定义 prefix 保留先前结果。
- 链式 lookup 选项 1:已知所需字段时,每个 lookup 用 fields: {product_id, product_category = category} 等;否则第二个 lookup 会删除第一个 lookup 添加的字段。
- 链式 lookup 选项 2:保留 lookup 所有字段时,每个 lookup 用不同 prefix: product. / warehouse.;新字段为 product.product_id、product.category、warehouse.category、warehouse.warehouse_region;原始源中以这些前缀开头的字段会被删除。
- 访问数据必须指定 timeframe;可用 UI、REST API 参数或 DQL 查询显式 from:/to:(省略一个默认 now()),或单个 timeframe: 参数。
- timeframe 可用绝对值或相对表达式;@ 操作符可将时间戳对齐到单位边界;示例:from:now()-1h@h, to:now()@h 上一完整小时;from:now()-1d@d, to:now()@d 昨天完整;from:now()@M 本月至今;from:now()-2h@h 回退 2 小时后对齐小时。
- 绝对时间戳用 ISO 8601:from:2024-01-15T08:00:00Z, to:2024-01-15T09:00:00Z。
- DQL 时间类型:timestamp 内部纳秒,暴露为日期/时间;timeframe 两个 timestamp;duration 内部纳秒,暴露为合理因子(ms、分钟、天)。
- 时间运算规则:timestamp - timestamp 得 duration;duration / duration 得 double,如 2h / 1m = 120.0;标量 × duration 得 duration,如 no_of_h * 1h。
- 提取时间元素(小时、月份中的天等)用 time functions(如 getHour 等),它们支持日历和时区包括 DST;避免用 formatTimestamp 提取时间组件;避免把 timestamp 和 duration 转 double/long 后用除法、取模和纳秒常量。
- 按函数组查阅对应规范:数据类型读 references/dql/dql-data-types.md;参数值类型读 references/dql/dql-parameter-value-types.md;命令读 references/dql/dql-commands.md;聚合函数读 references/dql/dql-functions-aggregation.md;数组函数读 references/dql/dql-functions-array.md;位运算读 references/dql/dql-functions-bitwise.md;布尔读 references/dql/dql-functions-boolean.md;转换读 references/dql/dql-functions-cast.md;常量读 references/dql/dql-functions-constant.md;转换函数读 references/dql/dql-functions-conversion.md;创建函数读 references/dql/dql-functions-create.md;加密函数读 references/dql/dql-functions-cryptographic.md;实体函数读 references/dql/dql-functions-entities.md;表达式时间序列聚合读 references/dql/dql-functions-expression-timeseries.md;流程函数读 references/dql/dql-functions-flow.md;通用函数读 references/dql/dql-functions-general.md;获取函数读 references/dql/dql-functions-get.md;迭代函数读 references/dql/dql-functions-iterative.md;数学函数读 references/dql/dql-functions-mathematical.md;网络函数读 references/dql/dql-functions-network.md;Smartscape 函数读 references/dql/dql-functions-smartscape.md;字符串函数读 references/dql/dql-functions-string.md;时间函数读 references/dql/dql-functions-time.md;指标时间序列聚合读 references/dql/dql-functions-timeseries.md。
适用边界 · 注意事项
- 不要用于解释已有查询或回答产品问题。
- 不要用于监控租户实际查询消耗/账单(查询花费多少、谁扫描最多、成本趋势);应使用 dt-platform-costs,本技能调优查询文本,不处理账单数据。
- 不适用于非 Dynatrace DQL 的其他查询语言或产品。