嘿~ 今天天气不错嘛
kibana

kibana

Web Scraper + Elasticsearch + Kibana + SearchKit 打造的豆瓣电影top250 搜索演示系统

Elasticsearch 发表了文章 • 0 个评论 • 4517 次浏览 • 2023-04-09 10:56 • 来自相关话题

Web Scraper + Elasticsearch + Kibana + SearchKit 打造的豆瓣电影top250 搜索演示系统

作者:小森同学

声明:电影数据来源于“豆瓣电影”,如有侵权,请联系删除

1.png

2.png

Web Scraper

{
    "_id": "top250",
    "startUrl": ["https://movie.douban.com/top250?start=[0-225:25]&filter="],
    "selectors": [{
        "id": "container",
        "multiple": true,
        "parentSelectors": ["_root"],
        "selector": ".grid_view li",
        "type": "SelectorElement"
    }, {
        "id": "name",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "span.title:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "number",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "em",
        "type": "SelectorText"
    }, {
        "id": "score",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "span.rating_num",
        "type": "SelectorText"
    }, {
        "id": "review",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "span.inq",
        "type": "SelectorText"
    }, {
        "id": "year",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "\\d{4}",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "tour_guide",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "^导演: \\S*",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "type",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "[^/]+$",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "area",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "[^\\/]+(?=\\/[^\\/]*$)",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "detail_link",
        "multiple": false,
        "parentSelectors": ["container"],
        "selector": ".hd a",
        "type": "SelectorLink"
    }, {
        "id": "director",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "",
        "selector": "span:nth-of-type(1) .attrs a",
        "type": "SelectorText"
    }, {
        "id": "screenwriter",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=编剧: )[\\u4e00-\\u9fa5A-Za-z0-9/()\\·\\s]+(?=主演)",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "film_length",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "\\d+",
        "selector": "span[property='v:runtime']",
        "type": "SelectorText"
    }, {
        "id": "IMDb",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=[IMDb:\\s+])\\S*(?=\\d*$)",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "language",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=语言: )\\S+",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "alias",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=又名: )[\\u4e00-\\u9fa5A-Za-z0-9/()\\s]+(?=IMDb)",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "pic",
        "multiple": false,
        "parentSelectors": ["container"],
        "selector": "img",
        "type": "SelectorImage"
    }]
}

elasticsearch

{
    "mappings": {
      "properties": {
        "IMDb": {
          "type": "keyword",
          "copy_to": [
            "all"
          ]
        },
        "alias": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "all": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "area": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "director": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "film_length": {
          "type": "long"
        },
        "id": {
          "type": "keyword"
        },
        "language": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "link": {
          "type": "keyword"
        },
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "number": {
          "type": "long"
        },
        "photo": {
          "type": "keyword"
        },
        "review": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "score": {
          "type": "double"
        },
        "screenwriter": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "type": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "year": {
          "type": "long"
        }
      }
    }
  }

kibana

需要使用pipeline对索引字段进行处理,如对type 通过空格进行分割为数组等,可以参照官方文档或其他博客。

制作仪表板省略, 请自行搜索

SearchKit

参考 https://github.com/searchkit/searchkit-starter-app

kibana搜索10000条输入限制如何解除

回复

Kibanaonionwithhoney 发起了问题 • 1 人关注 • 0 个回复 • 4966 次浏览 • 2023-01-05 15:02 • 来自相关话题

怎么查看 Kibana dashboard中最终执行的query语句

Kibanasdx 回复了问题 • 2 人关注 • 1 个回复 • 989 次浏览 • 2022-07-08 11:19 • 来自相关话题

在 Kibana 里统一访问来自不同集群的索引

资料分享medcl 发表了文章 • 0 个评论 • 1370 次浏览 • 2022-04-21 15:29 • 来自相关话题

在 Kibana 里统一访问来自不同集群的索引

现在有这么一个需求,客户根据需要将数据按照业务维度划分,将索引分别存放在了不同的三个集群, 将一个大集群拆分成多个小集群有很多好处,比如降低了耦合,带来了集群可用性和稳定性方面的好处,也避免了单个业务的热点访问造成其他业务的影响, 尽管拆分集群是很常见的玩法,但是管理起来不是那么方便了,尤其是在查询的时候,可能要分别访问三套集群各自的 API,甚至要切换三套不同的 Kibana 来访问集群的数据, 那么有没有办法将他们无缝的联合在一起呢?

极限网关!

答案自然是有的,通过将 Kibana 访问 Elasticsearch 的地址切换为极限网关的地址,我们可以将请求按照索引来进行智能的路由, 也就是当访问不同的业务索引时会智能的路由到不同的集群,如下图:

WechatIMG27.png

上图,我们分别有 3 个不同的索引:

  • apm-*
  • erp-*
  • mall-*

分别对应不同的三套 Elasticsearch 集群:

  • ES1-APM
  • ES2-ERP
  • ES3-MALL

接下来我们来看如何在极限网关里面进行相应的配置来满足这个业务需求。

配置集群信息

首先配置 3 个集群的连接信息。

elasticsearch:
  - name: es1-apm
    enabled: true
    endpoints:
     - http://192.168.3.188:9206
  - name: es2-erp
    enabled: true
    endpoints:
     - http://192.168.3.188:9207
  - name: es3-mall
    enabled: true
    endpoints:
     - http://192.168.3.188:9208

配置服务 Flow

然后,我们定义 3 个 Flow,分别对应用来访问 3 个不同的 Elasticsearch 集群,如下:

flow:
  - name: es1-flow
    filter:
      - elasticsearch:
          elasticsearch: es1-apm
  - name: es2-flow
    filter:
      - elasticsearch:
          elasticsearch: es2-erp
  - name: es3-flow
    filter:
      - elasticsearch:
          elasticsearch: es3-mall

然后再定义一个 flow 用来进行路径的判断和转发,如下:

  - name: default-flow
    filter:
      - switch:
          remove_prefix: false
          path_rules:
            - prefix: apm-
              flow: es1-flow
            - prefix: erp-
              flow: es2-flow
            - prefix: mall-
              flow: es3-flow
      - flow: #default flow
          flows:
            - es1-flow

根据请求路径里面的索引前缀来匹配不同的索引,并转发到不同的 Flow。

配置路由信息

接下来,我们定义路由信息,具体配置如下:

router:
  - name: my_router
    default_flow: default-flow

指向上面定义的默认 flow 来统一请求的处理。

定义服务及关联路由

最后,我们定义一个监听为 8000 端口的服务,用来提供给 Kibana 来进行统一的入口访问,如下:

entry:
  - name: es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: 0.0.0.0:8000

完整配置

最后的完整配置如下:

path.data: data
path.logs: log

entry:
  - name: es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: 0.0.0.0:8000

flow:
  - name: default-flow
    filter:
      - switch:
          remove_prefix: false
          path_rules:
            - prefix: apm-
              flow: es1-flow
            - prefix: erp-
              flow: es2-flow
            - prefix: mall-
              flow: es3-flow
      - flow: #default flow
          flows:
            - es1-flow
  - name: es1-flow
    filter:
      - elasticsearch:
          elasticsearch: es1-apm
  - name: es2-flow
    filter:
      - elasticsearch:
          elasticsearch: es2-erp
  - name: es3-flow
    filter:
      - elasticsearch:
          elasticsearch: es3-mall

router:
  - name: my_router
    default_flow: default-flow

elasticsearch:
  - name: es1-apm
    enabled: true
    endpoints:
     - http://192.168.3.188:9206
  - name: es2-erp
    enabled: true
    endpoints:
     - http://192.168.3.188:9207
  - name: es3-mall
    enabled: true
    endpoints:
     - http://192.168.3.188:9208

启动网关

直接启动网关,如下:

➜  gateway git:(master) ✗ ./bin/gateway -config sample-configs/elasticsearch-route-by-index.yml 

   ___   _   _____  __  __    __  _       
  / _ \ /_\ /__   \/__\/ / /\ \ \/_\ /\_/\
 / /_\///_\\  / /\/_\  \ \/  \/ //_\\\_ _/
/ /_\\/  _  \/ / //__   \  /\  /  _  \/ \ 
\____/\_/ \_/\/  \__/    \/  \/\_/ \_/\_/ 

[GATEWAY] A light-weight, powerful and high-performance elasticsearch gateway.
[GATEWAY] 1.0.0_SNAPSHOT, 2022-04-20 08:23:56, 2023-12-31 10:10:10, 51650a5c3d6aaa436f3c8a8828ea74894c3524b9
[04-21 13:41:21] [INF] [app.go:174] initializing gateway.
[04-21 13:41:21] [INF] [app.go:175] using config: /Users/medcl/go/src/infini.sh/gateway/sample-configs/elasticsearch-route-by-index.yml.
[04-21 13:41:21] [INF] [instance.go:72] workspace: /Users/medcl/go/src/infini.sh/gateway/data/gateway/nodes/c9bpg0ai4h931o4ngs3g
[04-21 13:41:21] [INF] [app.go:283] gateway is up and running now.
[04-21 13:41:21] [INF] [api.go:262] api listen at: http://0.0.0.0:2900
[04-21 13:41:21] [INF] [reverseproxy.go:255] elasticsearch [es1-apm] hosts: [] => [192.168.3.188:9206]
[04-21 13:41:21] [INF] [reverseproxy.go:255] elasticsearch [es2-erp] hosts: [] => [192.168.3.188:9207]
[04-21 13:41:21] [INF] [reverseproxy.go:255] elasticsearch [es3-mall] hosts: [] => [192.168.3.188:9208]
[04-21 13:41:21] [INF] [actions.go:349] elasticsearch [es2-erp] is available
[04-21 13:41:21] [INF] [actions.go:349] elasticsearch [es1-apm] is available
[04-21 13:41:21] [INF] [entry.go:312] entry [es_entry] listen at: http://0.0.0.0:8000
[04-21 13:41:21] [INF] [module.go:116] all modules are started
[04-21 13:41:21] [INF] [actions.go:349] elasticsearch [es3-mall] is available
[04-21 13:41:55] [INF] [reverseproxy.go:255] elasticsearch [es1-apm] hosts: [] => [192.168.3.188:9206]

网关启动成功之后,就可以通过网关的 IP+8000 端口来访问目标 Elasticsearch 集群了。

测试访问

首先通过 API 来访问测试一下,如下:

➜  ~ curl http://localhost:8000/apm-2022/_search -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /apm-2022/_search HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 21 Apr 2022 05:45:44 GMT
< content-type: application/json; charset=UTF-8
< Content-Length: 162
< X-elastic-product: Elasticsearch
< X-Backend-Cluster: es1-apm
< X-Backend-Server: 192.168.3.188:9206
< X-Filters: filters->elasticsearch
< 
* Connection #0 to host localhost left intact
{"took":142,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":0,"relation":"eq"},"max_score":null,"hits":[]}}%  

可以看到 apm-2022 指向了后端的 es1-apm 集群。

继续测试,erp 索引的访问,如下:

➜  ~ curl http://localhost:8000/erp-2022/_search -v 
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /erp-2022/_search HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 21 Apr 2022 06:24:46 GMT
< content-type: application/json; charset=UTF-8
< Content-Length: 161
< X-Backend-Cluster: es2-erp
< X-Backend-Server: 192.168.3.188:9207
< X-Filters: filters->switch->filters->elasticsearch->skipped
< 
* Connection #0 to host localhost left intact
{"took":12,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":0,"relation":"eq"},"max_score":null,"hits":[]}}%

继续测试,mall 索引的访问,如下:

➜  ~ curl http://localhost:8000/mall-2022/_search -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /mall-2022/_search HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 21 Apr 2022 06:25:08 GMT
< content-type: application/json; charset=UTF-8
< Content-Length: 134
< X-Backend-Cluster: es3-mall
< X-Backend-Server: 192.168.3.188:9208
< X-Filters: filters->switch->filters->elasticsearch->skipped
< 
* Connection #0 to host localhost left intact
{"took":8,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}% 

完美转发。

修改 Kibana 配置

修改 Kibana 的配置文件: kibana.yml,替换 Elasticsearch 的地址为网关地址(http://192.168.3.200:8000),如下:

elasticsearch.hosts: ["http://192.168.3.200:8000"]

重启 Kibana 让配置生效。

效果如下

kibana-clusers-op.jpg

可以看到,在一个 Kibana 的开发者工具里面,我们已经可以像操作一个集群一样来同时读写实际上来自三个不同集群的索引数据了。

展望

通过极限网关,我们还可以非常灵活的进行在线请求的流量编辑,动态组合不同集群的操作。

使用极限网关来代理 Kibana

Kibanamedcl 发表了文章 • 0 个评论 • 1567 次浏览 • 2022-02-15 20:29 • 来自相关话题

我的 Kibana 版本太旧了,我的 Kibana 没有密码保护,我的 Kibana 没有权限控制。烦不胜烦。  来来来,几个简单步骤告别不舒服的这几个问题,如下: 下载最新的 530 版本:http://release.elasticsearch.cn/gateway/snapshot/   找到配置:
entry:
  - name: my_es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: 0.0.0.0:8000
      skip_occupied_port: true
    tls:
      enabled: true

flow:
  - name: default_flow
    filter:
      - basic_auth:
          valid_users:
            medcl: passwd
      - http:
          schema: "http" #https or http
          host: "192.168.3.98:5601"
router:
  - name: my_router
    default_flow: default_flow
修改里面的 ip 为你实际的 Kibana IP 地址,如需多个,使用 hosts 参数,详见文档手册:   https://极限网关.com/docs/references/filters/http/   启动网关,因为自动开启了 https,访问网关的服务地址:https://localhost:8000,如下:
Jietu20220215-202309.jpg
  输入配置的用户名密码,即可。  
Jietu20220215-202414.jpg

Elastic日报 第1307期 (2021-01-12)

Elastic日报kin122 发表了文章 • 0 个评论 • 935 次浏览 • 2022-01-12 10:13 • 来自相关话题

1. Elasticsearch:如何将浮点值存储到整型字段中 https://elasticstack.blog.csdn ... 59801 2. Kibana使用:Search Bar https://cloud.tencent.com/deve ... 77628 3. Logstash:Pipeline-to-Pipeline 通信 - 一个实例处理多种日志 https://blog.csdn.net/UbuntuTo ... 29091 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup
1. Elasticsearch:如何将浮点值存储到整型字段中 https://elasticstack.blog.csdn ... 59801 2. Kibana使用:Search Bar https://cloud.tencent.com/deve ... 77628 3. Logstash:Pipeline-to-Pipeline 通信 - 一个实例处理多种日志 https://blog.csdn.net/UbuntuTo ... 29091 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup

7.14 Kibana 默认时间排序

回复

KibanaTsukiand 回复了问题 • 1 人关注 • 1 个回复 • 2670 次浏览 • 2021-11-20 16:58 • 来自相关话题

Elastic日报 第1245期 (2021-11-10)

Elastic日报kin122 发表了文章 • 0 个评论 • 896 次浏览 • 2021-11-10 09:41 • 来自相关话题

1. Lucene源码解析——StoredField存储方式 https://zhuanlan.zhihu.com/p/384486147 2.如何在 Kibana 的 Discover 界面中让显示图片字段 https://www.bilibili.com/video/BV14P4y1L7XL/ https://elasticstack.blog.csdn ... 19074 3. 几种常见的查询性能问题及优化方式--字节:张超 https://mp.weixin.qq.com/s/w7hEn2JE9ZXUBh3kZ0uOGg 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup
1. Lucene源码解析——StoredField存储方式 https://zhuanlan.zhihu.com/p/384486147 2.如何在 Kibana 的 Discover 界面中让显示图片字段 https://www.bilibili.com/video/BV14P4y1L7XL/ https://elasticstack.blog.csdn ... 19074 3. 几种常见的查询性能问题及优化方式--字节:张超 https://mp.weixin.qq.com/s/w7hEn2JE9ZXUBh3kZ0uOGg 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup

kibana7.14配置索引模式权限后页面依旧可以看到

Kibanacaster_QL 回复了问题 • 1 人关注 • 1 个回复 • 1504 次浏览 • 2021-09-30 18:26 • 来自相关话题

kibana 7.14 本地开发模式提示crash

Kibanatongchuan1992 回复了问题 • 2 人关注 • 1 个回复 • 1639 次浏览 • 2021-09-07 10:46 • 来自相关话题

堆栈监测 监测beats bug有人遇到过吗

Kibanatongchuan1992 回复了问题 • 2 人关注 • 1 个回复 • 1542 次浏览 • 2021-07-08 08:47 • 来自相关话题

kibana如何才能使用nested的字段作为可视化的条件?

Kibanaliuxg 回复了问题 • 2 人关注 • 1 个回复 • 1524 次浏览 • 2021-07-02 10:01 • 来自相关话题

kibana如何做出只查询出自己创建的索引的?

回复

Elasticsearchstartjava 发起了问题 • 1 人关注 • 0 个回复 • 1556 次浏览 • 2021-07-01 16:04 • 来自相关话题

新人求教,新安装的kibana,启动成功后访问不了

KibanaSanri99 回复了问题 • 3 人关注 • 2 个回复 • 16376 次浏览 • 2021-05-08 16:15 • 来自相关话题

kibana中dashboard怎么复制使用

KibanaReilee 回复了问题 • 3 人关注 • 1 个回复 • 2440 次浏览 • 2021-01-26 06:28 • 来自相关话题

条新动态, 点击查看
redfree

redfree 回答了问题 • 2018-01-25 14:10 • 10 个回复 不感兴趣

请问kibana有中文版么?

赞同来自:

我来做雷锋吧, Kibana汉化项目 支持kibana5.x - 6.x任意版本 ,英语不好,一部分用翻译汉化的,有错误之处可以发邮件指正。​https://github.com/anbai-inc/Kibana_Hanization 显示全部 »
我来做雷锋吧, Kibana汉化项目 支持kibana5.x - 6.x任意版本 ,英语不好,一部分用翻译汉化的,有错误之处可以发邮件指正。​https://github.com/anbai-inc/Kibana_Hanization
kennywu76

kennywu76 回答了问题 • 2017-11-30 16:50 • 3 个回复 不感兴趣

kibana怎样配置向多个ES请求

赞同来自:

Kibana从5.5开始已经支持cross cluster search。 所以要是用的比较高的版本,配置一下就可以了,参考:https://www.elastic.co/guide/en/kibana/5.5/management-cross-cluster... 显示全部 »
Kibana从5.5开始已经支持cross cluster search。 所以要是用的比较高的版本,配置一下就可以了,参考:https://www.elastic.co/guide/en/kibana/5.5/management-cross-cluster-search.html
延迟不用担心会很小的,建议采集还是用用beat,如果数据量大,就在beat和logstash中间加kafka
延迟不用担心会很小的,建议采集还是用用beat,如果数据量大,就在beat和logstash中间加kafka
bindiego

bindiego 回答了问题 • 2019-07-29 12:44 • 5 个回复 不感兴趣

kibana是否可以画关系网图?

赞同来自:

https://vega.github.io/vega/examples/edge-bundling/
 
Kibana 支持vega,可以试一试,而且时间全局过滤器也是可用的。
https://vega.github.io/vega/examples/edge-bundling/
 
Kibana 支持vega,可以试一试,而且时间全局过滤器也是可用的。

【线下活动-分享主题征集-武汉】 2019年3月 Elastic&尚德机构技术沙龙

活动medcl 回复了问题 • 3 人关注 • 1 个回复 • 5340 次浏览 • 2019-02-22 15:42 • 来自相关话题

使用 Elastic Stack 来监控和调优 Golang 应用程序

Beatsmedcl 发表了文章 • 0 个评论 • 11220 次浏览 • 2017-03-03 11:16 • 来自相关话题

Golang 因为其语法简单,上手快且方便部署正被越来越多的开发者所青睐,一个 Golang 程序开发好了之后,势必要关心其运行情况,今天在这里就给大家介绍一下如果使用 Elastic Stack 来分析 Golang 程序的内存使用情况,方便对 Golang 程序做长期监控进而调优和诊断,甚至发现一些潜在的内存泄露等问题。   Elastic Stack 其实是一个集合,包含 Elasticsearch、Logstash 和 Beats 这几个开源软件,而 Beats 又包含 Filebeat、Packetbeat、Winlogbeat、Metricbeat 和新出的 Heartbeat,呵呵,有点多吧,恩,每个 beat 做的事情不一样,没关系,今天主要用到 Elasticsearch、Metricbeat 和 Kibana 就行了。   Metricbeat 是一个专门用来获取服务器或应用服务内部运行指标数据的收集程序,也是 Golang 写的,部署包比较小才10M 左右,对目标服务器的部署环境也没有依赖,内存资源占用和 CPU 开销也较小,目前除了可以监控服务器本身的资源使用情况外,还支持常见的应用服务器和服务,目前支持列表如下:
  • Apache Module
  • Couchbase Module
  • Docker Module
  • HAProxy Module
  • kafka Module
  • MongoDB Module
  • MySQL Module
  • Nginx Module
  • PostgreSQL Module
  • Prometheus Module
  • Redis Module
  • System Module
  • ZooKeeper Module
当然,也有可能你的应用不在上述列表,没关系,Metricbeat 是可以扩展的,你可以很方便的实现一个模块,而本文接下来所用的 Golang Module 也就是我刚刚为 Metricbeat 添加的扩展模块,目前已经 merge 进入 Metricbeat 的 master 分支,预计会在 6.0 版本发布,想了解是如何扩展这个模块的可以查看 代码路径 和 PR地址。   上面的这些可能还不够吸引人,我们来看一下 Kibana 对 Metricbeat 使用 Golang 模块收集的数据进行的可视化分析吧:
df9c563e-f831-11e6-835c-183f3f9e5b94.png
  上面的图简单解读一下: 最上面一栏是 Golang Heap 的摘要信息,可以大致了解 Golang 的内存使用和 GC 情况,System 表示 Golang 程序从操作系统申请的内存,可以理解为进程所占的内存(注意不是进程对应的虚拟内存),Bytes allocated 表示 Heap 目前分配的内存,也就是 Golang 里面直接可使用的内存,GC limit 表示当 Golang 的 Heap 内存分配达到这个 limit 值之后就会开始执行 GC,这个值会随着每次 GC 而变化, GC cycles 则代表监控周期内的 GC 次数;   中间的三列分别是堆内存、进程内存和对象的统计情况;Heap Allocated 表示正在用和没有用但还未被回收的对象的大小;Heap Inuse 显然就是活跃的对象大小了;Heap Idle 表示已分配但空闲的内存; 底下两列是 GC 时间和 GC 次数的监控统计,CPUFraction 这个代表该进程 CPU 占用时间花在 GC 上面的百分比,值越大说明 GC 越频繁,浪费更多的时间在 GC 上面,上图虽然趋势陡峭,但是看范围在0.41%~0.52%之间,看起来还算可以,如果GC 比率占到个位数甚至更多比例,那肯定需要进一步优化程序了。   有了这些信息我们就能够知道该 Golang 的内存使用和分配情况和 GC 的执行情况,假如要分析是否有内存泄露,看内存使用和堆内存分配的趋势是否平稳就可以了,另外 GC_Limit 和 Byte Allocation 一直上升,那肯定就是有内存泄露了,结合历史信息还能对不同版本/提交对 Golang 的内存使用和 GC 影响进行分析。 接下来就要给大家介绍如何具体使用了,首先需要启用 Golang 的 expvar 服务,expvar(https://golang.org/pkg/expvar/) 是 Golang 提供的一个暴露内部变量或统计信息的标准包。 使用的方法很简单,只需要在 Golang 的程序引入该包即可,它会自动注册现有的 http 服务上,如下:
import _ "expvar"
如果 Golang 没有启动 http 服务,使用下面的方式启动一个即可,这里端口是 6060,如下:
func metricsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")

	first := true
	report := func(key string, value interface{}) {
		if !first {
			fmt.Fprintf(w, ",\n")
		}
		first = false
		if str, ok := value.(string); ok {
			fmt.Fprintf(w, "%q: %q", key, str)
		} else {
			fmt.Fprintf(w, "%q: %v", key, value)
		}
	}

	fmt.Fprintf(w, "{\n")
	expvar.Do(func(kv expvar.KeyValue) {
		report(kv.Key, kv.Value)
	})
	fmt.Fprintf(w, "\n}\n")
}

func main() {
   mux := http.NewServeMux()
   mux.HandleFunc("/debug/vars", metricsHandler)
   endpoint := http.ListenAndServe("localhost:6060", mux)
}
默认注册的访问路径是/debug/vars, 编译启动之后,就可以通过 http://localhost:6060/debug/vars  来访问 expvar 以 JSON 格式暴露出来的这些内部变量,默认提供了 Golang 的 runtime.Memstats 信息,也就是上面分析的数据源,当然你还可以注册自己的变量,这里暂时不提。   OK,现在我们的 Golang 程序已经启动了,并且通过 expvar 暴露出了运行时的内存使用情况,现在我们需要使用 Metricbeat 来获取这些信息并存进 Elasticsearch。   关于 Metricbeat 的安装其实很简单,下载对应平台的包解压(下载地址:https://www.elastic.co/downloads/beats/metricbeat ),启动 Metricbeat 前,修改配置文件:metricbeat.yml
metricbeat.modules:
  - module: golang
     metricsets: ["heap"]
     enabled: true
     period: 10s
     hosts: ["localhost:6060"]
     heap.path: "/debug/vars"
上面的参数启用了 Golang 监控模块,并且会10秒获取一次配置路径的返回内存数据,我们同样配置该配置文件,设置数据输出到本机的 Elasticsearch:
output.elasticsearch:
  hosts: ["localhost:9200"]
现在启动 Metricbeat:
./metricbeat -e -v
现在在 Elasticsearch 应该就有数据了,当然记得确保 Elasticsearch 和 Kibana 是可用状态,你可以在 Kibana 根据数据灵活自定义可视化,推荐使用 Timelion 来进行分析,当然为了方便也可以直接导入提供的样例仪表板,就是上面第一个图的效果。 关于如何导入样例仪表板请参照这个文档:https://www.elastic.co/guide/e ... .html    除了监控已经有的内存信息之外,如果你还有一些内部的业务指标想要暴露出来,也是可以的,通过 expvar 来做同样可以。一个简单的例子如下:
var inerInt int64 = 1024
pubInt := expvar.NewInt("your_metric_key")
pubInt.Set(inerInt)
pubInt.Add(2)
在 Metricbeat 内部也同样暴露了很多内部运行的信息,所以 Metricbeat 可以自己监控自己了。。。 首先,启动的时候带上参数设置pprof监控的地址,如下:
./metricbeat -httpprof="127.0.0.1:6060" -e -v
这样我们就能够通过 [url=http://127.0.0.1:6060/debug/vars]http://127.0.0.1:6060/debug/vars[/url] 访问到内部运行情况了,如下:
{
"output.events.acked": 1088,
"output.write.bytes": 1027455,
"output.write.errors": 0,
"output.messages.dropped": 0,
"output.elasticsearch.publishEvents.call.count": 24,
"output.elasticsearch.read.bytes": 12215,
"output.elasticsearch.read.errors": 0,
"output.elasticsearch.write.bytes": 1027455,
"output.elasticsearch.write.errors": 0,
"output.elasticsearch.events.acked": 1088,
"output.elasticsearch.events.not_acked": 0,
"output.kafka.events.acked": 0,
"output.kafka.events.not_acked": 0,
"output.kafka.publishEvents.call.count": 0,
"output.logstash.write.errors": 0,
"output.logstash.write.bytes": 0,
"output.logstash.events.acked": 0,
"output.logstash.events.not_acked": 0,
"output.logstash.publishEvents.call.count": 0,
"output.logstash.read.bytes": 0,
"output.logstash.read.errors": 0,
"output.redis.events.acked": 0,
"output.redis.events.not_acked": 0,
"output.redis.read.bytes": 0,
"output.redis.read.errors": 0,
"output.redis.write.bytes": 0,
"output.redis.write.errors": 0,
"beat.memstats.memory_total": 155721720,
"beat.memstats.memory_alloc": 3632728,
"beat.memstats.gc_next": 6052800,
"cmdline": ["./metricbeat","-httpprof=127.0.0.1:6060","-e","-v"],
"fetches": {"system-cpu": {"events": 4, "failures": 0, "success": 4}, "system-filesystem": {"events": 20, "failures": 0, "success": 4}, "system-fsstat": {"events": 4, "failures": 0, "success": 4}, "system-load": {"events": 4, "failures": 0, "success": 4}, "system-memory": {"events": 4, "failures": 0, "success": 4}, "system-network": {"events": 44, "failures": 0, "success": 4}, "system-process": {"events": 1008, "failures": 0, "success": 4}},
"libbeat.config.module.running": 0,
"libbeat.config.module.starts": 0,
"libbeat.config.module.stops": 0,
"libbeat.config.reloads": 0,
"memstats": {"Alloc":3637704,"TotalAlloc":155
... ...
比如,上面就能看到output模块Elasticsearch的处理情况,如 output.elasticsearch.events.acked 参数表示发送到 Elasticsearch Ack返回之后的消息。   现在我们要修改 Metricbeat 的配置文件,Golang 模块有两个 metricset,可以理解为两个监控的指标类型,我们现在需要加入一个新的 expvar 类型,这个即自定义的其他指标,相应配置文件修改如下:
- module: golang
  metricsets: ["heap","expvar"]
  enabled: true
  period: 1s
  hosts: ["localhost:6060"]
  heap.path: "/debug/vars"
  expvar:
    namespace: "metricbeat"
    path: "/debug/vars"
上面的一个参数 namespace 表示自定义指标的一个命令空间,主要是为了方便管理,这里是 Metricbeat 自身的信息,所以 namespace 就是 metricbeat。   重启 Metricbeat 应该就能收到新的数据了,我们前往 Kibana。   这里假设关注 output.elasticsearch.events.acked和 output.elasticsearch.events.not_acked这两个指标,我们在Kibana里面简单定义一个曲线图就能看到 Metricbeat 发往 Elasticsearch 消息的成功和失败趋势。 Timelion 表达式:
.es("metricbeat*",metric="max:golang.metricbeat.output.elasticsearch.events.acked").derivative().label("Elasticsearch Success"),.es("metricbeat*",metric="max:golang.metricbeat.output.elasticsearch.events.not_acked").derivative().label("Elasticsearch Failed")
效果如下:
Snip20170304_9.png
从上图可以看到,发往 Elasticsearch 的消息很稳定,没有出现丢消息的情况,同时关于 Metricbeat 的内存情况,我们打开导入的 Dashboard 查看:
Snip20170304_10.png
关于如何使用 Metricbeat 来监控 Golang 应用程序的内容基本上就差不多到这里了,上面介绍了如何基于 expvar 来监控 Golang 的内存情况和自定义业务监控指标,在结合 Elastic Stack 可以快速的进行分析,希望对大家有用。 最后,这个 Golang 模块目前还没 release,估计在 beats 6.0 发布,有兴趣尝鲜的可以自己下载源码打包。

对话 Kibana 之父:如果需要,你应该自己动手编写工具

资讯动态medcl 发表了文章 • 2 个评论 • 8499 次浏览 • 2017-01-11 11:45 • 来自相关话题

转载:http://www.infoq.com/cn/news/2 ... nToolElastic 中国开发者大会 2016上,ELK 正式宣布更名为“Elastic Stack”,Elastic公司称其开源项目累计已经有8000万次下载。Elastic Stack 最新版本为5.0,从此,Elastic公司会对Elasticsearch、Kibana、Logstash、Beats、X-Pack进行统一规划以同版本号码发布。会上,Kibana 的原作者 Rashid Khan 进行了题为《Kibana 5.0: The Window into the Elastic Stack》。 PPT下载:http://elasticsearch.cn/article/122 
IMG_4857.gif
早在2001年,Rashid 就接触了运维工作,他的第一份工作是在摩根大通集团做网络运维管理分析员。2012年,Rashid 在美国一家媒体公司担任架构工程师,并且研发了 Kibana 的初始版本,那时他的目的是专门设计界面以适配 Logstash,如今 Kibana 已经逐渐演变成了 Elasticsearch 的分析平台。运维出身的他是在怎样的情况下开始了 Kibana 开发,Kibana 走到今天经历了什么,将来 Kibana 的发展会是怎样的?InfoQ 对 Rashid 进行了采访,以下文章来自于采访稿件的整理。 作为运维人员,我亟须优化日志搜索 开始的时候做运维工作遇到很多问题,on call待命,甚至在凌晨2点被叫醒;这种工作状态让我感到很厌烦。往往,在日志中可以发现问题所在,但是需要花费好久时间才能找到。 于是,我寻找有哪些开源软件可以做基本的日志搜索,然后发现了Logstash和与之配合使用的Elasticsearch。经过测试,我发现Elasticsearch速度很快并且提供我所需要的功能;然后我就开始编写一套非常简单的interface作为补充展示,大概花费了我几天的时间。这就是第一版Kibana的诞生过程,当时是采用PHP编写的,功能是可以展示日志并配有搜索入口,目的是把这个工具可以交付给我的boss,使得他无需我的参与便可以使用这个interface。需要提一句的是,Elasticsearch 对于Web编程很友好,并且日志数据按照日期排列。 在全职投入 Kibana 为 Elastic 公司工作之前,我一直从事运维工作并且我非常喜欢运维工作。因为这段实践经验帮助我体会到了运维人的问题和困难,这让我知道了需要创造一个什么样的工具。我依然认为运维是一个非常有挑战的工作,让所有的东西都正常地运转起来。 编程吧,动手创造自己的工具 的确,我是运维人员,但是我还自己动手开发工具。这在美国越来越普遍了,因为大家意识到,如果你可以编写代码,你的工作会轻松很多,代码可以代替你进行重复工作。通过代码实现自动化是正确的途径,没有人愿意不停地做同样的事情。 编写Kibana是因为我当时没有发现一个适合我的工具,于是我决定自己动手。第一版Kibana是用PHP写的,第二版是用Ruby,第三版之后是用JavaScript。我不害怕学习心得语言,因为学语言并不难,Ruby或者JavaScript的语言掌握仅仅是简单的熟悉语法,并没有接触到实际项目中复杂的事情。而重写Kibana的工作也并不复杂,因为其实Elasticsearch做的工作最重。 “哪种编程语言最好?”说实话,其实这个问题的讨论对我而言并不重要。重要的是,为你的工作选择恰当的语言。PHP在我心中仍然有一席之地,我认为它依然是一个好的语言,可能很多人有异议,但是我认为它简单易上手、稳定变化慢,相关工具也很容易上手。Node.js相对来说,比较复杂;Node社区也意识到这个问题,并且正在改进。比如说,当时我选择了Ruby重写Kibana,是因为Logstash是用JRuby写的,Elasticsearch 使用Java写的(JRuby可以理解为Ruby可以跑在JVM里面)。当时想把 Kibana 的 Ruby那个版本是因为想放到Logstash中,但是没有成功。所以,接下来我们研发了Kibana 3 。 在开发Kibana之前,我用过Graphite,但是为什么依然不满足呢?首先,Graphite很棒,所有关于数字、指标、时间序列的事情。但是那个时候,我需要的是一个可以做日志搜索的东西,需要有一个Dashboard可以给出一个图片。我非常希望从日志中获得信息并且把它们和预定的指标绑定在一起,实际上这些幕后工作都是Elasticsearch做的,并且速度真的快很多。此外需要考虑到扩展性,Graphite对于它适合的大小还算可以,即使超过了极限,更多的数据对应着更多的CPU消耗;但是想扩展很多的话,就很困难了,这一点上Graphite还有很多可以提升的空间,Elastic Stack就可以很轻松地实现。 不过,我依然很喜欢Graphite,我也依然认为这是一个有需求的工具,并且它其实是可以和Elasticsearch、Kibana结合在一起使用的。Architecture dependent的问题困扰了很多人, 比如32bit和64bit两者之间,即便是传输一个文件也不能工作,这是一个非常可怕的事情。Graphite 解决了这个问题,并且界面很美,功能强大 。Kibana也解决了很多相似的问题, 尤其是加上了Elasticsearch的配合,解决了许多我在做运维工作时总是非常想做的工作。 从来没有犹豫过是否开源 12岁的时候就开始接触开源项目了,所以在写Kibana的时候从来没有犹豫过要不要把它开源。 开始的时候我们只是把需求写在纸上,然后一条条做。放到Github之后,看到下载量不断上升我们感到很吃惊。我们没有想到,原来这么多人都面临这同样的问题,没有想到大家对这样的一个开源项目如此需要。开源的目的就是为了能帮助人们,最初我也曾疑惑有可能根本没有人用;然后发现越来越多的人在讨论、使用它。现在Elastic Stack是一个开源整体,把个人的事业career放在服务其他人的开源项目上,并能收获到好的反馈,这让我们感到很开心、很欣慰。 当时的小愿望,现在的大公司 Kibana第一版存在仅仅几周。是因为我开始使用Ruby进行重写,这大概花费了两周的时间。因为Logstash使用Ruby写的(即便当时我并不会Ruby),而我的目的就是让Kibana适配Logstash和Elasticsearch,让三者在一起可以协作获得更多的信息。当时我的想法就是让三个工具可以无缝衔接起来好似一个工具一样,有趣的是,这仅仅是当时我自己的一个愿望,后来Elasticsearch的人联系我问要不要合并在成为同一家公司,我们才发现彼此的看法竟然不谋而合。
elastic-logo-H-full-color.jpg
我现在依然是on call的。在 Elastic 公司,我们有on call轮班制。其实这是与用户交流的机会,这是我们 Elastic 每一个开发者都非常珍视的机会。在对用户支持的过程中,我们可以更清晰地了解用户的需求和真实使用情况;还有一些其他方式,比如会议、沙龙、见面会等,任何可以帮助我们与社区连接的。在我看来,在用户发生问题时,你在他身边并且帮助修复问题:没有比这个更好的工作方式。所以,on call不是折磨,是机会。 Kibana的下一步:数据挖掘、角色报表 1、数据挖掘,精益求精 最开始在做日志分析的那个时候,坦率地讲,我并没有关联到了Data mining。因为那时只是想先把问题弄清楚。但是在把所有的问题都解决完(这些并不难,只是花时间而已),实现了最初我们想要的Kibana之后,运维的工作量就大大减少了。 一切都运转得很顺利之后,我们开始思考怎样能把事情做得越来越好,尽量少地产生问题。我们可以获得数据,并且发现了一些问题发生的规律:问题的发生节点,比如说往往半夜三点、发布新版本之后;问题的发生频率,哪些问题非常热门,我们需要把对应的工作放在CDN上;问题的优化处理,发生问题之后如何最快地回滚。机器学习很强有力,而且对于运维人员而言,越少的红色提示越幸福。但是目前我的考虑是,能做到提前预警就已经很棒了。 基于这些思考,我们认为需要开始进行数据挖掘的工作了,这样才把事情做得越来越好,才能更大程度地帮助公司用户。在五六年前,很少会有人想到运维团队可以给出商业业务的指导意见,但是现在这开始越来越普遍。 2、接下来,Dashboard不会只有public一种 此前Kibana的Dashboard是完全公开的,没有角色区分。我知道一些其他的工具提供了包边权限区分的功能。最初的时候,只是想保持事情的简单化,Kibana并没有考虑到把Dashboard做成基于角色的,我们考虑更多的是产品易用性、功能,而没有打算触及安全模块。对于我们自己而言,这并不是过去那些年优先级第一的事项。最开始Kibana的主要矛盾是怎样把内容展现出来,打造Elasticsearch的良好用户界面,所以那个时候是界面是对所有用户可见的。而权限的控制我们是在Elasticsearch上面实现的,搜索、索引、集群操作添加是在Elasticsearch,也就是说我们首先Elasticsearch中实现数据层的安全。 接下来,我们考虑怎样把安全性延展到Kibana中,对不同角色进行区分化的搜索展示。(此前,有一个插件可以满足在Kibana中进行 Elasticsearch 用户的控制。代码是开源的,任何公司都可以编写自己的安全模块,并且我们也乐意帮助他们)在决定做一件事情之后我们就希望把一件事情做得非常好,而不是半途而废。 Kibana in Elastic Stack 5.0
Snip20170111_11.png
研发情况 研发出新功能的第一版本通常很快,但是需要不断的测试确保所有运转正常。Elastic Stack5.0 的所有功能大概花费了9个月的研发时间。在决策哪些功能需要研发时,我们有几周的考虑时间,还会参考社区中的反馈。然后我们还会给开发者一些自主空间,我们试着避免总是给某些人下发某些任务。我们认为最好主意并不来自与管理层或者经理,而是来自于那些与用户交流频繁的软件工程师,花费很多时间做客户支持的同事。会面通常是远程的,因为我们是个分布式的公司,公司成员分布于30多个国家,一共470多人。Kibana部分的研发、测试和运营人员一共有20多人。 如果有两个程序员所做的事情是一样的话,没有关系这不是重复劳动,反而可以让产品更加优化,两个人可以互相讨论加速功能研发;否则的话产品会被程序员打上过强的个人烙印,最终让产品交付给客户的是整个团队。 会一直并且只是配合Elasticsearch 是的,我们没有其他 datasource 的计划,因为我们大部分的使用case是要有时间序列的。 最开始融合在一起的是 Elasticsearch 和 Logstash,然后 Kibana 参与进来。在这个融合的过程中,遇到任何冲突或者改变,我们的评判标准都是怎样对用户而言更友好。举例说明,安全问题最佳的解决是在数据层,搜索非常占用内存,使用ES可以做很复杂的事情,在旧版本的 Kibana 中,可以使用 Elasticsearch 的 API,但是这拖缓了速度,并且用户可能会做一些危险的事情。在 Kibana 和 Elasticsearch 融合之后,我再也没有那样做了,对于一些重的内存需求工作不会在UI层(Kibana)而是会放到数据层(ES),用最少的内存,让尽可能多的计算脱离 JVM heap ,放入socket breaker,让我们管理更简洁干净并做到在UI可追踪。 Kibana的美学 Kibana最初的设计师只是我一个人,现在当然我们有了自己的很优秀的设计师,这是很被看重的部分,没有外包出去。因为我们需要和设计团队频繁地交流,不断地给予反馈,和工程团队。这是我们公司文化的一个重要部分。 你想一想这是运维人员需要终日面对的工具,没有人愿意一直看着丑的东西;此外,也希望Kibana可以让运维人员的boss们感到惊艳,我们希望可以帮助使用者产生非常美的工作。 写在最后 在采访结束时,InfoQ问Rashid是否可以给广大读者一些建议,Rashid想了想说:

如果你有一个想法,把它code出来,build起来。不要等其他人的开源代码,有可能你会等到,但是有可能你永远等不到。在你写出来之后,你没准会收获惊喜。

 
1.png
 

kibana搜索10000条输入限制如何解除

回复

Kibanaonionwithhoney 发起了问题 • 1 人关注 • 0 个回复 • 4966 次浏览 • 2023-01-05 15:02 • 来自相关话题

怎么查看 Kibana dashboard中最终执行的query语句

回复

Kibanasdx 回复了问题 • 2 人关注 • 1 个回复 • 989 次浏览 • 2022-07-08 11:19 • 来自相关话题

7.14 Kibana 默认时间排序

回复

KibanaTsukiand 回复了问题 • 1 人关注 • 1 个回复 • 2670 次浏览 • 2021-11-20 16:58 • 来自相关话题

kibana7.14配置索引模式权限后页面依旧可以看到

回复

Kibanacaster_QL 回复了问题 • 1 人关注 • 1 个回复 • 1504 次浏览 • 2021-09-30 18:26 • 来自相关话题

kibana 7.14 本地开发模式提示crash

回复

Kibanatongchuan1992 回复了问题 • 2 人关注 • 1 个回复 • 1639 次浏览 • 2021-09-07 10:46 • 来自相关话题

堆栈监测 监测beats bug有人遇到过吗

回复

Kibanatongchuan1992 回复了问题 • 2 人关注 • 1 个回复 • 1542 次浏览 • 2021-07-08 08:47 • 来自相关话题

kibana如何才能使用nested的字段作为可视化的条件?

回复

Kibanaliuxg 回复了问题 • 2 人关注 • 1 个回复 • 1524 次浏览 • 2021-07-02 10:01 • 来自相关话题

kibana如何做出只查询出自己创建的索引的?

回复

Elasticsearchstartjava 发起了问题 • 1 人关注 • 0 个回复 • 1556 次浏览 • 2021-07-01 16:04 • 来自相关话题

新人求教,新安装的kibana,启动成功后访问不了

回复

KibanaSanri99 回复了问题 • 3 人关注 • 2 个回复 • 16376 次浏览 • 2021-05-08 16:15 • 来自相关话题

kibana中dashboard怎么复制使用

回复

KibanaReilee 回复了问题 • 3 人关注 • 1 个回复 • 2440 次浏览 • 2021-01-26 06:28 • 来自相关话题

kibana获取历史查询语句

回复

Kibanasun_q 发起了问题 • 1 人关注 • 0 个回复 • 2549 次浏览 • 2020-12-23 14:54 • 来自相关话题

Kibana支持按树层级下钻吗?

回复

Kibanaruifeng 发起了问题 • 2 人关注 • 0 个回复 • 1549 次浏览 • 2020-12-21 11:05 • 来自相关话题

在kibana中使用markdown动态展示多个指标的比率

回复

Kibanacclibra 发起了问题 • 1 人关注 • 0 个回复 • 2083 次浏览 • 2020-11-19 11:14 • 来自相关话题

kibana想要用ldap登入认证是不是就要买x-pack?

回复

KibanaGaolin Cheng 回复了问题 • 3 人关注 • 4 个回复 • 4993 次浏览 • 2020-11-06 17:04 • 来自相关话题

ES7.3版本设置kibana用户名和密码,无法登陆,求解!

回复

KibanaFlorence 回复了问题 • 5 人关注 • 5 个回复 • 9661 次浏览 • 2020-09-23 08:56 • 来自相关话题

Web Scraper + Elasticsearch + Kibana + SearchKit 打造的豆瓣电影top250 搜索演示系统

Elasticsearch 发表了文章 • 0 个评论 • 4517 次浏览 • 2023-04-09 10:56 • 来自相关话题

Web Scraper + Elasticsearch + Kibana + SearchKit 打造的豆瓣电影top250 搜索演示系统

作者:小森同学

声明:电影数据来源于“豆瓣电影”,如有侵权,请联系删除

1.png

2.png

Web Scraper

{
    "_id": "top250",
    "startUrl": ["https://movie.douban.com/top250?start=[0-225:25]&filter="],
    "selectors": [{
        "id": "container",
        "multiple": true,
        "parentSelectors": ["_root"],
        "selector": ".grid_view li",
        "type": "SelectorElement"
    }, {
        "id": "name",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "span.title:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "number",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "em",
        "type": "SelectorText"
    }, {
        "id": "score",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "span.rating_num",
        "type": "SelectorText"
    }, {
        "id": "review",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "",
        "selector": "span.inq",
        "type": "SelectorText"
    }, {
        "id": "year",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "\\d{4}",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "tour_guide",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "^导演: \\S*",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "type",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "[^/]+$",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "area",
        "multiple": false,
        "parentSelectors": ["container"],
        "regex": "[^\\/]+(?=\\/[^\\/]*$)",
        "selector": "p:nth-of-type(1)",
        "type": "SelectorText"
    }, {
        "id": "detail_link",
        "multiple": false,
        "parentSelectors": ["container"],
        "selector": ".hd a",
        "type": "SelectorLink"
    }, {
        "id": "director",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "",
        "selector": "span:nth-of-type(1) .attrs a",
        "type": "SelectorText"
    }, {
        "id": "screenwriter",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=编剧: )[\\u4e00-\\u9fa5A-Za-z0-9/()\\·\\s]+(?=主演)",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "film_length",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "\\d+",
        "selector": "span[property='v:runtime']",
        "type": "SelectorText"
    }, {
        "id": "IMDb",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=[IMDb:\\s+])\\S*(?=\\d*$)",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "language",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=语言: )\\S+",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "alias",
        "multiple": false,
        "parentSelectors": ["detail_link"],
        "regex": "(?<=又名: )[\\u4e00-\\u9fa5A-Za-z0-9/()\\s]+(?=IMDb)",
        "selector": "div#info",
        "type": "SelectorText"
    }, {
        "id": "pic",
        "multiple": false,
        "parentSelectors": ["container"],
        "selector": "img",
        "type": "SelectorImage"
    }]
}

elasticsearch

{
    "mappings": {
      "properties": {
        "IMDb": {
          "type": "keyword",
          "copy_to": [
            "all"
          ]
        },
        "alias": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "all": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "area": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "director": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "film_length": {
          "type": "long"
        },
        "id": {
          "type": "keyword"
        },
        "language": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "link": {
          "type": "keyword"
        },
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "number": {
          "type": "long"
        },
        "photo": {
          "type": "keyword"
        },
        "review": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "score": {
          "type": "double"
        },
        "screenwriter": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "type": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          },
          "copy_to": [
            "all"
          ],
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_smart"
        },
        "year": {
          "type": "long"
        }
      }
    }
  }

kibana

需要使用pipeline对索引字段进行处理,如对type 通过空格进行分割为数组等,可以参照官方文档或其他博客。

制作仪表板省略, 请自行搜索

SearchKit

参考 https://github.com/searchkit/searchkit-starter-app

在 Kibana 里统一访问来自不同集群的索引

资料分享medcl 发表了文章 • 0 个评论 • 1370 次浏览 • 2022-04-21 15:29 • 来自相关话题

在 Kibana 里统一访问来自不同集群的索引

现在有这么一个需求,客户根据需要将数据按照业务维度划分,将索引分别存放在了不同的三个集群, 将一个大集群拆分成多个小集群有很多好处,比如降低了耦合,带来了集群可用性和稳定性方面的好处,也避免了单个业务的热点访问造成其他业务的影响, 尽管拆分集群是很常见的玩法,但是管理起来不是那么方便了,尤其是在查询的时候,可能要分别访问三套集群各自的 API,甚至要切换三套不同的 Kibana 来访问集群的数据, 那么有没有办法将他们无缝的联合在一起呢?

极限网关!

答案自然是有的,通过将 Kibana 访问 Elasticsearch 的地址切换为极限网关的地址,我们可以将请求按照索引来进行智能的路由, 也就是当访问不同的业务索引时会智能的路由到不同的集群,如下图:

WechatIMG27.png

上图,我们分别有 3 个不同的索引:

  • apm-*
  • erp-*
  • mall-*

分别对应不同的三套 Elasticsearch 集群:

  • ES1-APM
  • ES2-ERP
  • ES3-MALL

接下来我们来看如何在极限网关里面进行相应的配置来满足这个业务需求。

配置集群信息

首先配置 3 个集群的连接信息。

elasticsearch:
  - name: es1-apm
    enabled: true
    endpoints:
     - http://192.168.3.188:9206
  - name: es2-erp
    enabled: true
    endpoints:
     - http://192.168.3.188:9207
  - name: es3-mall
    enabled: true
    endpoints:
     - http://192.168.3.188:9208

配置服务 Flow

然后,我们定义 3 个 Flow,分别对应用来访问 3 个不同的 Elasticsearch 集群,如下:

flow:
  - name: es1-flow
    filter:
      - elasticsearch:
          elasticsearch: es1-apm
  - name: es2-flow
    filter:
      - elasticsearch:
          elasticsearch: es2-erp
  - name: es3-flow
    filter:
      - elasticsearch:
          elasticsearch: es3-mall

然后再定义一个 flow 用来进行路径的判断和转发,如下:

  - name: default-flow
    filter:
      - switch:
          remove_prefix: false
          path_rules:
            - prefix: apm-
              flow: es1-flow
            - prefix: erp-
              flow: es2-flow
            - prefix: mall-
              flow: es3-flow
      - flow: #default flow
          flows:
            - es1-flow

根据请求路径里面的索引前缀来匹配不同的索引,并转发到不同的 Flow。

配置路由信息

接下来,我们定义路由信息,具体配置如下:

router:
  - name: my_router
    default_flow: default-flow

指向上面定义的默认 flow 来统一请求的处理。

定义服务及关联路由

最后,我们定义一个监听为 8000 端口的服务,用来提供给 Kibana 来进行统一的入口访问,如下:

entry:
  - name: es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: 0.0.0.0:8000

完整配置

最后的完整配置如下:

path.data: data
path.logs: log

entry:
  - name: es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: 0.0.0.0:8000

flow:
  - name: default-flow
    filter:
      - switch:
          remove_prefix: false
          path_rules:
            - prefix: apm-
              flow: es1-flow
            - prefix: erp-
              flow: es2-flow
            - prefix: mall-
              flow: es3-flow
      - flow: #default flow
          flows:
            - es1-flow
  - name: es1-flow
    filter:
      - elasticsearch:
          elasticsearch: es1-apm
  - name: es2-flow
    filter:
      - elasticsearch:
          elasticsearch: es2-erp
  - name: es3-flow
    filter:
      - elasticsearch:
          elasticsearch: es3-mall

router:
  - name: my_router
    default_flow: default-flow

elasticsearch:
  - name: es1-apm
    enabled: true
    endpoints:
     - http://192.168.3.188:9206
  - name: es2-erp
    enabled: true
    endpoints:
     - http://192.168.3.188:9207
  - name: es3-mall
    enabled: true
    endpoints:
     - http://192.168.3.188:9208

启动网关

直接启动网关,如下:

➜  gateway git:(master) ✗ ./bin/gateway -config sample-configs/elasticsearch-route-by-index.yml 

   ___   _   _____  __  __    __  _       
  / _ \ /_\ /__   \/__\/ / /\ \ \/_\ /\_/\
 / /_\///_\\  / /\/_\  \ \/  \/ //_\\\_ _/
/ /_\\/  _  \/ / //__   \  /\  /  _  \/ \ 
\____/\_/ \_/\/  \__/    \/  \/\_/ \_/\_/ 

[GATEWAY] A light-weight, powerful and high-performance elasticsearch gateway.
[GATEWAY] 1.0.0_SNAPSHOT, 2022-04-20 08:23:56, 2023-12-31 10:10:10, 51650a5c3d6aaa436f3c8a8828ea74894c3524b9
[04-21 13:41:21] [INF] [app.go:174] initializing gateway.
[04-21 13:41:21] [INF] [app.go:175] using config: /Users/medcl/go/src/infini.sh/gateway/sample-configs/elasticsearch-route-by-index.yml.
[04-21 13:41:21] [INF] [instance.go:72] workspace: /Users/medcl/go/src/infini.sh/gateway/data/gateway/nodes/c9bpg0ai4h931o4ngs3g
[04-21 13:41:21] [INF] [app.go:283] gateway is up and running now.
[04-21 13:41:21] [INF] [api.go:262] api listen at: http://0.0.0.0:2900
[04-21 13:41:21] [INF] [reverseproxy.go:255] elasticsearch [es1-apm] hosts: [] => [192.168.3.188:9206]
[04-21 13:41:21] [INF] [reverseproxy.go:255] elasticsearch [es2-erp] hosts: [] => [192.168.3.188:9207]
[04-21 13:41:21] [INF] [reverseproxy.go:255] elasticsearch [es3-mall] hosts: [] => [192.168.3.188:9208]
[04-21 13:41:21] [INF] [actions.go:349] elasticsearch [es2-erp] is available
[04-21 13:41:21] [INF] [actions.go:349] elasticsearch [es1-apm] is available
[04-21 13:41:21] [INF] [entry.go:312] entry [es_entry] listen at: http://0.0.0.0:8000
[04-21 13:41:21] [INF] [module.go:116] all modules are started
[04-21 13:41:21] [INF] [actions.go:349] elasticsearch [es3-mall] is available
[04-21 13:41:55] [INF] [reverseproxy.go:255] elasticsearch [es1-apm] hosts: [] => [192.168.3.188:9206]

网关启动成功之后,就可以通过网关的 IP+8000 端口来访问目标 Elasticsearch 集群了。

测试访问

首先通过 API 来访问测试一下,如下:

➜  ~ curl http://localhost:8000/apm-2022/_search -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /apm-2022/_search HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 21 Apr 2022 05:45:44 GMT
< content-type: application/json; charset=UTF-8
< Content-Length: 162
< X-elastic-product: Elasticsearch
< X-Backend-Cluster: es1-apm
< X-Backend-Server: 192.168.3.188:9206
< X-Filters: filters->elasticsearch
< 
* Connection #0 to host localhost left intact
{"took":142,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":0,"relation":"eq"},"max_score":null,"hits":[]}}%  

可以看到 apm-2022 指向了后端的 es1-apm 集群。

继续测试,erp 索引的访问,如下:

➜  ~ curl http://localhost:8000/erp-2022/_search -v 
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /erp-2022/_search HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 21 Apr 2022 06:24:46 GMT
< content-type: application/json; charset=UTF-8
< Content-Length: 161
< X-Backend-Cluster: es2-erp
< X-Backend-Server: 192.168.3.188:9207
< X-Filters: filters->switch->filters->elasticsearch->skipped
< 
* Connection #0 to host localhost left intact
{"took":12,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":0,"relation":"eq"},"max_score":null,"hits":[]}}%

继续测试,mall 索引的访问,如下:

➜  ~ curl http://localhost:8000/mall-2022/_search -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /mall-2022/_search HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 21 Apr 2022 06:25:08 GMT
< content-type: application/json; charset=UTF-8
< Content-Length: 134
< X-Backend-Cluster: es3-mall
< X-Backend-Server: 192.168.3.188:9208
< X-Filters: filters->switch->filters->elasticsearch->skipped
< 
* Connection #0 to host localhost left intact
{"took":8,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}% 

完美转发。

修改 Kibana 配置

修改 Kibana 的配置文件: kibana.yml,替换 Elasticsearch 的地址为网关地址(http://192.168.3.200:8000),如下:

elasticsearch.hosts: ["http://192.168.3.200:8000"]

重启 Kibana 让配置生效。

效果如下

kibana-clusers-op.jpg

可以看到,在一个 Kibana 的开发者工具里面,我们已经可以像操作一个集群一样来同时读写实际上来自三个不同集群的索引数据了。

展望

通过极限网关,我们还可以非常灵活的进行在线请求的流量编辑,动态组合不同集群的操作。

使用极限网关来代理 Kibana

Kibanamedcl 发表了文章 • 0 个评论 • 1567 次浏览 • 2022-02-15 20:29 • 来自相关话题

我的 Kibana 版本太旧了,我的 Kibana 没有密码保护,我的 Kibana 没有权限控制。烦不胜烦。  来来来,几个简单步骤告别不舒服的这几个问题,如下: 下载最新的 530 版本:http://release.elasticsearch.cn/gateway/snapshot/   找到配置:
entry:
  - name: my_es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: 0.0.0.0:8000
      skip_occupied_port: true
    tls:
      enabled: true

flow:
  - name: default_flow
    filter:
      - basic_auth:
          valid_users:
            medcl: passwd
      - http:
          schema: "http" #https or http
          host: "192.168.3.98:5601"
router:
  - name: my_router
    default_flow: default_flow
修改里面的 ip 为你实际的 Kibana IP 地址,如需多个,使用 hosts 参数,详见文档手册:   https://极限网关.com/docs/references/filters/http/   启动网关,因为自动开启了 https,访问网关的服务地址:https://localhost:8000,如下:
Jietu20220215-202309.jpg
  输入配置的用户名密码,即可。  
Jietu20220215-202414.jpg

Elastic日报 第1307期 (2021-01-12)

Elastic日报kin122 发表了文章 • 0 个评论 • 935 次浏览 • 2022-01-12 10:13 • 来自相关话题

1. Elasticsearch:如何将浮点值存储到整型字段中 https://elasticstack.blog.csdn ... 59801 2. Kibana使用:Search Bar https://cloud.tencent.com/deve ... 77628 3. Logstash:Pipeline-to-Pipeline 通信 - 一个实例处理多种日志 https://blog.csdn.net/UbuntuTo ... 29091 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup
1. Elasticsearch:如何将浮点值存储到整型字段中 https://elasticstack.blog.csdn ... 59801 2. Kibana使用:Search Bar https://cloud.tencent.com/deve ... 77628 3. Logstash:Pipeline-to-Pipeline 通信 - 一个实例处理多种日志 https://blog.csdn.net/UbuntuTo ... 29091 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup

Elastic日报 第1245期 (2021-11-10)

Elastic日报kin122 发表了文章 • 0 个评论 • 896 次浏览 • 2021-11-10 09:41 • 来自相关话题

1. Lucene源码解析——StoredField存储方式 https://zhuanlan.zhihu.com/p/384486147 2.如何在 Kibana 的 Discover 界面中让显示图片字段 https://www.bilibili.com/video/BV14P4y1L7XL/ https://elasticstack.blog.csdn ... 19074 3. 几种常见的查询性能问题及优化方式--字节:张超 https://mp.weixin.qq.com/s/w7hEn2JE9ZXUBh3kZ0uOGg 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup
1. Lucene源码解析——StoredField存储方式 https://zhuanlan.zhihu.com/p/384486147 2.如何在 Kibana 的 Discover 界面中让显示图片字段 https://www.bilibili.com/video/BV14P4y1L7XL/ https://elasticstack.blog.csdn ... 19074 3. 几种常见的查询性能问题及优化方式--字节:张超 https://mp.weixin.qq.com/s/w7hEn2JE9ZXUBh3kZ0uOGg 编辑:kin122 归档:https://ela.st/cn-daily-all 订阅:https://ela.st/cn-daily-sub 沙龙:https://ela.st/cn-meetup

如何修改kibana的默认主页

Kibana点火三周 发表了文章 • 3 个评论 • 7558 次浏览 • 2019-01-18 15:34 • 来自相关话题

在6.0版本以前,登录kibana之后,默认会路由到app/kibana下的discover应用。 在6.3版本以后,新增了一个home路径/app/kibana#/home?_g=h@44136fa,访问根路径\会直接跳到以上路径。

希望在kibana上做更多定制化开发的同学,或许会有需求在登录kibana之后能够跳转到自己的页面。

要完成以上需求,只需要在kibana的配置文件里面增加一行:

server.defaultRoute: /app/system_portal

以上例子,我让kibana登录之后直接跳到我自己的app插件system_portal

配置默认路由的文件, src/server/http/get_default_route.js

import _ from 'lodash';

export default _.once(function (kbnServer) {
  const {
    config
  } = kbnServer;
  // 根目录basePath加上defaultRoute
  return `${config.get('server.basePath')}${config.get('server.defaultRoute')}`;
});

默认路由就是定义在server.defaultRoute中,默认值是app/kibana,可查看src/server/config/schema.js:

import Joi from 'joi';
import { constants as cryptoConstants } from 'crypto';
import os from 'os';

import { fromRoot } from '../../utils';
import { getData } from '../path';

export default async () => Joi.object({
  pkg: Joi.object({
    version: Joi.string().default(Joi.ref('$version')),
    branch: Joi.string().default(Joi.ref('$branch')),
    buildNum: Joi.number().default(Joi.ref('$buildNum')),
    buildSha: Joi.string().default(Joi.ref('$buildSha')),
  }).default(),

  env: Joi.object({
    name: Joi.string().default(Joi.ref('$env')),
    dev: Joi.boolean().default(Joi.ref('$dev')),
    prod: Joi.boolean().default(Joi.ref('$prod'))
  }).default(),

  dev: Joi.object({
    basePathProxyTarget: Joi.number().default(5603),
  }).default(),

  pid: Joi.object({
    file: Joi.string(),
    exclusive: Joi.boolean().default(false)
  }).default(),

  cpu: Joi.object({
    cgroup: Joi.object({
      path: Joi.object({
        override: Joi.string().default()
      })
    })
  }),

  cpuacct: Joi.object({
    cgroup: Joi.object({
      path: Joi.object({
        override: Joi.string().default()
      })
    })
  }),

  server: Joi.object({
    uuid: Joi.string().guid().default(),
    name: Joi.string().default(os.hostname()),
    host: Joi.string().hostname().default('localhost'),
    port: Joi.number().default(5601),
    maxPayloadBytes: Joi.number().default(1048576),
    autoListen: Joi.boolean().default(true),
    defaultRoute: Joi.string().default('/app/kibana').regex(/^\//, `start with a slash`),
    basePath: Joi.string().default('').allow('').regex(/(^$|^\/.*[^\/]$)/, `start with a slash, don't end with one`),
    rewriteBasePath: Joi.boolean().when('basePath', {
      is: '',
      then: Joi.default(false).valid(false),
      otherwise: Joi.default(false),
    }),
    customResponseHeaders: Joi.object().unknown(true).default({}),
    ssl: Joi.object({
      enabled: Joi.boolean().default(false),
      redirectHttpFromPort: Joi.number(),
      certificate: Joi.string().when('enabled', {
        is: true,
        then: Joi.required(),
      }),
      key: Joi.string().when('enabled', {
        is: true,
        then: Joi.required()
      }),
      keyPassphrase: Joi.string(),
      certificateAuthorities: Joi.array().single().items(Joi.string()).default(),
      supportedProtocols: Joi.array().items(Joi.string().valid('TLSv1', 'TLSv1.1', 'TLSv1.2')),
      cipherSuites: Joi.array().items(Joi.string()).default(cryptoConstants.defaultCoreCipherList.split(':'))
    }).default(),
    cors: Joi.when('$dev', {
      is: true,
      then: Joi.object().default({
        origin: ['*://localhost:9876'] // karma test server
      }),
      otherwise: Joi.boolean().default(false)
    }),
    xsrf: Joi.object({
      disableProtection: Joi.boolean().default(false),
      whitelist: Joi.array().items(
        Joi.string().regex(/^\//, 'start with a slash')
      ).default(),
      token: Joi.string().optional().notes('Deprecated')
    }).default(),
  }).default(),

  logging: Joi.object().keys({
    silent: Joi.boolean().default(false),

    quiet: Joi.boolean()
      .when('silent', {
        is: true,
        then: Joi.default(true).valid(true),
        otherwise: Joi.default(false)
      }),

    verbose: Joi.boolean()
      .when('quiet', {
        is: true,
        then: Joi.valid(false).default(false),
        otherwise: Joi.default(false)
      }),

    events: Joi.any().default({}),
    dest: Joi.string().default('stdout'),
    filter: Joi.any().default({}),
    json: Joi.boolean()
      .when('dest', {
        is: 'stdout',
        then: Joi.default(!process.stdout.isTTY),
        otherwise: Joi.default(true)
      }),

    useUTC: Joi.boolean().default(true),
  })
    .default(),

  ops: Joi.object({
    interval: Joi.number().default(5000),
  }).default(),

  plugins: Joi.object({
    paths: Joi.array().items(Joi.string()).default(),
    scanDirs: Joi.array().items(Joi.string()).default(),
    initialize: Joi.boolean().default(true)
  }).default(),

  path: Joi.object({
    data: Joi.string().default(getData())
  }).default(),

  optimize: Joi.object({
    enabled: Joi.boolean().default(true),
    bundleFilter: Joi.string().default('!tests'),
    bundleDir: Joi.string().default(fromRoot('optimize/bundles')),
    viewCaching: Joi.boolean().default(Joi.ref('$prod')),
    watch: Joi.boolean().default(false),
    watchPort: Joi.number().default(5602),
    watchHost: Joi.string().hostname().default('localhost'),
    watchPrebuild: Joi.boolean().default(false),
    watchProxyTimeout: Joi.number().default(5 * 60000),
    useBundleCache: Joi.boolean().default(Joi.ref('$prod')),
    unsafeCache: Joi.when('$prod', {
      is: true,
      then: Joi.boolean().valid(false),
      otherwise: Joi
        .alternatives()
        .try(
          Joi.boolean(),
          Joi.string().regex(/^\/.+\/$/)
        )
        .default(true),
    }),
    sourceMaps: Joi.when('$prod', {
      is: true,
      then: Joi.boolean().valid(false),
      otherwise: Joi
        .alternatives()
        .try(
          Joi.string().required(),
          Joi.boolean()
        )
        .default('#cheap-source-map'),
    }),
    profile: Joi.boolean().default(false)
  }).default(),
  status: Joi.object({
    allowAnonymous: Joi.boolean().default(false)
  }).default(),
  map: Joi.object({
    manifestServiceUrl: Joi.string().default(' https://catalogue.maps.elastic.co/v2/manifest'),
    emsLandingPageUrl: Joi.string().default('https://maps.elastic.co/v2'),
    includeElasticMapsService: Joi.boolean().default(true)
  }).default(),
  tilemap: Joi.object({
    url: Joi.string(),
    options: Joi.object({
      attribution: Joi.string(),
      minZoom: Joi.number().min(0, 'Must be 0 or higher').default(0),
      maxZoom: Joi.number().default(10),
      tileSize: Joi.number(),
      subdomains: Joi.array().items(Joi.string()).single(),
      errorTileUrl: Joi.string().uri(),
      tms: Joi.boolean(),
      reuseTiles: Joi.boolean(),
      bounds: Joi.array().items(Joi.array().items(Joi.number()).min(2).required()).min(2)
    }).default()
  }).default(),
  regionmap: Joi.object({
    includeElasticMapsService: Joi.boolean().default(true),
    layers: Joi.array().items(Joi.object({
      url: Joi.string(),
      format: Joi.object({
        type: Joi.string().default('geojson')
      }).default({
        type: 'geojson'
      }),
      meta: Joi.object({
        feature_collection_path: Joi.string().default('data')
      }).default({
        feature_collection_path: 'data'
      }),
      attribution: Joi.string(),
      name: Joi.string(),
      fields: Joi.array().items(Joi.object({
        name: Joi.string(),
        description: Joi.string()
      }))
    }))
  }).default(),

  i18n: Joi.object({
    defaultLocale: Joi.string().default('en'),
  }).default(),

  // This is a configuration node that is specifically handled by the config system
  // in the new platform, and that the current platform doesn't need to handle at all.
  __newPlatform: Joi.any(),

}).default();

为何要通过Kibana展示promethues的数据以及如何去做

Kibana点火三周 发表了文章 • 1 个评论 • 7322 次浏览 • 2018-12-27 10:59 • 来自相关话题

Elastic stack不停的迭代中狂奔。在最新的V6.5版本发布后,我们可以发现,其路线图已经越来越倾向于成为一个全栈的,全链路的,从下至上,从底层硬件资源数据一直到上层用户数据,从资源监控,到性能监控,直至安全审计的智能化运维系统了。这其中解决的一个痛点是:企业中存在各种各样的业务系统,每个系统又存在不同的数据源和存储数据的数据库;同时在运维管理层面上,又各种不同的监控系统(资源监控,性能监控,安全和审计)以及上层的可视化系统。这样,导致运维人员需要面对繁多的系统、入口和数据维度,在处理问题时,需要登录不同的平台,并且无法对数据进行有效的关联分析,因此,是迫切需要一个强大的平台,能够快速便捷的处理这些问题的。 我们可以看到,从不停发布的beats,以及beats里面不停添加的modules:

20181227080511775.png

以及支持的各种数据指标模版:

20181227080702828.png

elastic stack在加速将越来越多的数据需要汇聚到一起,并且提供一个统一的接口进入,这就是Kibana。这里,我不打算深入的比较Kibana和Grafana,简单说一句,就是grafana的主要场景只是dashboard,并不适合将其用作一个将所有数据集中到一起,需要做各种维度的查询,分析,安全检查等功能的portal。所以,这里我们讨论的是Kibana上如何展示其他数据源的数据。

为什么是prometheus而不是beats

在这个人人上云的时代,无论是open stack还是K8S,最流行的资源监控软件我看到的是prometheus,特别是以node_exporter为基础的一系列metric采集工具,为prometheus提供了各种维度的监控数据。而对应的,elastic stack也提供了类似filebeat, metricbeat, packatbeat等一系列工具和对应的数据template。

我没有深入使用过prometheus,但作为一个beats的资深用户,我还是感觉到beats还存在诸多的问题,特别是filebeat上幽灵般存在的内存占用过多的问题,导致大规模在所有的节点上安装beats成为一种风险。并且,最主要的一个点,我觉得是beats采集的数据,是依赖于整个elastic stack进行展示的,而作为云的运维人员,其关心的重点是每个虚拟机,容器的资源监控情况,metric和alart是其重心,而非query,search,security等功能。并且安装一个prometheus,比安装整个elastic stack简便得多,消耗的资源也小的多。所以,普遍的,从主机运维人员的角度,肯定首选安装prometheus的exporter来作资源的监控,而非安装beats。

为什么Kibana上需要集成prometheus的数据

正因为之前所讲的,我们试图使用elastic stack作为一个多维度的统一的数据入口和展示工具,要求我们必须能在Kibana看到硬件资源监控级别的指标,而elastic stack提供的beats等工具,却并不为云运维人员所待见(因为他们更喜欢prometheus,而非elastic stack,原因见以上)。因此,如果我们需要将elastic stack打造为一套全栈的智能运维系统,大多数情况下,prometheus成为必须跨越的一个槛。

将prometheus上的数据转移到elasticsearch

这是我想到的第一个解决方案。可惜logstash上没有prometheus的input plugins。所以,我们还是需要beats。注意,在metricbeat上有一个prometheus的module,号称可以 fetch metric from prometheus exporter,但实际上只是一个乌龙,这个module的并不能从成千上万的云主机或者容器中拉取数据,它能做的只是获取prometheus服务器节点prometheus这个进程的基本数据,然并卵。 这里给大家介绍的是两个社区提供prometheus相关的beats:

但建议大家还是自己写一个beat吧,代码可以参考prombeat。 不过如果你仔细观看prometheus里面的数据,都是num type的,将其转存到elasticsearch绝对不是一个经济的选择:

20181227091438404.png

将grafana集成到kibana中

这是为什么我在一开始提到了grafana,虽然它不适合做portal,但是极其适合做dashboard,而kibana又是如此的开放,随便做个插件,可以轻松的跳转到grafana的dashboard上。而grafana与prometheus又是如此的登对,看看grafana上的各种专业而美丽的prometheus的dashboard吧:

20181227091946394.png

我们要做的是做一个kibana的插件,然后将关键参数传递给grafana,并跳转:

metric.gif

虽然kibana和grafana是两个不同的工具,但并不妨碍我们将它们放在一起工作。而Kibana的开放性和基于插件的独立开发模式,让我们可以更方便的将各种好用的开源工具集成到一起,这里展示的Kibana与grafana和promethues的集成,希望能给到你一些微光。

Kibana优化过程(Optimize)过长或无法结束的解决方案

Kibana点火三周 发表了文章 • 5 个评论 • 4712 次浏览 • 2018-12-12 11:06 • 来自相关话题

使用过Kibana的同学应该都知道,当我们在kibana的配置文件中打开或者关闭功能,或者安装、卸载额外的插件后,重启kibana会触发一个优化的过程(optimize),如下图:

20181212101105813.png

这个过程或长或短,视你电脑的性能而定。这里简单介绍一下该过程所要完成的事情。

Kibana是一个单页Web应用

首先,Kibana是一个单页的web应用。何为单页web应用?即所有的页面的读取都是在浏览器上完成,而与后台服务器无关。与后台服务器的通信只关乎数据,而非页面。所以,应用上所有的UI都被打包在一起,一次性的发送到了浏览器端,而不是通过URL到后台进行获取。所以,我们看到kibana的首页是下面这样的: http://localhost:5601/app/kibana#/ 注意这里的#后,代表#后面的内容会被浏览器提取,不往服务器端进行url的情况,而是在浏览器上进行内部重新渲染。因为所有的页面都是存储在浏览器的,所有在初次访问的时候,会加载大量的代码到浏览器端,这些代码都是被压缩过的bundle文件:

20181212101741186.png

而optimize的过程,就是把这些原本可读性的源代码压缩为bundle.js的过程。因此,每当你对Kibana进行裁剪之后重启,因为前端的部分是完全由浏览器负责的,所有bundle文件需要重新生成后再发给浏览器,所以会触发optimize的过程。

Kibana在6.2.0版本之后,常规版本已经默认自带了xpack(当然,你还是可以直接下载不带xpack的开源社区版),导致Kibana的size已经到了200M左右,而且越往后的版本,功能越多,代码量越大,每次optimize的过程都会耗费更多的时间。一般来说,我们会将Kibana部署在单独的机器上,因为这仅仅是一个web后端,通常我们不会分配比较优质的资源,(2C4G都算浪费的了),这种情况下面,每次我们裁剪后重启Kibana都会耗费半个小时~1个小时的时间,更有甚者直接hang住,查看系统日志才知道OOM了。

Nodejs的内存机制

Kibana是用Nodejs编写的程序,在一般的后端语言中,基本的内存使用上基本没有什么限制,但是在nodeJs中却只能使用部分内存。在64位系统下位约为1.4G,在32位系统下约为0.7G,造成这个问题的主要原因是因为nodeJs基于V8构建,V8使用自己的方式来管理和分配内存,这一套管理方式在浏览器端使用绰绰有余,但是在nodeJs中这却限制了开发者,在应用中如果碰到了这个限制,就会造成进程退出。

Nodejs内存机制对Kibana优化的影响

因为Kibana的代码体量越来越大,将所有的代码加载到内存之后,再解析语法树,进行bundle的转换所耗费的内存已经接近1.4G的限制了,当你安装更多插件,比如sentinl的时候,系统往往已经无法为继,导致Kibana无法启动

解决方案

这种情况下,我们需要在Kibana启动的时候,指定NodeJs使用更多的内存。这个可以通过设置Node的环境变量办到。

NODE_OPTIONS="--max-old-space-size=4096"

当然,我的建议是直接指定在kibana的启动脚本当中,修改/usr/share/kibana/bin/kibana文件为:

#!/bin/sh
SCRIPT=$0

# SCRIPT may be an arbitrarily deep series of symlinks. Loop until we have the concrete path.
while [ -h "$SCRIPT" ] ; do
  ls=$(ls -ld "$SCRIPT")
  # Drop everything prior to ->
  link=$(expr "$ls" : '.*-> \(.*\)$')
  if expr "$link" : '/.*' > /dev/null; then
    SCRIPT="$link"
  else
    SCRIPT=$(dirname "$SCRIPT")/"$link"
  fi
done

DIR="$(dirname "${SCRIPT}")/.."
NODE="${DIR}/node/bin/node"
test -x "$NODE" || NODE=$(which node)
if [ ! -x "$NODE" ]; then
  echo "unable to find usable node.js executable."
  exit 1
fi

NODE_ENV=production exec "${NODE}" $NODE_OPTIONS --max_old_space_size=3072 --no-warnings "${DIR}/src/cli" ${@}

改动在最后一句:NODE_ENV=production exec "${NODE}" $NODE_OPTIONS --max_old_space_size=3072 --no-warnings "${DIR}/src/cli" ${@}

这样,我们可以保证Kibana能顺利的完成optimize的过程

Day 3 - kibana二次开发tips

Adventvvv 发表了文章 • 2 个评论 • 11564 次浏览 • 2018-12-03 09:11 • 来自相关话题

介绍

大家好,我是vvv,这个名字和王者荣耀AG超玩会中的vv没有一毛钱关系,随意取的一个的名字,后来发现貌似不能改了。做过一些数据产品,正是这段时间里开始接触elasticstack,对kibana做过一些二次开发。今天主要想写一些开发过程中的一些tips,希望可以给大家带来一些帮助。

技术栈分析

既然我们的主题是kibana,我们先来看下kibana的主要技术栈。很早开始kibana就开始基于nodejs (hapi框架) + angular(1.x)来进行开发,后来引入了react。kibana本身的代码也经过了多次重构剥离。现在的kibana的代码结构更加清晰

前提

elasticstack发展迅速,现在已经是6.5版本了。我们今天要介绍的是6.x系列的版本,6.x各个版本会有一些细微差异,但大致一样

tips

官方提供kibana下载版本主要是编译后的release版本。如果要基于kibana做二次开发,我们需要去https://github.com/elastic/kibana 上面下载对应的分支。官方有相应的文档去说明如何安装开发环境。我这里有一些tips:

设置国内yarn源

yarn config --global set 'registry https://registry.npm.taobao.org'

一些耗时需要编译的包可以全局安装

yarn global add  node-sass

多环境nodejs版本

不同kibana版本对nodejs版本要求也不一样,为了减少坑我们通常和官方要求的保持一致,如果你的电脑上需要运行多套不同版本的nodejs,那么你可能需要zsh + nvs, 会根据根目录的.node-version版本自动切换当前使用的node版本

IDE推荐

推荐使用vscode,轻量免费,支持很多插件。可以安装个prettier插件,帮助对代码做更好的格式化

debug

如果你用的不是上面我推荐的vscode的话,请忽略这一条。对于使用vscode的同学,首先在vsocde的设置里面开启:

"autoAttach": "on"

然后在vsocode里面打开一个终端,输入:

node --inspect-brk scripts/kibana.js --dev --oss --no-base-path

这个时候vscode就会在启动kibana dev模式的同时attach一个进程进去用于断点调试,对于调试node层非常方便。也能帮助你更好的阅读kibana源码

本地es

我们知道kibana是长在es之上,想要运行kibana怎么少得了es。kibana又一些命令命令可以快速的启动一个es环境:

下载并启动一个当前kibana需要的es版本

yarn es snapshot

灌入一些测试数据(如果需要定制灌入的数据可以看下这个脚本的帮助内容,加-h参数即可)

node scripts/makelogs

编译

kibana代码在release之前是要进行编译的。kibana提供了方便的命令行进行编译,甚至跨平台的交叉编译(生成不同平台的kibana release版本)。但是呢,有几个问题:

  1. kibana在编译的时候需要去aws上下载一些安装包,会导致正常情况下国内访问十分缓慢。(编译命令提供了几个参数可以关掉下载一些如nodejs等,但是还是很慢)
  2. build十分消耗cpu/gpu (mac的iterm2启动会做gpu优化)

解决办法:

  1. 如果你能解决网络问题,而且有性能不错的编译机器。这都不是问题
  2. 如果你对kibana的代码更改都是无侵入的(比如只是写了一些插件扩展),那么你可以去官方下载他们的snapshot版本
  3. 当然,如果你用的kibana版本就是release版本并且你的扩展都是插件,那么你直接用官方的release版本就好了

库的选型

  1. server端: nodejs具有十分丰富的生态,你可以找到很多nodejs相关的库。kibana本身的后端web框架是基于node的hapi的。hapi是一个沃尔玛团队维护的企业级框架,其本身也有很多扩展。当你需要对web框架做一些扩展的时候,可以优先想到去hapi官方看下

  2. ui端: kibana有一套漂亮的ui,其本身也是单独剥离成了一个库,方便引入使用。当然你也可以引入一些其他的前端库来满足你的具体业务需求。推荐尽量使用原生的eui和kibana源码里面的一些封装。这样让你的引入更少,更容易维护。

国际化

国际化是kibana很早就开始立的一个项。这块的进度也是越来越快。新版的kibana里面用@kbn/i18n这个package来统一javascript,html, nodejs做国际化的事情(具体大家可以看下这个package的readme)。国际化这块有一些建议:

  1. 扩展插件的时候养成国际化的习惯
  2. 默认的语系不建议再次设置成一个json文件。因为最新的@kbn/i18n会提供一个默认的文本,用于默认情况下展示。所以我们是没必要重复去维护一个默认的语言翻译json
  3. 假设你的默认语言是英文(和kibana一致),只有当你想要替换kibana默认翻译的时候,才去覆写en.json
  4. 当你对原生kibana有国际化这种需求的时候,建议独立出一个i18n翻译的插件去维护各个语言翻译相关的东西
  5. 目前kibana的国际化还未100%,如果你想知道目前哪些文本内容是支持国际化的。可以尝试如下脚本:
node scripts/extract_default_translations \
 --path src/core_plugins/kibana \
 --output /tmp
  1. 各个插件的之间的翻译文件独立,即使是相同的翻译内容。插件文本内容养成预留国际化的习惯

总结

上面列举了一些我平时的一些经验。时间篇幅有限,未能一一列举。希望可以帮到大家吧。也希望可以和大家多多交流

推荐kibana插件Cleaner 管理ES index TTL

Kibanatruman.p.du 发表了文章 • 0 个评论 • 3669 次浏览 • 2018-09-05 09:23 • 来自相关话题

Cleaner

这是一个管理index TTL 插件,精美UI,高效运维管理elasticsearch index助手

https://github.com/TrumanDu/cleaner

screenshots

config

  1. scheduleTime

    server job schedule period,unit second ,default value is 60 second.

    you can edit it. like: cleaner.scheduleTime: 100

  2. mergePattern

    merge pattern,default value is [^a-z]+$.

    you can edit it. like: cleaner.mergePattern: '[\d]{4}[-|\.|/][\d]{1,2}[-|\.|/][\d]{1,2}'

development

See the kibana contributing guide for instructions setting up your development environment. Once you have completed that, use the following npm tasks.

  • npm start

    Start kibana and have it include this plugin

  • npm start -- --config kibana.yml

    You can pass any argument that you would normally send to bin/kibana by putting them after -- when running npm start

  • npm run build

    Build a distributable archive

  • npm run test:browser

    Run the browser tests in a real web browser

  • npm run test:server

    Run the server tests using mocha

For more information about any of these commands run npm run ${task} -- --help.

Elastic日报 第357期 (2018-08-08)

Elastic日报elk123 发表了文章 • 0 个评论 • 1843 次浏览 • 2018-08-08 23:03 • 来自相关话题

1.kibana插件Logtrail终端式体验。 http://t.cn/RDMgCLh 2.es集群启动流程。 http://t.cn/RDMkAsX 3.es搜索优化。 http://t.cn/RDMkDSv 活动预告 1. Elastic 中国开发者大会 2018 ,开始接受演讲申请和赞助合作 https://conf.elasticsearch.cn/2018/shenzhen.html  编辑:wt 归档:https://elasticsearch.cn/article/747 订阅:https://tinyletter.com/elastic-daily
1.kibana插件Logtrail终端式体验。 http://t.cn/RDMgCLh 2.es集群启动流程。 http://t.cn/RDMkAsX 3.es搜索优化。 http://t.cn/RDMkDSv 活动预告 1. Elastic 中国开发者大会 2018 ,开始接受演讲申请和赞助合作 https://conf.elasticsearch.cn/2018/shenzhen.html  编辑:wt 归档:https://elasticsearch.cn/article/747 订阅:https://tinyletter.com/elastic-daily

Kibana TSVB 注解的使用

Kibanamedcl 发表了文章 • 0 个评论 • 6299 次浏览 • 2018-07-05 09:38 • 来自相关话题

昨天介绍了 Kibana 的里程碑插件,举了个用里程碑来展示数据的注解,写完之后,还是觉得这个例子有点不是太好,

第一,里程碑时间轴还是比较独立,和其他时序图形的时间轴对不上,所以看起来,很不好进行参考,虽然可以首先对时间过滤到出现异常的范围,然后再看里程碑图表的信息,不过,这个实在是体验太差了,用里程碑显示独立的里程信息应该是很好的,如果要做数据的注解,有没有更好的办法呢?

答案是有的,以上一个图形展示的 TSVB 来说,TSVB 本来就自带了数据注解的功能,今天我来给大家介绍一下怎么使用。

  1. 打开 TSVB 的编辑,转到 Annotations 选项卡

  2. 在 Index Patterns 里面设置你要引用的数据,然后设置一个时间字段,此处为 @timestamp

  3. 设置要显示的 Tag 字段,支持多个,用逗号分隔

  4. 设置显示的标签,支持模板, {{字段名}}

最后的效果及设置的截图,如下所示:

Snip20180513_12.png

是不是很简单。

昨天介绍了 Kibana 的里程碑插件,举了个用里程碑来展示数据的注解,写完之后,还是觉得这个例子有点不是太好,

第一,里程碑时间轴还是比较独立,和其他时序图形的时间轴对不上,所以看起来,很不好进行参考,虽然可以首先对时间过滤到出现异常的范围,然后再看里程碑图表的信息,不过,这个实在是体验太差了,用里程碑显示独立的里程信息应该是很好的,如果要做数据的注解,有没有更好的办法呢?

答案是有的,以上一个图形展示的 TSVB 来说,TSVB 本来就自带了数据注解的功能,今天我来给大家介绍一下怎么使用。

  1. 打开 TSVB 的编辑,转到 Annotations 选项卡

  2. 在 Index Patterns 里面设置你要引用的数据,然后设置一个时间字段,此处为 @timestamp

  3. 设置要显示的 Tag 字段,支持多个,用逗号分隔

  4. 设置显示的标签,支持模板, {{字段名}}

最后的效果及设置的截图,如下所示:

Snip20180513_12.png

是不是很简单。

Kibana 里程碑插件的使用

Kibanamedcl 发表了文章 • 7 个评论 • 5753 次浏览 • 2018-07-04 11:07 • 来自相关话题

今天介绍一下 Kibana 的里程碑插件的使用,这个是一个相对还比较新的可视化插件,可以用来对具有时间上下文相关的数据,以里程碑的方式来展现这些数据点在时间轴上的关联性。

这样说可能比较抽象,举个荔枝,你在 Elasticsearch 里面存的是服务器日志信息,然后有一天,老板说网站很慢,帮忙重启一下,(老板听说重启可以解决问题,反正他说他的笔记本重启之后就老快了),这个是一个已知的维护动作,所以你默默的在后台记录了重启的时间和是谁叫你重启的(这里是老板),到了月底的时候,老板让你把这个月的服务器运行数据给他看,然后问你为什么某一个时间服务器请求都为0,你打开 Kibana,指着其中一个时间点说,诺,这里,你让我重启了服务器。

是的,你可以对数据进行注解,用来解释数据和异常,这个是一个很好的场景,另外,还可以关联持续集成工具,每次谁代码提交了,你把这个作为一个事件,存到 es 里面,然后用里程碑可视化显示,那么这个提交造成的服务运行指标的变化,比如性能提升和下降,就会非常直观的关联到这次代码提交,同理,软件版本的发布也是一个里程碑事件,也可以展示并关联起来。然后,在使用的时候,还可以根据时间定位到感兴趣的地方,查看该段时间都发生了哪些自定义的事件和日志,方便分析。做安全方面的分析也可以用来跟踪和做入侵事后复盘的注解。

是不是,很多地方都能使用这个插件呢。

插件地址:https://github.com/walterra/kibana-milestones-vis/

演示截图:

kibana-milestones-vis.png

关于如何使用,其实在该项目的 README 里面已经比较详细了。

1.首先找到对应的 Kibana 插件的版本,如果没有可能需要手动编译插件,有的话,直接找到下载地址。 https://github.com/walterra/kibana-milestones-vis/releases

2.使用 Kibana 的插件安装命令下载安装

➜  kibana-6.2.4-darwin-x86_64 bin/kibana-plugin install https://github.com/walterra/kibana-milestones-vis/releases/download/v6.2.4/kibana-milestones-vis-6.2.4.zip
Found previous install attempt. Deleting...
Attempting to transfer from https://github.com/walterra/kibana-milestones-vis/releases/download/v6.2.4/kibana-milestones-vis-6.2.4.zip
Transferring 1353656 bytes....................
Transfer complete
Retrieving metadata from plugin archive
Extracting plugin archive
Extraction complete
Optimizing and caching browser bundles...

3.启动 Kibana,然后进入 Visualize 面板,应该就能找到这个新的 Milestone 类型的可视化组件了。

Snip20180512_1.png

Snip20180512_2.png

加两个维护日志

Snip20180512_3.png

Snip20180512_4.png

Snip20180512_5.png

和日志关联分析

Snip20180512_6.png

4.还有一个隐藏的秘籍,就是可以支持图片作为标注

Snip20180512_8.png

Snip20180512_10.png

用图片代替文字,是不是更直观,如果你的数据是电影相关的,你可以放一个电影海报替代,如果你的是历史人物相关的,比如,可以换成人物头像,地点等等。

好了,是不是很炫,快去自己试试吧。

开源可视化和快速分析组件.