一、ES集群健康检查
二、ES查询
三、Logstash
四、Logstash配置案例


一、ES集群健康检查

1、集群健康检查

curl IP:PORT/_cluster/health?pretty //查看集群健康状态
curl IP:PORT/_cluster/stats?pretty  //查看系统统计信息
curl IP:PORT/_cluster/pending_tasks?pretty  //查看集群堆积任务;有一些任务只能由主节点去处理,比如创建一个新的 索引或者在集群中移动分片。由于一个集群中只能有一个主节点,所以只有这一节点可以处理集群级别的元数据变动。在 99.9999% 的时间里,这不会有什么问题。元数据变动的队列基本上保持为零。
curl IP:PORT/_cluster/settings?pretty   //查看集群配置
curl -XGET 'http://localhost:9200/_nodes/hot_threads?pretty' //集群节点热线程
curl -XGET '127.0.0.1:9200/_cluster/health?level=indices;pretty=true' //集群各个索引健康状况
curl '192.168.192.222:9200/_nodes/stats?pretty' //监控单个节点的状态信息 https://www.elastic.co/guide/cn/elasticsearch/guide/current/_monitoring_individual_nodes.html#_%E7%B4%A2%E5%BC%95%E9%83%A8%E5%88%86

2、集群慢日志配置

[root@node1 config]# curl -H "Content-Type:application/json" -XPUT '192.168.192.222:9200/_cluster/settings?pretty' -d '{
"transient":
{
   "logger.index_search_slowlog_rolling.level":"trace"  //老版本使用= ,新版本使用: 
}
}'

{
  "acknowledged" : true,
  "persistent" : { },
  "transient" : {
    "logger" : {
      "index_search_slowlog_rolling" : {
        "level" : "trace"
      }
    }
  }
}

index.search.slowlog.level: TRACE
index.search.slowlog.threshold.query.warn: 10s
index.search.slowlog.threshold.query.info: 5s
index.search.slowlog.threshold.query.debug: 2s
index.search.slowlog.threshold.query.trace: 500ms

调整集群日志级别

curl –XPUT IP:PORT/cluster/settings -d'{"transient":{"logger.root":"DEBUG"}}'
curl –XPUT IP:PORT/cluster/settings -d'{"transient":{"logger.root":"INFO"}}’
[root@node1 config]# curl  '192.168.192.222:9200/_cluster/settings?pretty'
{
  "persistent" : { },   //持久化配置
  "transient" : {   //临时配置
    "logger" : {
      "index_search_slowlog_rolling" : {
        "level" : "trace"
      }
    }
  }
}

3、节点

curl -s 'http://192.168.192.222:9200/_cat/health?v'
GET /_cat/nodes?v&h=ip,port,heapPercent,heapMax //节点状态信息
curl -s 'http://127.0.0.1:9200/_cat/master' //查看master
curl -s 'http://127.0.0.1:9200/_cat/nodes?help' 
直接关闭节点下线, 可通过自动容灾恢复副本, 也可以配置分配黑名单, ESDB 会自动把该 IP 的所有分片自动转移到其他节点上。 等转移完成后, 这个空节点就可以毫无影响地下线了。
curl  -H "Content-Type:application/json" 192.168.192.222:9200/_cat/shards?v
curl -XPUT -H "Content-Type:application/json" 192.168.192.222:9200/_cluster/settings -d '{ "transient" :{ "cluster.routing.allocation.exclude._ip" : "192.168.192.222" }}'
curl  '192.168.192.222:9200/_cluster/settings?pretty' //验证是否生效
curl -XPUT -H "Content-Type:application/json" 192.168.192.222:9200/_cluster/settings -d '{ "transient" :{ "cluster.routing.allocation.exclude._ip" : "" }}' //这样就可以继续分配了

4、索引

curl http://192.168.192.222:9200/_cat/shards?v  //查看集群分片状态
curl http://192.168.192.222:9200/logstash-2019.03.24/_stats?pretty  //查看单个索引logstash-2019.03.2状态信息
curl http://192.168.192.222:9200/logstash-2019.03.24/_settings?pretty   //查看索引配置
curl IP:PORT/INDEX_NAME/TYPE_NAME/_Mapping?pretty   //查看索引 Mapping
curl –XPUT IP:PORT/INDEX_NAME/_settings -d '{"index" :{"Refresh_interval" : "10s"}}'    //推送 Refresh 时间周期
curl -s 'http://192.168.192.222:9200/_all/_stats?pretty'   //所有索引统计信息
curl -s  http://192.168.192.222:9200/p2,partment/_stats?prett  //查看2个索引(p2,partment)的使用情况
curl -XDELETE  http://192.168.192.222:9200/logstash-2019.03.24?pretty    //删除索引

