一、ES集群健康检查
二、ES查询
三、Logstash
四、Logstash配置案例
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
[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"
}
}
}
}
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" : "" }}' //这样就可以继续分配了
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
关闭 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"}}
curl http://192.168.192.222:9200 //查看版本信息
白屏操作:可以安装Kibana
查询索引: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"
}
} ]
}
}
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]
}
}
}'
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,,,,,)"
//常量值,分数
ELK stack的另外一个组件:
L:logstash //log stash的agent部署在服务器上,负责收集日志,存储到elasticsearch上
- 性能不太高,重量级。
- 有人使用:message queue, //消息队列收集数据
K:Kibina //Node js开发的搜索界面
图1:
Logstash:数据收集,日志收集。
- 高度插件化:
- input,codec,filter,output
图2:
logstash server:output之后,再发给前端Redis实现存储也可以
MQ:message queue //AMQP:高级消息队列协议,实现数据缓冲。
实现方案有:RabbitMQ,ActiveMQ,Qpid,ZeroMQ,Kafka,Redis的一个子功能
rsyslog:面对海量数据时,不行。
Logstash支持多种数据获取机制:通过TCP/UDP协议、文件、syslog、windows Eventlogs及STDIN等。
获取到数据后:支持对数据进行过滤、修改等操作;
工作机制:
图3:
每个shifter负责收集日志,但是server不可能同时接受如此多的shifter同时发来信息。
message queue:常用的是redis,server从队列中逐条取出。过滤或者修改。然后发送给ES集群
server是插件式工作方式:
- input plugin:收集数据。从redis或者其他地方取出数据。
- codec plugin:编码插件
- filter plugin:过滤插件
- output plugin:发送插件
源码安装: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} }' //推送到消息队列
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
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"]
}
}
}
数据类型:
- Array: [item1,item2,...]
- Boolean: true,false
- Bytes:简单数据
- Codec:编码器
- Hash:key => value ,字典
- Number:数值,整数或者浮点数
- Password: 密码,****
- Path:文件系统路径
- String:字符串
字段引用: []
条件判断:
- ==,!=,《,《=,>,>=
- =~,!~ //正则匹配
- in,not in
- and,or,xor //xor异或
- () //复合表达式
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.htmldata_type:logstash输出时有两种格式:list:列表channel:频道 list相对简单, channel: 用户可能只关心其中一个频道 数据存储的时候:是指定数据存储到哪个频道的 0-15个数据库, 可以专门为redis分配一个数据库 redis可能同时为多个服务提供存存储服务 batch:true/false,一次可以rpush多个数据,false一次只能一个 key:为list或者list启用的名字
[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
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
[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
}
}
[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
}
}
在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}
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 //获取第一个
[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
转载于:https://blog.51cto.com/hmtk520/2368960