
Nightingale Doris 数据源查询指南query-datasource 技能下的 SQL 日志与时序查询实战【免费下载链接】nightingaleNightingale is to monitoring and alerting what Grafana is to visualization.项目地址: https://gitcode.com/GitHub_Trending/ni/nightingaleNightingale 的 AI Agent 内置query-datasource技能定义见 SKILL.md允许 Agent 通过统一的 HTTP API 查询 Prometheus、Elasticsearch、ClickHouse、Doris 等多种数据源。本文聚焦其中doris插件类型围绕 doris.md 展开完整讲解 Doris 数据源的元数据查询、日志查询与时序查询 API 的请求格式与参数语义并结合仓库源码剖析其连接配置、只读安全校验与结果行数限制等底层实现。读完本文你将能在自己的 Nightingale 环境中直接调用这些 API或让 Agent 正确构造 Doris 查询请求。一、Doris 数据源在 query-datasource 技能中的定位在 query-datasource 技能说明 的数据源类型速查表中Doris 的定位如下plugin_type数据源查询语言适用场景dorisDorisSQLMySQL 兼容方言日志查询、时序查询Doris 使用 SQL 作为查询语言语法与 MySQL 高度兼容因此在 Nightingale 中它被归类为 SQL 型数据源。技能文档明确指出ClickHouse、MySQL、PostgreSQL、Doris 共享同一套元数据查询端点db-databases、db-tables、db-desc-table而 TDengine 则使用专用端点。这一划分与源码中 datasource_query.go 的sqlDatasourceTypes集合一致——mysql、ck、pgsql、doris、tdengine均走 SQL 查询路径由GetSQLDatasource获取插件实例后再调用QueryData/QueryLog。二、查询前置条件登录与数据源定位所有 Doris 查询请求都需要Authorization: Bearer token请求头token 的获取与数据源 ID 的确定遵循技能文档的统一执行步骤登录获取 TokenPOST /api/n9e/auth/login请求体为{username:username,password:password}从响应中提取dat.access_token查询数据源列表POST /api/n9e/datasource/list请求体为空{}响应中的每个数据源包含id、name、plugin_type三个字段据此确定 Doris 数据源对应的datasource_id发起查询根据plugin_type为doris按本文后续 API 格式构造请求。注意技能文档强调所有查询都要求先通过数据源列表拿到datasource_id并且所有 API 响应统一包裹在{dat: data}结构中。三、元数据查询库、表、表结构Doris 与 ClickHouse、MySQL、PostgreSQL 共用以下三个元数据端点路由注册见 router.go接口实现见 router_datasource_db.go1. 查询数据库列表POST /api/n9e/db-databases Authorization: Bearer token Content-Type: application/json Body: {cate: doris, datasource_id: 1, query: []}服务端通过dscache.DsCache.Get(cate, datasourceId)获取 Doris 插件实例调用其ShowDatabases方法。底层执行SHOW DATABASES见 doris.go返回数据库名数组。2. 查询表列表POST /api/n9e/db-tables Authorization: Bearer token Content-Type: application/json Body: {cate: doris, datasource_id: 1, query: [database_name]}query数组只接受一个字符串参数——数据库名。服务端调用ShowTables(ctx, database)底层执行SHOW TABLES INdatabase见 doris.go。3. 查询表结构POST /api/n9e/db-desc-table Authorization: Bearer token Content-Type: application/json Body: {cate: doris, datasource_id: 1, query: [{database: logs_db, table: access_log}]}query数组中的对象需包含database与table两个字段。服务端调用DescribeTable(ctx, query)见 datasource/doris/doris.go底层执行DESCRIBE db.table并返回列属性数组。源码中 DescTable 还会将 Doris 原生类型映射为内部类型Type2字段例如double、decimal*→ floatdatetime、date、date*→ datetext、varchar*、char*→ text含int的类型 → long。并标注该列是否可建立索引Indexable供日志报表做字段提取时参考。四、日志查询POST /api/n9e/logs-queryPOST /api/n9e/logs-query Authorization: Bearer token Content-Type: application/json{ cate: doris, datasource_id: 1, query: [ { sql: SELECT * FROM logs_db.access_log WHERE log_time FROM_UNIXTIME($from) AND log_time FROM_UNIXTIME($to) AND message LIKE %error% ORDER BY log_time DESC LIMIT 100, from: 1712000000, to: 1712003600, database: logs_db } ] }要点说明sql中的$from与$to是时间变量占位符由系统自动替换为请求中from/to的秒级 Unix 时间戳无需手写具体数值FROM_UNIXTIME()将秒级时间戳转换为 Doris 的日期时间类型用于与log_time字段比较建议显式添加ORDER BY ... DESC与LIMIT控制返回条数在 Agent 工具侧日志查询默认limit为 50上限 500见 datasource_query.go服务端实现见 QueryLog解析参数后调用doris.QueryLogs见 logs.go内部等价于Query()响应中返回日志条目数组及total总数。五、时序查询POST /api/n9e/ds-queryPOST /api/n9e/ds-query Authorization: Bearer token Content-Type: application/json{ cate: doris, datasource_id: 1, query: [ { sql: SELECT DATE_TRUNC(log_time, INTERVAL 1 MINUTE) AS ts, COUNT(*) AS value FROM logs_db.access_log WHERE log_time FROM_UNIXTIME($from) AND log_time FROM_UNIXTIME($to) GROUP BY ts ORDER BY ts, from: 1712000000, to: 1712003600, database: logs_db, keys: { valueKey: value, labelKey: , timeKey: ts } } ] }要点说明sql必须产出时间列 数值列的结构上例中ts为时间列、value为数值列GROUP BY按时间粒度聚合keys.timeKey指定 SQL 结果中的时间列名keys.valueKey指定数值列名keys.labelKey可留空若有多个分组维度列用空格分隔多个列名技能文档的统一约定服务端实现见 QueryDatavalueKey为必填缺失会直接返回错误valueKey is required随后按from/to或默认interval60秒计算时间范围再调用doris.QueryTimeseries见 timeseries.go并通过sqlbase.FormatMetricValues按keys组装为时序点列。六、Query Parameters 参数总表字段类型必填说明sqlstring是SQL 查询语句支持$from、$to时间变量fromint64是开始时间Unix 秒级时间戳toint64是结束时间Unix 秒级时间戳databasestring是数据库名Doris 查询必须指定keys.valueKeystring否数值列名时序查询必填keys.labelKeystring否标签/分组列名keys.timeKeystring否时间列名注意from/to为秒级时间戳。上例1712000000与1712003600对应一个 1 小时的时间窗口若请求中未显式携带from/to而只有interval如告警规则预览场景QueryLog 会以当前时间向前回退interval秒自动补全时间范围。七、底层实现连接配置、只读校验与行数上限1. 数据源连接配置Doris 插件通过 dskit/doris/doris.go 的Doris结构体承载连接配置关键字段也是数据源设置中的 JSON key如下配置项默认值说明doris.addr无FE 的 MySQL 协议地址center 可达必填doris.internal_addr无edge 进程使用的 FE MySQL 地址edge 场景下优先使用doris.fe_addr无FE 的 HTTP 端点doris.user/doris.password无只读账号Validate中 user 必填doris.timeout60000查询超时单位毫秒doris.max_idle_conns10连接池最大空闲连接数doris.max_open_conns100连接池最大打开连接数doris.conn_max_lifetime14400连接最大存活时间单位秒doris.max_query_rows500单次查询最大返回行数doris.cluster_name无集群名doris.enable_write/doris.user_write/doris.password_write无写用户开关与写账号写路径使用独立连接实现上Doris 使用标准 MySQL 驱动go-sql-driver/mysql建立连接DSN 格式为user:passtcp(addr)/db?charsetutf8连接按addr:user:password:database组合缓存于连接池见 NewConn并按库名隔离复用。2. 只读安全校验双层防线Doris 查询严格只读有两层校验服务端插件层timeseries.go 维护DorisBannedOp黑名单包含CREATE、INSERT、ALTER、REVOKE、DROP、RENAME、ATTACH、DETACH、OPTIMIZE、TRUNCATE、SETSQL 按空格分词后命中即拒绝Agent 工具层datasource_query.go 的validateReadOnlySQL在 Agent 构造请求时前置拦截INSERT、UPDATE、DELETE、DROP、ALTER、CREATE、TRUNCATE、REPLACE、GRANT、REVOKE等写操作关键字只允许SELECT类查询通过。3. 结果行数上限MaxQueryRows为避免大结果集拖垮服务CheckMaxQueryRows 通过 SQL 分析跳过无需检查的聚合查询或LIMIT不超过上限的查询对需要检查的查询采用SELECT 1 FROM (sql) AS __probe_chk LIMIT maxRows1的探测方式见 probeRowCount利用 Doris 对LIMIT的提前终止优化以 O(maxRows) 的开销判定是否超限优于COUNT(*)的全量扫描。八、注意事项与最佳实践只读约束写操作被明令禁止切勿在查询中使用CREATE、INSERT、UPDATE、DELETE、ALTER、DROP等语句database必填Doris 查询必须显式携带database字段服务端连接会按库隔离连接缓存 key 包含 database时间函数SQL 中可直接使用DATE_TRUNC()、NOW()、FROM_UNIXTIME()等函数配合$from/$to变量完成时间窗口过滤与粒度聚合MySQL 兼容Doris SQL 语法与 MySQL 高度兼容可用反引号引用库名/表名标准SELECT ... WHERE ... GROUP BY ... ORDER BY ... LIMIT均可直接使用响应结构所有接口响应统一为{dat: data}日志查询返回total与条目列表时序查询返回ref、metric标签与values时间点序列调试提示若返回operation ... is forbid说明 SQL 命中了只读黑名单若返回query result rows count exceeds the maximum limit请为查询补充LIMIT或WHERE过滤条件。通过上述 API 与源码级的参数理解你可以直接在脚本或 Agent 工具中完成对 Nightingale 中 Doris 数据源的库表探查、日志检索与时序聚合并将结果接入告警、报表或对话式分析流程。【免费下载链接】nightingaleNightingale is to monitoring and alerting what Grafana is to visualization.项目地址: https://gitcode.com/GitHub_Trending/ni/nightingale创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考