查看partment这个indices的设置情况,分成了5个分片,一个副本 5*2=10

[root@node1 config]# curl  '192.168.192.222:9200/partment/_settings?pretty'
{
  "partment" : {
    "settings" : {
      "index" : {
        "creation_date" : "1553314416886",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "5EuKe9CGSaGkxwfq1RMVMQ",
        "version" : {
          "created" : "6060299"
        },
        "provided_name" : "partment"
      }
    }
  }
}

[root@node2 ~]# curl  '192.168.192.222:9200/_cat/shards?v'  //查看分片分布情况,partment共10个分片(5个primary,5个replica)
index    shard prirep state   docs store ip              node
p2       3     p      STARTED    1 5.5kb 192.168.192.224 node3
p2       3     r      STARTED    1 5.5kb 192.168.192.223 node2
p2       2     p      STARTED    1 5.5kb 192.168.192.222 node1
p2       2     r      STARTED    1 5.5kb 192.168.192.224 node3
p2       1     r      STARTED    0  261b 192.168.192.222 node1
p2       1     p      STARTED    0  261b 192.168.192.223 node2
p2       4     r      STARTED    0  261b 192.168.192.224 node3
p2       4     p      STARTED    0  261b 192.168.192.223 node2
p2       0     r      STARTED    0  261b 192.168.192.222 node1
p2       0     p      STARTED    0  261b 192.168.192.224 node3
partment 3     p      STARTED    1 5.5kb 192.168.192.222 node1
partment 3     r      STARTED    1 5.5kb 192.168.192.224 node3
partment 2     r      STARTED    1 5.5kb 192.168.192.222 node1
partment 2     p      STARTED    1 5.5kb 192.168.192.223 node2
partment 1     p      STARTED    0  261b 192.168.192.224 node3
partment 1     r      STARTED    0  261b 192.168.192.223 node2
partment 4     r      STARTED    0  261b 192.168.192.222 node1
partment 4     p      STARTED    0  261b 192.168.192.224 node3
partment 0     p      STARTED    0  261b 192.168.192.222 node1
partment 0     r      STARTED    0  261b 192.168.192.223 node2

5、迁移shard

关闭 Allocate

curl –XPUT IP:PORT/_cluster/settings -d '{"persistent": {"cluster.routing.allocation.enable": "none"}}’

Allocate 限速

curl –XPUT IP:PORT/_cluster/settings -d '{"persistent":{"cluster.routing.allocation.node_concurrent_recoveries":8}}'
curl –XPUT IP:PORT/_cluster/settings -d '{"persistent":{"cluster.routing.allocation.cluster_concurrent_rebalance":8}}'
curl –XPUT IP:PORT/_cluster/settings -d '{"persistent":{"indices.recovery.max_bytes_per_sec":"600mb"}}’

迁移 Shard

curl –XPUT IP:PORT/_cluster/reroute?pretty –d '{"commands":[{"move":{"index":"INDEX","Shard":SHARD_NUM," from_node":"SOURCE_IP","to_node":"DES_IP"}}]}’

打开 Allocate

curl IP:PORT/_cluster/settings –d '{"persistent": {"cluster.routing.allocation.enable": "all"}}

6、其他

curl http://192.168.192.222:9200  //查看版本信息

白屏操作:可以安装Kibana

二、ES查询

1、查询索引API

