- Logstash
- Logstash - 入门示例
- 入门示例 - 下载安装
- 入门示例 - hello world
- 入门示例 - 配置语法
- 入门示例 - plugin的安装
- 入门示例 - 长期运行
- Logstash - 插件配置
- 插件配置 - input配置
- input配置 - file
- input配置 - stdin
- input配置 - syslog
- input配置 - tcp
- 插件配置 - codec配置
- codec配置 - json
- codec配置 - multiline
- codec配置 - collectd
- codec配置 - netflow
- 插件配置 - filter配置
- filter配置 - date
- filter配置 - grok
- filter配置 - dissect
- filter配置 - geoip
- filter配置 - json
- filter配置 - kv
- filter配置 - metrics
- filter配置 - mutate
- filter配置 - ruby
- filter配置 - split
- filter配置 - elapsed
- 插件配置 - output配置
- output配置 - elasticsearch
- output配置 - email
- output配置 - exec
- output配置 - file
- output配置 - nagios
- output配置 - statsd
- output配置 - stdout
- output配置 - tcp
- output配置 - hdfs
- Logstash - 场景示例
- 场景示例 - nginx访问日志
- 场景示例 - nginx错误日志
- 场景示例 - postfix日志
- 场景示例 - ossec日志
- 场景示例 - windows系统日志
- 场景示例 - Java日志
- 场景示例 - MySQL慢查询日志
- Logstash - 性能与测试
- 性能与测试 - generator方式
- 性能与测试 - 监控方案
- 监控方案 - logstash-input-heartbeat方式
- 监控方案 - jmx启动参数方式
- 监控方案 - API方式
- Logstash - 扩展方案
- 扩展方案 - 通过redis传输
- 扩展方案 - 通过kafka传输
- 扩展方案 - AIX 平台上的logstash-forwarder-java
- 扩展方案 - rsyslog
- 扩展方案 - nxlog
- 扩展方案 - heka
- 扩展方案 - fluent
- 扩展方案 - Message::Passing
- Logstash - 源码解析
- 源码解析 - pipeline流程
- 源码解析 - Event的生成
- Logstash - 插件开发
- 插件开发 - utmp插件示例
- Beats
- Beats - filebeat
- Beats - packetbeat网络流量分析
- Beats - metricbeat
- Beats - winlogbeat
- ElasticSearch
- ElasticSearch - 架构原理
- 架构原理 - segment、buffer和translog对实时性的影响
- 架构原理 - segment merge对写入性能的影响
- 架构原理 - routing和replica的读写过程
- 架构原理 - shard的allocate控制
- 架构原理 - 自动发现的配置
- ElasticSearch - 接口使用示例
- 接口使用示例 - 增删改查操作
- 接口使用示例 - 搜索请求
- 接口使用示例 - Painless脚本
- 接口使用示例 - reindex接口
- ElasticSearch - 性能优化
- 性能优化 - bulk提交
- 性能优化 - gateway配置
- 性能优化 - 集群状态维护
- 性能优化 - 缓存
- 性能优化 - fielddata
- 性能优化 - curator工具
- 性能优化 - profile接口
- ElasticSearch - rally测试方案
- ElasticSearch - 多集群互联
- ElasticSearch - 别名的应用
- ElasticSearch - 映射与模板的定制
- ElasticSearch - puppet-elasticsearch模块的使用
- ElasticSearch - 计划内停机升级的操作流程
- ElasticSearch - 镜像备份
- ElasticSearch - rollover和shrink
- ElasticSearch - Ingest节点
- ElasticSearch - Hadoop 集成
- Hadoop 集成 - spark streaming交互
- ElasticSearch - 权限管理
- 权限管理 - Shield
- 权限管理 - Search-Guard 在 Elasticsearch 2.x 上的运用
- ElasticSearch - 监控方案
- 监控方案 - 监控相关接口
- 监控相关接口 - 集群健康状态
- 监控相关接口 - 节点状态
- 监控相关接口 - 索引状态
- 监控相关接口 - 任务管理
- 监控相关接口 - cat 接口的命令行使用
- 监控方案 - 日志记录
- 监控方案 - 实时bigdesk方案
- 监控方案 - cerebro
- 监控方案 - zabbix trapper方案
- ElasticSearch - ES在运维监控领域的其他玩法
- ES在运维监控领域的其他玩法 - percolator接口
- ES在运维监控领域的其他玩法 - watcher报警
- ES在运维监控领域的其他玩法 - ElastAlert
- ES在运维监控领域的其他玩法 - 时序数据库
- ES在运维监控领域的其他玩法 - Grafana
- ES在运维监控领域的其他玩法 - juttle
- ES在运维监控领域的其他玩法 - Etsy的Kale异常检测
- Kibana 5
- Kibana 5 - 安装、配置和运行
- Kibana 5 - 生产环境部署
- Kibana 5 - discover功能
- Kibana 5 - 各visualize功能
- 各visualize功能 - area
- 各visualize功能 - table
- 各visualize功能 - line
- 各visualize功能 - markdown
- 各visualize功能 - metric
- 各visualize功能 - pie
- 各visualize功能 - tile map
- 各visualize功能 - vertical bar
- Kibana 5 - dashboard功能
- Kibana 5 - timelion 介绍
- Kibana 5 - console 介绍
- Kibana 5 - setting功能
- Kibana 5 - 常用sub agg示例
- 常用sub agg示例 - 函数堆栈链分析
- 常用sub agg示例 - 分图统计
- 常用sub agg示例 - TopN的时序趋势图
- 常用sub agg示例 - 响应时间的百分占比趋势图
- 常用sub agg示例 - 响应时间的概率分布在不同时段的相似度对比
- Kibana 5 - 源码解析
- 源码解析 - .kibana索引的数据结构
- 源码解析 - 主页入口
- 源码解析 - discover解析
- 源码解析 - visualize解析
- 源码解析 - dashboard解析
- Kibana 5 - 插件
- 插件 - 可视化开发示例
- 插件 - 后端开发示例
- 插件 - 完整app开发示例
- Kibana 5 - Kibana报表
- 竞品对比
插件 - 后端开发示例
上一节介绍了如何给 Kibana 开发浏览器端的可视化插件。新版 Kibana 跟 Kibana3 比,最大的一个变化是有了独立的 node.js 服务器端。那么同样的,也就有了服务器端的 Kibana 插件。最明显的一个场景:我们可以在 node.js 里跑定时器做 Elasticsearch 的告警逻辑了!
本节示例一个最基础的 Kibana 告警插件开发。只演示基础的定时器和 Kibana 插件规范,实际运用中,肯定还涉及历史记录,告警项配置更新等。请读者不要直接 copy-paste。
首先,我们尽量沿袭 Elastic 官方的 watcher 产品的告警配置设计。也新建一个索引,里面是具体的配置内容:
# curl -XPUT http://127.0.0.1:9200/watcher/watch/error_status -d'
{
"trigger": {
"schedule" : { "interval" : "60" }
},
"input" : {
"search" : {
"request" : {
"indices" : [ "<logstash-{now/d}>", "<logstash-{now/d-1d}>" ],
"body" : {
"query" : {
"filtered" : {
"query" : { "match" : { "host" : "MacBook-Pro" } },
"filter" : { "range" : { "@timestamp" : { "from" : "now-5m" } } }
}
}
}
}
}
},
"condition" : {
"script" : {
"script" : "payload.hits.total > 0"
}
},
"transform" : {
"search" : {
"request" : {
"indices" : [ "<logstash-{now/d}>", "<logstash-{now/d-1d}>" ],
"body" : {
"query" : {
"filtered" : {
"query" : { "match" : { "host" : "MacBook-Pro" } },
"filter" : { "range" : { "@timestamp" : { "from" : "now-5m" } } }
}
},
"aggs" : {
"topn" : {
"terms" : {
"field" : "path.raw"
}
}
}
}
}
}
},
"actions" : {
"email_admin" : {
"throttle_period" : "15m",
"email" : {
"to" : "admin@domain",
"subject" : "Found {{payload.hits.total}} Error Events",
"priority" : "high",
"body" : "Top10 paths:n{{#payload.aggregations.topn.buckets}}t{{key}} {{doc_count}}n{{/payload.aggregations.topn.buckets}}"
}
}
}
}'
我们可以看到,跟原版的相比,只改动了很小的一些地方:
- 为了简便,
interval
固定写数值,没带s/m/d/H
之类的单位; condition
里直接使用了 JavaScript,这点也是 ES 2.x 的 mapping 要求跟 watcher 本身有冲突的一个地方:watcher的"ctx.payload.hits.total" : { "gt" : 0 }
这种写法,如果是普通索引,会因为字段名里带.
直接写入失败的;- 因为是在 Kibana 里面运行,所以从 ES 拿到的只有 payload(也就是查询响应),所以把里面的
ctx.
都删掉了。
好,然后创建插件:
cd kibana-4.3.0-darwin-x64/src/plugins
mkdir alert
在自定义插件目录底下创建 package.json
描述:
{
"name": "alert",
"version": "0.0.1"
}
以及最终的 index.js
代码:
'use strict';
module.exports = function (kibana) {
var later = require('later');
var _ = require('lodash');
var mustache = require('mustache');
return new kibana.Plugin({
init: function init(server) {
var client = server.plugins.elasticsearch.client;
var sched = later.parse.text('every 10 minute');
later.setInterval(doalert, sched);
function doalert() {
getCount().then(function(resp){
getWatcher(resp.count).then(function(resp){
_.each(resp.hits.hits, function(hit){
var watch = hit._source;
var every = watch.trigger.schedule.interval;
var watchSched = later.parse.recur().every(every).second();
var wt = later.setInterval(watching, watchSched);
function watching() {
var request = watch.input.search.request;
var condition = watch.condition.script.script;
var transform = watch.transform.search.request;
var actions = watch.actions;
client.search(request).then(function(payload){
var ret = eval(condition);
if (ret) {
client.search(transform).then(function(payload) {
_.each(_.values(actions), function(action){
if(_.has(action, 'email')) {
var subject = mustache.render(action.email.subject, {"payload":payload});
var body = mustache.render(action.email.body, {"payload":payload});
console.log(subject, body);
}
});
});
}
});
}
});
});
});
}
function getCount() {
return client.count({
index:'watcher',
type:"watch"
});
}
function getWatcher(count) {
return client.search({
index:'watcher',
type:"watch",
size:count
});
}
}
});
};
其中用到了两个 npm 模块,later 模块用来实现定时器和 crontab 文本解析,mustache 模块用来渲染邮件内容模板,这也是 watcher 本身采用的渲染模块。
需要安装一下:
npm install later
npm install mustache
然后运行 ./bin/kibana
,就可以看到终端上除了原有的内容以外,还会定期输出 alert 的 email 内容了。
要点解释
这个极简示例中,主要有两段:
- 注册为插件
module.exports = function (kibana) {
return new kibana.Plugin({
init: function init(server) {
注意上一节的可视化插件,这块是:
module.exports = function (kibana) {
return new kibana.Plugin({
uiExports: {
visTypes: [
- 引用 ES client
init: function init(server) {
var client = server.plugins.elasticsearch.client;
这里通过调用 server.plugins
来直接引用 Kibana 里其他插件里的对象。这样,alert 插件就可以跟其他功能共用同一个 ES client,免去单独配置自己的 ES 设置项和新开网络连接的资源消耗。
本节代码后续优化改进,见:https://github.com/chenryn/kaae。项目中还附带有一个 spy 式插件,有兴趣的读者可以继续学习 spy 这类不太常见的插件扩展的用法。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论