- 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报表
- 竞品对比
源码解析 - discover解析
前文已经说到,kibana.js 中依次加载了各主要功能模块的入口。比如搜索页是 src/core_plugins/kibana/public/discover/index.js
。通过这个文件路径就可以猜到,有关搜索页的功能,代码应该都在 src/core_plugins/kibana/public/discover/
里了。这个目录下的文件有:
- _hit_sort_fn.js
- components/
- controllers/
- directives/
- index.html
- index.js
- partials/
- saved_searches/
- styles/
这也是一个比较标准的 angular 模块的目录结构了。一眼就能知道,controller、directive 等等分别应该进哪里去看。当然首先第一步还是看 index.js:
import 'plugins/kibana/discover/saved_searches/saved_searches';
import 'plugins/kibana/discover/directives/no_results';
import 'plugins/kibana/discover/directives/timechart';
import 'ui/collapsible_sidebar';
import 'plugins/kibana/discover/components/field_chooser/field_chooser';
import 'plugins/kibana/discover/controllers/discover';
import 'plugins/kibana/discover/styles/main.less';
import 'ui/doc_table/components/table_row';
import savedObjectRegistry from 'ui/saved_objects/saved_object_registry';
savedObjectRegistry.register(require('plugins/kibana/discover/saved_searches/saved_search_register'));
已存搜索、事件数趋势图、事件列表、字段列表,各自载入了。下面可以看一下这几个功能点的实现。
plugins/kibana/discover/saved_searches/saved_searches.js
- 定义 savedSearches 这个 angular service,用来操作 kbnIndex 索引里 search 这个类型下的数据;
- 加载了
saved_searches/_saved_searches.js
提供的 savedSearch 这个 angular factory,这里定义了一个搜索 (search) 在kbnIndex
里的数据结构,包括 title, description, hits, column, sort, version 等字段(这部分内容,可以直接通过读取 Elasticsearch 中的索引内容看到,比阅读代码更直接,本章最后即专门介绍kbnIndex
中的数据结构),看的是不是有点眼熟?没错,这个 savedSearch 就是继承了上一节我们介绍的那个 courier 的 savedObject:
module.factory('SavedSearch', function (courier) {
_.class(SavedSearch).inherits(courier.SavedObject);
function SavedSearch(id) {
...
- 还加载并注册了
plugins/kibana/management/saved_object_registry
,表示可以在 management 里修改这里的 savedSearches 对象。
plugins/kibana/discover/directives/timechart.js
- 加载
ui/vislib
。 - 提供 discoverTimechart 这个 angular directive,监听 “data” 并调用
vislib.Chart
对象绘图。
vislib 是整个 Kibana 可视化的实现部分,下一节会更详细的讲述。
plugins/kibana/discover/components/field_chooser/field_chooser.js
- 提供 discFieldChooser 这个 angular directive,其中监听字段和事件的变化,并调用计算常用字段排行,
$scope.$watchMulti([
'[]fieldCounts',
'[]columns',
'[]hits'
], function (cur, prev) {
var newHits = cur[2] !== prev[2];
var fields = $scope.fields;
var columns = $scope.columns || [];
var fieldCounts = $scope.fieldCounts;
if (!fields || newHits) {
$scope.fields = fields = getFields();
}
_.chain(fields)
.each(function (field) {
field.displayOrder = _.indexOf(columns, field.name) + 1;
field.display = !!field.displayOrder;
field.rowCount = fieldCounts[field.name];
})
.sortBy(function (field) {
return (field.count || 0) * -1;
})
.groupBy(function (field) {
if (field.display) return 'selected';
return field.count > 0 ? 'popular' : 'unpopular';
})
.tap(function (groups) {
groups.selected = _.sortBy(groups.selected || [], 'displayOrder');
groups.popular = groups.popular || [];
groups.unpopular = groups.unpopular || [];
var extras = groups.popular.splice(config.get('fields:popularLimit'));
groups.unpopular = extras.concat(groups.unpopular);
})
.each(function (group, name) {
$scope[name + 'Fields'] = _.sortBy(group, name === 'selected' ? 'display' : 'name');
})
.commit();
$scope.fieldTypes = _.union([undefined], _.pluck(fields, 'type'));
});
监听 “data” 并调用 $scope.details()
方法,
提供 $scope.vizLocation()
方法。方法中,根据字段的类型不同,分别可能使用 date_histogram
/geohash_grid
/terms
聚合函数,创建可视化模型,然后带着当前页这些设定——前面说过,各 app 之间通过 globalState 共享状态,也就是 URL 中的 ?_a=(...)
。各 app 会通过 rison.decode($location.search()._a)
和 rison.encode($location.search()._a)
设置和读取——跳转到 “/visualize/create” 页面,相当于是这三个常用聚合的快速可视化操作。
默认的 create 页的 rison 如下:
return '#/visualize/create?' + $.param(_.assign($location.search(), {
indexPattern: $scope.state.index,
type: type,
_a: rison.encode({
filters: $scope.state.filters || [],
query: $scope.state.query || undefined,
vis: {
type: type,
aggs: [
agg,
{schema: 'metric', type: 'count', 'id': '2'}
]
}
})
});
之前章节的 url 示例中,读者如果注意的话,会发现 id 是从 2 开始的,原因即在此。
- 加载
plugins/kibana/discover/components/field_chooser/lib/field_calculator.js
,提供fieldCalculator.getFieldValueCounts()
方法,在$scope.details()
中读取被点击的字段值的情况。 - 加载
plugins/kibana/discover/components/field_chooser/discover_field.js
,提供 discoverField 这个 angular directive,用于弹出浮层展示临时的 visualize(调用上一条提供的$scope.details()
方法),同时给被点击的字段加常用度;加载plugins/kibana/discover/components/field_chooser/lib/detail_views/string.html
网页,用于浮层效果。网页中对 indexed 或 scripted 类型的字段,可以调用前面提到的vizLocation()
方法。
import detailsHtml from 'plugins/kibana/discover/components/field_chooser/lib/detail_views/string.html';
$scope.toggleDetails = function (field, recompute) {
if (_.isUndefined(field.details) || recompute) {
// This is inherited from fieldChooser
$scope.details(field, recompute);
detailScope.$destroy();
detailScope = $scope.$new();
detailScope.warnings = getWarnings(field);
detailsElem = $(detailsHtml);
$compile(detailsElem)(detailScope);
$elem.append(detailsElem).addClass('active');
} else {
delete field.details;
detailsElem.remove();
$elem.removeClass('active');
}
};
- 加载并渲染
plugins/kibana/discover/components/field_chooser/field_chooser.html
网页。网页中使用了上一条提供的 discover-field。
plugins/kibana/discover/controllers/discover.js
加载了诸多 js,主要做了:
- 为 “/discover/:id?” 提供 route 并加载
plugins/discover/index.html
网页。 - 提供 discoverApp 这个 angular controller。
- 加载
ui/vis.js
并在 setupVisualization 函数中绘制 histogram 图。
var visStateAggs = [
{
type: 'count',
schema: 'metric'
},
{
type: 'date_histogram',
schema: 'segment',
params: {
field: $scope.opts.timefield,
interval: $state.interval
}
}
];
$scope.vis = new Vis($scope.indexPattern, {
title: savedSearch.title,
type: 'histogram',
params: {
addLegend: false,
addTimeMarker: true
},
listeners: {
click: function (e) {
timefilter.time.from = moment(e.point.x);
timefilter.time.to = moment(e.point.x + e.data.ordered.interval);
timefilter.time.mode = 'absolute';
},
brush: brushEvent
},
aggs: visStateAggs
});
$scope.searchSource.aggs(function () {
$scope.vis.requesting();
return $scope.vis.aggs.toDsl();
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论