查询索引:Query API
Query DSL:domain search language //JSON格式的语言

  • 用户实现诸多类型的查询操作:比如,simple term query,phrase,range boolean,fuzzy等。
  • (JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式
    ES的查询操作执行分为两个步骤:
  • 分散阶段:向所有shard分散的node发起请求
  • 合并阶段:合并shard

查询方式:
向ES发起查询请求的方式有两种:

  • 1.通过Restful request API查询。也称为query string.
  • 2.通过发送REST request body进行。
    
    1.Query string
  • curl -XGET '192.168.192.222:9200/students/_search?pretty'
  • curl -XGET 'http://192.168.192.222:9200/students/_search?pretty'
    2.REST body
    [root@node3 ~]# curl -XGET 'http://192.168.4.120:9200/students/_search?pretty' -d '
    {
    "query": { "match_all": {} }
    }'
    多索引、多类型查询://多个索引之间或者同索引多类型之间

    [root@node3 ~]# curl -XGET 'http://192.168.4.120:9200/_search?pretty'

  • /_search: 查询所有索引
  • /INDEX_NAME/_search:单索引
  • /INDEX1,INDEX2/_search:多索引
  • /s,t/_search :所有s或者t开头的索引
  • /students/class1/_search: 单类型搜索
  • /students/class1,class2/_search :多类型搜索
    
    Mapping和Analysis:映射和分析
    ES:对每一个文档,会取得其所有域的所有值,生成一个名为“_all"的域;执行查询时,如果在query_string未指定查询的域,
    则在_all域上执行查询操作。
  • GET /_search?q='Xianglong'
  • GET /_search?q-'Xianglong Shiba Zhang'
  • GET /_search?q=courses:'Xianglong Shiba Zhang'
  • GET /_search?q=courses:'Xianglong' /在指定域上精确查找
前两个在_all域中搜索,后两个,在指定的域中搜索。
  • curl -XGET 'localhost:9200/students/_search?q="long"' //可以搜索到,匹配到关键字了
  • curl -XGET 'localhost:9200/students/_search?q="long shiba"' //搜索不到,因为会把“long shiba”当做一个词,但是分词时把long和shiba 是分开的
  • curl -XGET 'localhost:9200/students/_search?q=courses:"long shiba"&pretty'
  • curl -XGET 'localhost:9200/students/_search?q=courses:"shiba"&pretty' //能够搜索到
  • curl -XGET 'localhost:9200/students/_search?q="shiba%20shiba"&pretty' //%20代表一个空格
  • curl -XGET 'localhost:9200/students/_search?q="Guo"&pretty' // “Guoxiang” 都不会被匹配到,前后有多余的子串都不行,分词的缘故
_all域中默认使用的是数值型,
数据类型:string,numbers,boolean,dates
  • curl 'localhost:9200/students/_mapping/
  • curl 'localhost:9200/students/_mapping/class1?pretty' //查看被映射的数据类型
    age : long
    class: string
    ... :string //多数都是子串

    2、查询定义

    ES中所有的数据广义上可被理解为两类:

  • types:exact //精确值:值未经加工过的原始值,在搜索时进行精确匹配。(可缓存)
  • full-text:全文搜索 用于引用文本中数据,可以不区分大小写或者引用同义词,判断文档在多大程度上匹配查询请求。(不可缓存)

为了完整full-text搜索,ES 必须首先分析文本,并创建出倒排索引。倒排索引中的数据还需要进行“正规化”为标准格式 //例如统一使用小写,正整数,等

  • 分词:
  • 正规化:

分析=分词+正规化,分析需要由分析器来进行:analyzer
分析器通常有三个组件:

  • 1.字符过滤器
  • 2.分词器
  • 3.分词过滤器

ES内置的分析器:

  • Standard analyzer:基于unicode,用途广
  • Simple analyzer:单词
  • Whitespce analyzer:空白字符进行分割
  • Lanuage analyer:适用于多种不同语言的

分析器不仅在创建索引时用到:在构建查询时也会用到;
建议在查询和创建时使用同一种分析方法

索引/类型/id

[root@node1 conf.d]# curl -XPUT 'localhost:9200/test/class2/1?pretty' -d '{
 "first_name":"Feng",
 "sencond_name":"Xiao",
 "gender":"Male",
 "courses":"xinaglongshibazhang"
}'
{   
  "_index" : "test",
  "_type" : "class2",
  "_id" : "1",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}
[root@node1 conf.d]# curl -XGET 'localhost:9200/test/_search?q="xiao"&pretty'
{
  "took" : 21,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.15342641,
    "hits" : [ {
      "_index" : "test",
      "_type" : "class2",
      "_id" : "1",
      "_score" : 0.15342641,
      "_source" : {
        "first_name" : "Feng",
        "sencond_name" : "Xiao",
        "gender" : "Male",
        "courses" : "xinaglongshibazhang"
      }
    } ]
  }
}

