Time Series Timelion 组件详解
Timelion是基于自定义查询表达式的时序数据分析工具,通过链式函数调用实现复杂数据处理
核心功能:基于自定义查询表达式分析时序数据,支持链式函数调用与复杂运算
1 ) 数据源配置
- 内置数据源:
es():从Elasticsearch索引读取数据(需指定index参数)worldbank():从世界银行API拉取数据(需注意时间跨度匹配,例如查询近51年GDP数据)- 关键参数:
index:目标索引名(如logstash-*)q:查询条件(支持Lucene语法)metric:聚合指标(如sum、avg)split:分组字段(基于terms聚合)offset:时间偏移(如offset="-1d"展示昨日数据)
- 外部数据源:
- 如
worldbank模块可拉取世界银行数据(需注意时间跨度,示例:worldbank.China.GDP)
- 如
2 )表达式函数与运算
- 数据查询示例:
效果:按操作系统分组的中国地区流量总和,并与前一日对比。.es(index="logstash-*", q="geo.src:CN", metric="sum:bytes", split="os:3", offset="-1d") - 数据处理函数:
函数类型 示例 作用 数学运算 .abs().cusum()绝对值处理后累加求和 统计计算 .derivative()求导(变化率) 移动分析 .moving_average()计算滑动平均趋势线 条件判断 .if(lt,500,0,800)值<500时返回0,否则返回800 - 可视化控制:
label("Today"):定义图例标签color("#FF0000"):设置线条颜色yaxis(2):指定副Y轴(解决多单位数据对比问题)
- 关键函数
- 数据处理:
abs()(绝对值)cusum()(累加和)derivative()(求导)mvavg()(移动平均)
- 可视化控制:
.label("Today")(图例命名).lines(width=2)(线宽控制).color(#FF0000)(颜色设置).yaxis(2)(双Y轴定位)
- 数据处理:
- 高级应用场景
- 多序列对比:
.es(q="geo.src:CN").label("CN") .es(q="geo.src:US").label("US") .divide(.es(metric="sum:bytes")).multiply(100) // 计算流量占比 - 多序列运算:
.es(q="geo.src:CN").divide(.es(metric="sum:bytes")).multiply(100) // 计算中国流量占比 - 动态范围控制:
range(0,1000):将不同量级数据归一化(如请求数与字节数)scale_interval("1s"):强制按秒级间隔计算(避免时间窗口变动影响精度)
- 动态阈值告警:
.es(metric="max:bytes").if(lt, 500, 0, 800) // <500时设为0,否则800 - 预警标记:
.es(metric="max:bytes").if(gt,10000,"#FF0000","#00FF00") // 超阈值标红
- 多序列对比:
- 时间偏移对比:
.offset(-1d)将昨日数据与今日叠加显示(示例:今日为蓝线,昨日为红线)
其核心功能包括:
-
多数据源支持
.es():查询Elasticsearch索引数据.worldbank():获取世界银行公开数据集.graphql():连接GraphQL接口
基础查询结构示例:
.es( index="logstash-*", // 索引名称 q="geo.src:CN", // 查询条件(Lucene语法) metric="sum:bytes", // 聚合指标(字节求和) split="os.keyword:3", // 按操作系统分组(取前3) offset="-1d" // 时间偏移(比对昨日数据) ) -
数据处理函数库
// 数据转换 .abs() // 绝对值 .log() // 对数变换 .cusum() // 累积求和 .derivative() // 数值微分 .mvavg(7) // 7期移动平均 // 可视化控制 .label("Today") // 图例命名 .color("#FF0000") // 颜色设置 .lines(fill=0.5, width=2) // 线图样式(50%透明度,线宽2px) .yaxis(2) // 指定第二Y轴 -
多序列运算
// 计算中国流量占比 cn_traffic = .es(q="geo.src:CN", metric="sum:bytes") total_traffic = .es(metric="sum:bytes") cn_traffic.divide(total_traffic).multiply(100) -
阈值告警实现
.es(metric="max:mem_usage") .if(lt, 70, "#00FF00") // <70% 绿色 .if(gte, 70, "#FF9900") // ≥70% 橙色 .if(gte, 85, "#FF0000") // ≥85% 红色
Visual Builder 可视化构建器
定位:实验性组件,基于Pipeline Aggregation实现高阶时序分析,官方Dashboard广泛采用。
-
核心结构
- Data层:
- 定义索引、时间字段、采样间隔(
interval)。 - 设置值域范围(如
max:1限制CPU使用率≤100%)。
- 定义索引、时间字段、采样间隔(
- Metrics层:
- 支持多级Pipeline Aggregation(如
avg→derivative→sum)。 - 关键聚合类型:
buckets_script:脚本计算(例:(system_cpu_user + system_cpu_system) / cpu_cores)。series_agg:Kibana特有聚合(支持sum_over_time跨时序累加)。
- 支持多级Pipeline Aggregation(如
- Data层:
-
典型工作流示例
- 网络流量正负对比:
效果:流入/流出流量以0轴为基准对称显示。inbound: max(bytes_in) → derivative() → positive_only() outbound: max(bytes_out) → derivative() → multiply(-1) // 负值展示 - 多图表联动:
所有基于Visual Builder的图表支持全局筛选联动(优于基础图表)。
- 网络流量正负对比:
-
样式与交互控制
- 动态修改图表类型(线图/柱图)、透明度、颜色梯度。
- 支持条件着色(如CPU使用率>85%→红色)。
Visual Builder技术解析
Visual Builder基于Pipeline Aggregation实现,是Kibana官方推荐的时序分析方案:
-
核心处理流程(以CPU使用率计算为例)
{ "aggs": [ { "id": "user_cpu", "type": "avg", "field": "system.cpu.user" }, { "id": "system_cpu", "type": "avg", "field": "system.cpu.system" }, { "id": "cores", "type": "max", "field": "system.cpu.cores" }, { "id": "cpu_usage", "type": "bucket_script", "script": "(params.user + params.system) / params.cores", "buckets_path": { "user": "user_cpu", "system": "system_cpu", "cores": "cores" } } ] } -
双向流量对比实现
-
跨图表联动优势
- 全局过滤器自动同步
- 点击图表元素联动筛选
- 动态参数传递(Variables)
Visual Builder可视化构建器
实验性功能(标记为Experimental),基于Pipeline聚合实现灵活图表设计
核心组件
-
数据管道(Pipeline Aggregation)
- 典型结构:
metric → bucket_script → series_agg
示例(CPU使用率计算):"aggs": { "user_avg": { "avg": { "field": "cpu.user" } }, "system_avg": { "avg": { "field": "cpu.system" } }, "cores": { "max": { "field": "cpu.cores" } }, "usage": { "bucket_script": { "buckets_path": { "user": "user_avg", "sys": "system_avg", "core": "cores" }, "script": "(params.user + params.sys) / params.core" } } }
- 典型结构:
-
图表类型
- Time Series:时序折线/柱状图
- Metric:数值面板(支持Markdown动态模板)
- Top N:分组排序(如
terms aggregation+sort)
-
交互优势
- 仪表盘联动:多图表共享时间范围与过滤条件,实现动态钻取。
- 流量对比示例(流入/流出同图):
"outbound": { "bucket_script": { "buckets_path": { "traffic": "outbound_agg" }, "script": "params.traffic * -1" // 负值使柱状图向下延伸 } }
其他辅助组件
- Markdown 卡片
- 用途:添加标题、超链接、说明文本
- 示例:
[System Overview](/app/dashboards#system_view) [Host Metrics](/app/dashboards#host_metrics)- 实现Dashboard间快速导航
- Tag Cloud 文字云
- 字段映射:
size_field控制关键词大小(如count) - 参数:
orientation调整文字角度 - 配置项:
- 大小字段:
size by sum:bytes - 方向控制:
orientation="multiple"
- 大小字段:
- 字段映射:
- Controls 筛选器
- 动态过滤:添加下拉菜单(如
geo.src字段筛选),实时影响关联图表 - 动态过滤组件(实验性),例如:
Filter: geo.src.keyword Options: Dynamic dropdown from Elasticsearch
Dashboard 集成与设计原则
核心价值:聚合多组件实现主题化数据叙事
目标:整合可视化组件构建主题化数据故事
-
构建流程
- 创建Dashboard → 拖拽调整组件布局与尺寸。
- 统一时间范围(如
Last 10 years)。 - 使用Markdown添加章节标题与导航链接。
-
设计最佳实践
- 单一主题聚焦:例如"System Health"仅包含CPU/内存/磁盘图表。
- 视觉层次优化:
- 关键指标置顶(如Metric组件)。
- 关联图表相邻布局(如流量进出对比)。
- 交互一致性:确保所有组件响应全局时间范围与筛选器。
最佳实践
- 主题聚焦:单Dashboard仅展示同一主题图表(如“服务器监控”包含CPU/内存/磁盘)。
- 布局优化:
- 关键指标置顶(如Metric大数字)
- 关联图表横向并置(如流量入/出对比)
- 交互设计:
- 通过Markdown超链接跳转关联Dashboard
- 使用Controls减少图表数量冗余
注意:避免过度设计,复杂Timelion表达式可保存为独立对象复用
通过系统化整合Timelion表达式编写、Visual Builder管道设计及Dashboard编排逻辑,可构建企业级监控解决方案。建议结合Kibana官方示例库(如Metricbeat Dashboard)深化实践,重点掌握bucket_script与series_agg等高级聚合方法
工程示例:1
1 )方案1:Timelion查询服务(NestJS + Elasticsearch)
import { Injectable } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';
@Injectable()
export class TimelionService {
private readonly esClient: Client;
constructor() {
this.esClient = new Client({ node: 'http://localhost:9200' });
}
async fetchTimeSeriesData(index: string, query: any) {
const body = {
size: 0,
aggs: {
time_series: {
date_histogram: { field: '@timestamp', fixed_interval: '1h' },
aggs: {
metric: { [query.metricType]: { field: query.metricField } },
split: { terms: { field: query.splitField, size: 5 } }
}
}
}
};
return this.esClient.search({ index, body });
}
}
ES配置要点:
- 索引需开启
date_histogram所需的时间字段映射 - 优化分片策略:时序数据建议按天分片(
index_pattern: logs-YYYY.MM.DD)
2 )方案2:Visual Builder管道聚合处理
// 实现 buckets_script 计算CPU使用率
const cpuUsagePipeline = {
aggs: {
avg_user: { avg: { field: 'system.cpu.user' } },
avg_system: { avg: { field: 'system.cpu.system' } },
cpu_usage: {
bucket_script: {
buckets_path: { user: 'avg_user', system: 'avg_system', cores: 'cpu_cores' },
script: 'params.user + params.system / params.cores'
}
}
}
};
// NestJS调用示例
async executePipelineAgg(index: string) {
const body = { aggs: { timestamp_group: { date_histogram: { field: '@timestamp', interval: '1h' }, ...cpuUsagePipeline } } };
return this.esClient.search({ index, body });
}
性能优化:
- 启用ES脚本缓存:
script.max_compilations_rate=100/1m - 使用Painless脚本替代Groovy提升安全性
3 )方案3:动态Dashboard生成服务
import { KibanaClient } from '@elastic/elasticsearch';
@Injectable()
export class DashboardService {
private readonly kibanaClient: KibanaClient;
constructor() {
this.kibanaClient = new KibanaClient({ host: 'http://localhost:5601' });
}
async createSystemDashboard(panels: any[]) {
const dashboard = {
title: 'System Health Monitor',
panels: JSON.stringify(panels), // 包含Timelion/Visual Builder等组件配置
options: { darkTheme: false },
};
return this.kibanaClient.savedObjects.create({
type: 'dashboard',
attributes: dashboard,
});
}
}
安全与维护:
- 通过Kibana API密钥认证:
headers: { 'kbn-xsrf': 'true', Authorization: 'ApiKey XXX' }。 - 版本控制:使用Git管理Dashboard JSON定义文件。
工程示例:2
1 ) 方案1:基础查询服务封装
// src/elastic/elastic.service.ts
import { Injectable } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';
@Injectable()
export class ElasticService {
private readonly client: Client;
constructor() {
this.client = new Client({ node: 'http://localhost:9200' });
}
async searchTimelionData(params: {
index: string;
query: string;
metric: string;
splitField?: string;
offset?: string;
}) {
const body = {
query: {
bool: {
filter: [
{ range: { '@timestamp': { gte: 'now-1h' } } },
{ query_string: { query: params.query } }
]
}
},
aggs: {
metric_agg: { [params.metric.split(':')[0]]: { field: params.metric.split(':')[1] } },
...(params.splitField && {
split_agg: {
terms: {
field: params.splitField,
size: params.splitField.includes(':') ? parseInt(params.splitField.split(':')[1]) : 10
}
}
})
}
};
return this.client.search({ index: params.index, body });
}
}
2 ) 方案2:可视化配置持久化
// src/visualization/visual.service.ts
import { ElasticService } from '../elastic/elastic.service';
interface VisualConfig {
type: 'timeline' | 'metric' | 'tagcloud';
expression: string;
title: string;
colorRules?: { lt?: number; gt?: number; color: string }[];
}
@Injectable()
export class VisualService {
constructor(private readonly elastic: ElasticService) {}
async saveVisualization(config: VisualConfig) {
return this.elastic.client.index({
index: 'kibana_visualizations',
body: {
created_at: new Date().toISOString(),
config
}
});
}
async generateTimelionExpression(config: {
metrics: { index: string; query: string; metric: string }[];
operations: string[];
}) {
return config.metrics.map((m, i) =>
`.es(index="${m.index}", q="${m.query}", metric="${m.metric}")${config.operations[i] ? '.' + config.operations[i] : ''}`
).join('\n');
}
}
3 ) 方案3:集群监控看板自动化
docker-compose-monitoring.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
environment:
- cluster.name=monitoring-cluster
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:7.17.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
metricbeat:
image: docker.elastic.co/beats/metricbeat:7.17.0
user: root
volumes:
- /:/hostfs:ro
- /proc:/hostfs/proc:ro
- ./metricbeat.yml:/usr/share/metricbeat/metricbeat.yml
volumes:
esdata:
metricbeat.yml
metricbeat.modules:
- module: system
metricsets: ["cpu", "memory", "network", "process"]
enabled: true
period: 10s
processes: ['.*']
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
indices:
- index: "metricbeat-%{[agent.version]}-%{+yyyy.MM.dd}"
工程示例:3
1 ) 方案1:基础数据查询服务
// src/elastic/elastic.service.ts
import { Injectable } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';
@Injectable()
export class ElasticService { private readonly client: Client;
constructor() {
this.client = new Client({ node: 'http://localhost:9200' }); }
async searchTimelionData(index: string, query: any) {
return this.client.search({
index,
body: {
query: {
bool: {
filter: [{ range: { '@timestamp': { gte: 'now-1d' } } }],
must: [{ match: { 'geo.src': query.country } }] }
}, aggs: {
traffic_sum: { sum: { field: 'bytes' } }
}
}
});
}
}
2 ) 方案2:Pipeline聚合处理层
export const getCPUUsagePipeline = () => ({
aggs: { user_avg: { avg: { field: "cpu.user" } },
system_avg: { avg: { field: "cpu.system" } },
cores: { max: { field: "cpu.cores" } }, usage: {
bucket_script: {
buckets_path: { user: "user_avg", sys: "system_avg", core: "cores" },
script: "(params.user + params.sys) / params.core"
}
}
}
});
3 ) 方案3:Kibana仪表盘自动化部署
// src/kibana/dashboard.manager.ts
import { KibanaClient } from '@elastic/elasticsearch';
export class DashboardManager {
private kibana: KibanaClient; constructor() { this.kibana = new KibanaClient({ node: 'http://localhost:5601' });
}
async createDashboard(visualizationIds: string[]) {
return this.kibana.savedObjects.create({
type: 'dashboard',
attributes: {
title: 'Server Monitoring',
panels: JSON.stringify(visualizationIds.map(id => ({
type: 'visualization',
id, size: { xs: 12, sm: 6 }
}))),
options: { darkTheme: false }
}
});
}
}
ElasticSearch 周边配置处理
1 ) 性能优化配置
elasticsearch.yml
thread_pool.write.queue_size: 1000 # 写入队列扩容
indices.memory.index_buffer_size: 30% # 索引缓冲区内存分配
indices.queries.cache.size: 10% # 查询缓存设置
2 ) 安全防护方案
启用基础认证
bin/elasticsearch-keystore add xpack.security.authc.api_key.secure
配置TLS加密传输
bin/elasticsearch-certutil cert -out config/certs/elastic-certificates.p12
3 ) 备份恢复策略
PUT _snapshot/my_backups
{
"type": "fs",
"settings": {
"location": "/mnt/es_backups",
"compress": true,
"max_restore_bytes_per_sec": "100mb"
}
}
// 定时快照策略
PUT _slm/policy/nightly-snapshots
{
"schedule": "0 30 1 * * ?",
"name": "<nightly-snap-{now/d}>",
"repository": "my_backups",
"config": {
"indices": ["*"],
"ignore_unavailable": true
}
}
4 ) 集群状态监控端点
// 在NestJS中实现健康检查
@Get('cluster-health')
async getClusterHealth() {
const { body } = await this.elastic.client.cluster.health();
return {
status: body.status,
node_count: body.number_of_nodes,
active_shards: body.active_shards_percent_as_number,
pending_tasks: body.number_of_pending_tasks
};
}
5 ) 索引生命周期管理(ILM)
PUT _ilm/policy/logs_policy {
"policy": {
"phases": {
"hot": { "actions": { "rollover": { "max_size": "50GB" } } },
"delete": { "min_age": "30d", "actions": { "delete": {} } }
}
}
}
6 ) 索引模板
PUT _index_template/logs_template
{ "template": { "settings": { "number_of_shards": 3 },
"mappings": { "properties": { "@timestamp": { "type": "date" } } }
},
"index_patterns": ["logs-*"]
}
💡 初学者提示:
- Pipeline聚合:对已有聚合结果进行二次计算
- Bucket Script:使用Painless脚本处理多聚合结果
- 双Y轴适用场景:对比单位差异大的指标(如请求数 vs 流量字节数)
关键知识点补充
-
Elasticsearch 聚合类型:
- Metric:
sum,avg,max - Bucket:
terms,date_histogram - Pipeline:
derivative,cumulative_sum
- Metric:
-
Kibana 配置优化:
- 时序索引模板:启用
index.mapping.dynamic_templates自动检测数值类型。 - 冷热数据分层:
ilm_policy自动迁移旧索引至廉价存储。
- 时序索引模板:启用
技术要点
-
Timelion核心优势
- 动态偏移比对:
.es(offset="-1d")实现同期数据对比 - 多轴展示:
.yaxis(2)解决量纲差异问题 - 表达式链:支持>50种数学/统计函数组合
- 动态偏移比对:
-
Visual Builder最佳实践
- Pipeline聚合:通过
bucket_script实现复杂指标计算 - 镜像展示技巧:出站流量乘以-1实现双向对比
- 阈值着色:
color_rules实现自动告警标识
- Pipeline聚合:通过
-
Dashboard设计原则
- 主题聚焦:单仪表板不超过6个核心指标
- 黄金布局:关键指标左上→详情右下
- 动态交互:Controllers实现全局过滤
学习建议:
- 初学者可通过Kibana示例数据导入航班数据集,实操Timelion表达式构建
- 生产环境推荐结合NestJS实现可视化配置管理,避免硬编码查询语句
1183

被折叠的 条评论
为什么被折叠?