3、过滤器filter dsl:

term filter: //精确匹配包含包含指定term的文档;
    { "term": {"name":"Guo"} } //判断name中是否包含Guo
terms filter:用于多值精确匹配
    { "terms": { "name": ["Guo","Rong"] }}  //name包含Guo或者Rong的
range filter:用于在指定的范围内查找数值或时间
    { “range":
        "age": {
            "gte": 15
            "lte": 25  //15和25之间
        }
    }
    gt,lt,gte,lte
exists and missing filter:存在于不存在
    { 
        "exists": {
            "age": 25
        }
    }
boolean filter:基于boolean模型来合并多个filter子句。
    must:其内部所有的子句条件必须同时匹配,即must
        must: {
            "term": { "age": 25}
            "term": { "agnder": "Female" }
        }   
    must_not:其所有子句必须不匹配,即not
        must_not: {
            "term": { “age": 25 }
        }
    should:至少有一个子句匹配,即or
        should: {
            "term": { "age": 25}
            "term": { "agnder": "Female" }
        }   

查询语句的结构:

    {
        QUERY_NAME: {
            ARGEMENT: VALUE,
            ARGEMENT: VALUE,
            }
    }

    {
        QUERY_NAME: {
            FIELD_NAME: {
            ARGEMENT: VALUE,
            ARGEMENT: VALUE,
            }
        }   
    }   
[root@node3 ~]# curl -XGET 'localhost:9200/students/_search?pretty' -d '{
"term" : {"name": "Guo" }
}'
//在新的版本中这种用法,好像已经不能使用

[root@node1 conf.d]# curl -XGET 'localhost:9200/test/_search?pretty' -d '{
"query": {
"term": {
"first_name":"feng"
}
}
}'
注意,缩进,要统一,例如都适用两位座位缩进

[root@node3 ~]# curl -XGET 'localhost:9200/students/_search?pretty' -d '{
"query": {
  "terms": {
  "age": [25,23,22,28]
   }
  }
}'

4、QUERY DSL:

match_all Query:查看index内的所有文档,没有指定任何query,默认即match_all query
{ "match_all" : {} }
match Query:在几乎任何域上执行full-text或exact-value查询

如果执行full-text查询,首先要对查询时的语句进行分析;
    { "match": {"students": "Guo" }}
如果指定exact-value查询,搜索精确值,此时,建议使用过滤,而非查询
    { "match": {"name": "Guo"} }

multi_match Query:

    用于在多个域上执行相同的查询;
    {
        "multi_match":
            "query": full-text search
            "field": {'field1','field2'}
    }           

    {
        "multi_match":
            "query": {
                "students":"Guo"
            }
            "field":
                {
                    "name",
                    "description"
                }
    }
    //在name和description中查找 students和Guo

bool query:
基于boolean逻辑合并多个查询语句:与bool filter不同的是,查询子句不是返回"yes"或“no"
而是其计算出的匹配度分值,因此,boolean Query会为各个子句合并其score;

must:
must_not:
should:
合并filter和query:

    可以把filter放到query上,进行过滤,但是很少把filter用到query上
    {
        "filterd": {
            query: { "match": {"gender": "female" }}
            filter: { "term": {"age": 25}}
            }
    }

查询语句语法检查:_validate

GET /INDEX/_validdata/query?pretty   
{
    ...
}

GET /INDEX/_validdata/query?explain&pretty  //显示具体的错误内容
{
    ...
}

[root@node3 ~]# curl -XGET 'localhost:9200/students/_search?pretty' -d '
{    "term": { "first_name": "Jing" }
  "query": {
     "term": { "first_name": "Jing" }
 }
}'
    //执行成功
[root@node3 ~]# curl -XGET 'localhost:9200/students/_validate/query?pretty' -d '
{
  "query": {
     "term": { "first_name": "Jing" }
 }
}'
    //valid: "true"  表示语法正确

[root@node3 ~]# curl -XGET 'localhost:9200/students/_validate/query?explain&pretty' -d '
{
  "query": {
     "term": { "first_name": "Jing" }
 }
}'    
    "explanation": "ConstantScore: \u0001,,,,,)"
    //常量值,分数

三、Logstash

ELK stack的另外一个组件:
L:logstash //log stash的agent部署在服务器上,负责收集日志,存储到elasticsearch上

  • 性能不太高,重量级。
  • 有人使用:message queue, //消息队列收集数据
    K:Kibina //Node js开发的搜索界面

图1:
ElasticSearch详解(二)_第1张图片

1、logstash概述

Logstash:数据收集,日志收集。

  • 高度插件化:
  • input,codec,filter,output

图2:
ElasticSearch详解(二)

logstash server:output之后,再发给前端Redis实现存储也可以
MQ:message queue //AMQP:高级消息队列协议,实现数据缓冲。
实现方案有:RabbitMQ,ActiveMQ,Qpid,ZeroMQ,Kafka,Redis的一个子功能

rsyslog:面对海量数据时,不行。
Logstash支持多种数据获取机制:通过TCP/UDP协议、文件、syslog、windows Eventlogs及STDIN等。
获取到数据后:支持对数据进行过滤、修改等操作;

工作机制:
图3:
ElasticSearch详解(二)

每个shifter负责收集日志,但是server不可能同时接受如此多的shifter同时发来信息。
message queue:常用的是redis,server从队列中逐条取出。过滤或者修改。然后发送给ES集群
server是插件式工作方式:

  • input plugin:收集数据。从redis或者其他地方取出数据。
  • codec plugin:编码插件
  • filter plugin:过滤插件
  • output plugin:发送插件

2、安装logstash

源码安装:https://www.elastic.co/downloads/logstash
解压后直接启动:
bin/logstash -e 'input { stdin {} } output { stdout{} }'    //输入内容测试
bin/logstash -e 'input { stdin {} } output { stdout{codec => rubydebug} }' //使用rubydebug编码
bin/logstash -e 'input { stdin {} } output { elasticsearch {hosts => ["192.168.192.222:9200"]} stdout{} }' //推送到目标es主机
bin/logstash -e 'input { stdin {} } output { elasticsearch {hosts => ["172.16.0.15:9200", "172.16.0.16:9200"]} stdout{} }'
bin/logstash -e 'input { stdin {} } output { kafka { topic_id => "test" bootstrap_servers => "172.16.0.11:9092,172.16.0.12:9092,172.16.0.13:9092"} stdout{codec => rubydebug} }' //推送到消息队列

3、修改配置文件

vim logstash.conf
[root@node1 logstash-7.0.0-beta1]# cat config/logstash.conf 
input {
    file {
        type => "os_message_log"
        path => "/var/log/*.log"
        discover_interval => 10
        start_position => "beginning" 
    }
}

output {
  elasticsearch {
    hosts => ["http://192.168.192.222:9200"]
    index => "%{File}-%{+YYYY.MM.dd}"
    #user => "elastic"
    #password => "changeme"
  }
}

启动:logstash -f ./logstash.conf

4、配置框架:

logstash的功能类似于管道:input | filter | output ,如无需对数据进行过滤,filter可以省略

input {
    ...
}

filter {
    ...
}

output {
    ...
} 
四种类型的插件:input,filter,codec,output
input {
  file { 
    type => "flow"
    path => "/var/nginx_logs/*.log" 
    discover_interval => 5
    start_position => "beginning"
  }
}

output {

  if [type] == "flow" {
    elasticsearch { 
      index => "flow-%{+YYYY.MM.dd}"
      hosts => ["172.16.0.14:9200", "172.16.0.15:9200", "172.16.0.16:9200"]
    }

  }  

}

5、数据类型和字段引用

数据类型:

  • Array: [item1,item2,...]
  • Boolean: true,false
  • Bytes:简单数据
  • Codec:编码器
  • Hash:key => value ,字典
  • Number:数值,整数或者浮点数
  • Password: 密码,****
  • Path:文件系统路径
  • String:字符串

字段引用: []
条件判断:

  • ==,!=,《,《=,>,>=
  • =~,!~ //正则匹配
  • in,not in
  • and,or,xor //xor异或
  • () //复合表达式

6、插件Input插件

https://www.elastic.co/guide/en/logstash/current/input-plugins.html
input插件:

  • file:从指定的文件中读取事件流;其工作特性类似于tail -1 file //首次会读取所有。
    按行读取,每一行为一个事件。可以通过codec实现将多行变为一个事件。
    使用Filewatch(Ruby Gen库)监听文件的变化。支持glob风格进行文件展开[可以同时展开多个文件]。
    .sincedb:记录了每个被监听文件的inode,number,minor,number,pos[上一次读取的位置]
    能够识别日志的滚动操作。滚动后的新文件从第一行读取
  • udp:通过udp协议从网络连接来读取Message,其必备参数为port;
    用于指明自己监听的端口。host则用来指明自己监听的地址。
    //接受别人的日志,我的端口和地址
    collectd:性能监控程序:C开发,收集系统性能,发送到网络主机。
  • redis插件:允许logstash从redis收集数据。支持redis channel和list两种方式。
    等等

    7、filter插件

    https://www.elastic.co/guide/en/logstash/current/filter-plugins.html
    filter插件:用于将event通过output发出之前对其实现处理功能。//这里只说 grok
    grok:用于分析并结构化文本数据;目前是logstash中将非结构化日志数据转换为结构化可查询数据的不二之选。
    syslog,apache,nginx日志等,需要指定模式
    模式:这是httpd的日志
    192.168.4.101 - - [11/May/2017:18:26:46 +0800] "GET /favicon.ico HTTP/1.1" 403 213 "http://192.168.4.119/_plugin/head"
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36"

%ip %user %group [%datetime] %method %url %version %status  %size %reference %user_agent
%ip //模式%ip会自动替换为 192.168.4.101,按照空格进行分割
    ip => 192.168.4.101
    user =>
    group => 
    datetime => 11/May/2017:18:26:46 +0800
grok提供有combined和common 等log
    [root@node1 conf.d]# rpm -ql logstash |grep -i "patterns$"
    /opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-0.3.0/patterns/grok-patterns
        COMMONAPACHELOG:
        COMBINEDAPACHELOG:

语法格式:

    %{SYNTAX:SEMANTIC}
        SYNTAX:预定义模式名称
        SEMANTIC:匹配到的文本的自定义标识符
    示例:
        1.1.1.1  GET /index.html 30 0.23

        %{IP:clientip} %{WORD:method} %{URLPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

        %{IP:clientip} //IP是预定义的能够匹配1.1.1.1,clientip是取出之后自定义的变量名
        %{WORD:method} //匹配单词,然后赋值给method
        %{URLPATHPARAM:request} //          

自定义grok的模式:

  • grok的模式是基于正则表达式的模式编写,其元字符与其他awk/sed/grep/pcre差别不大
  • 1.直接使用模式匹配:
  • 2.pattern放到一个文件中匹配
    filter {
    grok {
    patterns_dir => ["./patterns"]
    match => { "message" => "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" }
    }
    }           

    8、output插件

    https://www.elastic.co/guide/en/logstash/current/output-plugins.html
    lotstash之output插件:elasticsearch,file,http,mongodb,redis ,stdout,tcp ,udp,zabbix,...
    elasticsearch:保存到elasticsearch中

  • action ["index", "delete", "create", "update"]
  • hosts: 主机列表
  • index: 存储到的目标索引的位置
  • protocol:协议
    http: 9200,transport:9300,node和transport一样
  • workers:工作线程数
    redis:保存到redis中 //可以当做logstash的输入和输出
  • agent ----[redis] ---> ES--->ES集群[]/[]/[] //对于agent来说输出时redis,但是对于ES来说输入时redis
    redis作为logstash的输出插件:https://www.elastic.co/guide/en/logstash/2.4/plugins-outputs-redis.html
    data_type:logstash输出时有两种格式:list:列表channel:频道
    list相对简单,
    channel:
    用户可能只关心其中一个频道
    数据存储的时候:是指定数据存储到哪个频道的
    0-15个数据库,
    可以专门为redis分配一个数据库
    redis可能同时为多个服务提供存存储服务
    batch:true/false,一次可以rpush多个数据,false一次只能一个
    key:为list或者list启用的名字

四、Logstash配置案例

1、logstash-input-file

[root@node1 conf.d]# vim /etc/logstash/conf.d/file.conf
input {
    file {
        type => "flow"
        discovery_interval => 5
        path => ["/var/log/messages"]
        type => "system"
        start_position => "beginning"
    }
}

output {
    if [type] == "flow" {
        elasticsearch {
        index => "flow-%{+YYYY.MM.dd}"
        hosts => ["172.16.0.14:9200", "172.16.0.15:9200", "172.16.0.16:9200"]
    }

    }
}

[root@node1 conf.d]# logstash -f file.conf

2、logstash-input-udp

node2上使用collectd记录主机状态信息,发送给node2 [logstash],的UDP

(1)node2:collectd

    yum install collectd -y 
[root@node2 ~]# vim /etc/collectd.conf 
[root@node2 ~]# egrep -v "^#|^$" /etc/collectd.conf
    Hostname    "node2.mt.com"
    LoadPlugin syslog
    LoadPlugin cpu
    LoadPlugin df
    LoadPlugin interface
    LoadPlugin load
    LoadPlugin memory
    LoadPlugin network
    
        
        
    
    Include "/etc/collectd.d"
[root@node2 ~]# systemctl start collectd.service
[root@node2 ~]# systemctl status collectd.service

(2)node1:logstash

[root@node1 conf.d]# vim udp_collectd.conf
input {
        udp {
                port => 25820
                codec => collectd {}  //编码器为collectd
                type => "collectd"  //type可以随意起名字
        }
}
output {
        stdout {
                codec => rubydebug
        }
}
[root@node1 conf.d]# logstash -f udp_collectd.conf --configtest

3、logstash-filter-grok

[root@node1 conf.d]# vim grok.conf
[root@node1 conf.d]# egrep -v "^#|^$" grok.conf 
input {
    stdin {}
}
filter {
    grok {
        match => { "message" => "%{IP:clientip} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} "}
    }
}
output {
    stdout {
        codec => rubydebug
    }
}   

4、logstash-file-apachelog

[root@node1 conf.d]# cat apache2.conf 
input {
    file {
        path    => ["/root/access_log"]
        type    => "apachelog"
        start_position  => "beginning"
    }
}

filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
}

output {
    stdout {
        codec => rubydebug
    }
}   

5、收集nginx日志

在grok-parms文件中添加对nginx的匹配模式

[root@node1 conf.d]# cat nginx.conf 
input {
    file {
        path    => ["/var/log/nginx/access.log"]  //nginx的日志是access.log,而httpd的是access_log
        type    => "nginxlog"
        start_position  => "beginning"
    }
}

filter {
    grok {
        match => { "message" => "%{NGINXACCESS}" }
    }
}

output {
    stdout {
        codec => rubydebug
    }
}   

将如下信息添加至 /opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-0.3.0/patterns/grok-patterns文件的尾部:
NGUSERNAME [a-zA-Z.\@-+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:clientip} - %{NOTSPACE:remote_user} [%{HTTPDATE:timestamp}] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NOTSPACE:http_x_forwarded_for}

6、redis作为输出插件

node1:192.168.3.109 //运行了redis,logstash用于测试

[root@node1 conf.d]# vim nglogredis.conf
input {
    file {
        path    => ["/var/log/nginx/access.log"]
        type    => "nginxlog"
        start_position  => "beginning"
    }   
}

filter {
    grok {
        match   => { "message" => "%{NGINXACCESS}" }
    }   
}

output {
    redis {
        port    => "6379"       //一定要有“ ” 否则会出错
        host    => ["127.0.0.1"]
        data_type   => "list"   
        key => "logstash_log"
    }   
}

redis-cli
    help @list
    LLEN logstash-nginxlog //
    LINDEX logstash-nginxlog 1 //获取第一个

7、redis作为输入插件

[root@node2 ~]# vim /etc/logstash/conf.d/server.conf
input {
    redis {
        port    => "6379"
        host    => "192.168.3.109"
        data_type       => "list"
        type    => "nginxlog"
        key     => "logstash_log"
    }
}

output {
    stdout {
        codec   => rubydebug
    }
}   

logstash -f /etc/logstash/conf.d/server.conf //可以看到收集的日志
假如在node1上继续执行 获取命令
[root@node1 conf.d]# logstash -f nglogredis.conf

参考博客:
https://blog.csdn.net/zuochang_liu/article/details/81807955
https://www.elastic.co/guide/en/logstash/current/first-event.html
https://www.elastic.co/guide/en/logstash/current/dir-layout.html