二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Nexus系列文章

  • Jenkins系列文章

  • ELK笔记

    • ELK

      • elk基础环境安装
      • 使用rsyslog传输管理nginx日志
        • 1,nginx 日志 json 化。
        • 2,发送端配置。
        • 3,接收端配置。
        • 4,配置 logstash。
        • 5,简单使用 kibana。
      • 使用filebeat管理微服务日志
      • 监控告警之elastalert的配置全解
      • elk采集日志的流程引入kafka集群的配置流程
      • 记一次日志突然写不进去了的处理
    • FileBeat

    • LogStash

    • ElasticSearch

    • Kibana

  • Kubernetes笔记

  • LLM专题

  • 系列专题
  • ELK笔记
  • ELK
二丫讲梵
2019-01-05
目录

使用rsyslog传输管理nginx日志

文章发布较早,内容可能过时,阅读注意甄别。

现在有好几台主机的 nginx 日志想要监控分析一下,那么,如何让远程主机的日志都乖乖的来到 elk 主机之上呢,这是一个需要考虑的问题,而这里,我就使用 rsyslog 来完成。

这种方式貌似针对于远程主机上只有单项日志的情况,就像我们现在做的,只处理 nginx 的访问日志一般的,如果还有更多的日志需要从远程转发到 elk 集群中,就需要用其他方式了,或者说我只会配置这么一种,更复杂的,目前还玩不转。后来哈,在当我测试 rsyslog 转发多个日志的时候,发现,里边配置规则过于复杂,分类方面也非常不给力,就此打住,一旦多个日志,直接用 filebeat 即可。

现在,废话不多说,直接进入正题。

目前的思路,可以通过下图了解:

说明:

  • 图中举例了两台 nginx,其实可以有更多台 nginx 日志可以想后方转发。
  • 双方以 rsyslog 作为桥梁,从而实现日志的中转运输。其中 nginx 主机上是发送端,elk 主机上是接收端。
  • 针对不同的 nginx 日志,可以启动不同的 logstash 实例,然后将日志转发给 es。
  • 由 es,统一将日志转给 kibana。

基本上配置起来也就是按上边的思路走,一步步配置起来就好了。

主机情况:

主机 组件
172.16.37.157 Nginx,Rsyslog
10.100.120.82 Rsyslog,ELK

# 1,nginx 日志 json 化。

首先来配置 nginx 端的日志,为了方便后边一系列的操作,需要先把 nginx 的日志 json 化,要配置也非常简单,通过编辑 nginx 的配置文件来实现:

在 nginx 的配置文件 nginx.conf 的 http 区域添加如下内容:

log_format json '{"@timestamp":"$time_iso8601",'
                 '"host":"$server_addr",'
                 '"request_method": "$request_method", '
                 '"clientip":"$remote_addr",'
                 '"size":$body_bytes_sent,'
                 '"responsetime":$request_time,'
                 '"upstreamtime":"$upstream_response_time",'
                 '"upstreamhost":"$upstream_addr",'
                 '"http_host":"$host",'
                 '"url":"$uri",'
                 '"xff":"$http_x_forwarded_for",'
                 '"referer":"$http_referer",'
                 '"agent":"$http_user_agent",'
                 '"status":"$status"}';
1
2
3
4
5
6
7
8
9
10
11
12
13
14

注意,这个地方的配置,其实是非常重要的,里边定义了许多的字段(可能还不明白字段是什么意思,等到后边会慢慢介绍这个东东),这些字段取自于原 nginx 日志,然后再转给 es,最后通过 kibana 展示出来,从而让分析更加多维,立体,简单说明一下这些参数:

  • timestamp:日志的时间戳。
  • host:nginx 所在主机 IP。
  • request_method:请求类型(POST,GET)
  • clientip:前端 ip。
  • size:请求大小。
  • responsetime:请求响应时间。
  • upstreamtime:后端相应请求时间。
  • upstreamhost:后端服务器 IP。
  • http_host:域名。
  • url:请求的接口。
  • xff:用户 IP。
  • referer:完整请求地址。
  • agent:客户端类型。
  • status:状态码。

其中的clientip常规情况下就是指请求的来源 IP 地址,下边的xff也是,原因是我们的环境当中在 nginx 节点之前,还有一层 waf,所以此时代表请求的来源 IP 地址的,则是xff,这个字段用意,将会在后边说明。

然后在 nginx 的访问日志配置 access_log 处更改配置如下:

access_log /var/log/nginx/access.log json;
1

此处的 json 是与上边的log_format后边的名称相对应的,保持一致即可。如果有多台,可以将如上配置配置过去,这里我就不一一列举了,就拿这台 nginx 作为示例了。下边也一样,不再配置多台。

# 2,发送端配置。

现在开始编辑 rsyslog 发送端的配置,直接编辑 rsyslog 的配置文件,这里以其中一台服务器的 nginx 日志作为示例,通过 rsyslog 将 nginx 的访问日志转发到 elk 主机上去。

说明有二:

  • 默认我这里使用的是 CentOS7 的主机,已经安装了 rsyslog-8.x 的服务。
  • 还有主机是 CentOS-6.x 的,可能 rsyslog 版本很低,这个解决非常简单,通过如下两条命令安装即可。
wget http://rpms.adiscon.com/v8-stable/rsyslog.repo -O /etc/yum.repos.d/rsyslog.repo
yum -y install rsyslog
rsyslogd -v
1
2
3

接下来列出配置内容:

[root@localhost curl]$egrep -v "^#|^$" /etc/rsyslog.conf
$ModLoad imfile
$InputFilePollInterval 3
$WorkDirectory /var/spool/rsyslog
$PrivDropToGroup adm
$InputFileName /var/log/nginx/access.log
$InputFileTag nginx-access:
$InputFileStateFile stat-nginx-access
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
$template BiglogFormatNginx,"%msg%\n"
if $programname == 'nginx-access' then @10.100.120.82:514;BiglogFormatNginx
1
2
3
4
5
6
7
8
9
10
11
12
13
  • InputFileName:定义日志文件位置,此处貌似不能使用*.log 来匹配。
  • InputFileTag:定义一个 tag,方便下边调用。
  • template:定义日志格式的模板。
  • 最后一句:将日志转发给10.100.120.82的UDP(一个@表示 UDP,两个@表示 TCP)端口514,并应用模板BiglogFormatNginx。

# 3,接收端配置。

接收端在 elk 主机之上,这里同样配置 rsyslog 作为接收端,然后将接收到的日志存在 elk 本地。配置内容如下:

[root@localhost ~]$egrep -v "^#|^$" /etc/rsyslog.conf
$template myformat,"%rawmsg%\n"
$ActionFileDefaultTemplate myformat
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
$ModLoad immark  # provides --MARK-- message capability
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514
$WorkDirectory /var/lib/rsyslog
$AllowedSender tcp, 10.100.120.0/24,172.16.37.0/24
$template Remote,"/logs/logstashfile/%fromhost-ip%/%fromhost-ip%_%$YEAR%-%$MONTH%-%$DAY%.log"
:fromhost-ip, !isequal, "127.0.0.1" ?Remote
$IncludeConfig /etc/rsyslog.d/*.conf
$OmitLocalLogging on
$IMJournalStateFile imjournal.state
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

说明:

  • 1,在本机开启 upd,tcp 端口 514 接收日志。
  • 2,接收的范围,是 IP 定义的,多个网段的话中间用逗号隔开。
  • 3,接收到的日志存放模板,存在本地的/logs 目录下,这里注意需要创建对应目录。
  • 4,不杰接受来自 elk 本机的日志。

然后在两边都启动 rsyslog 服务。

systemctl restart rsyslog
systemctl enable rsyslog
systemctl status rsyslog
1
2
3

等待一会儿,就能够在 elk 主机上看到日志目录生成了。

[root@elk logstashfile]$pwd
/logs/logstashfile
[root@elk logstashfile]$ls
172.16.37.157
1
2
3
4

然后进去看一下日志,发现就是远程主机当中已经 json 化的 nginx 访问日志。

# 4,配置 logstash。

接着就该考虑如何将远程转过来的 nginx 日志,呈现在 elk 集群当中,这里使用 logstash 进行日志的转发,配置如下:

cat > /etc/logstash/conf.d/nginx.conf << EOF
input {
    file {
        type => "nginx-access"
        path => "/logs/logstashfile/172.16.37.157/172.16.37.157_*.log"
        codec => "json"
    }
}
filter {
    geoip {
        source => "xff"
        fields => ["city_name", "country_code2", "country_name", "latitude", "longitude", "region_name"]
        remove_field => ["[geoip][latitude]", "[geoip][longitude]"]
    }
    json {
        source => "message"
        target => "jsoncontent"
    }
}
output {
    if [type] == "nginx-access" {
        elasticsearch {
            hosts => ["127.0.0.1:9200"]
            manage_template => true
            index => "nginx-access-%{+YYYY-MM}"
        }
    }
}
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  • 1,input 定义日志的名称(type),位置(path),格式。可以定义多个。这里直接读取通过 rsyslog 放置到本地的日志。
  • 2,filter 定义一些关键字段的过滤。通过 geoip 来实现 ip 的地理位置标识,注意这个地方我的 source 是 xff,上边我已经解释过这个原因,如果你的是常规情况,那么应该更改成 clientip。
  • 3,output 定义标准输出,到本机的 9200 端口,最后的 index 是索引名称,可以自定义,如果是不同主机上的日志,可以在这个地方根据其 ip 不同来进行区分。

注意:此处所配置的geoip (opens new window)不需要像网上许多教程说的,还要再引用对应的数据库,因为目前最新版本的 elk 已经配备了相应的配置,这点,在等会儿启动的日志当中可以见分晓。

然后再将这个实例起来,通过此实例将日志转给 es。

启动时默认有一个 data 目录,为了方便以后多实例管理,所以单独创建一个,另外启动日志也可以输出一个,从而让运维更容易,同样也创建对应的目录。

mkdir /usr/share/logstash/data1
mkdir /logs/logstash_nohup
1
2

启动实例。

nohup /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/nginx.conf --path.data=/usr/share/logstash/data1 &> /logs/logstash_nohup/nginx.out &
1

然后监听一下转发状况:

[root@localhost ~]$tail -fn 100 /logs/logstash_nohup/nginx.out
WARNING可以忽略,因为我们启动的时候已经指定配置文件了。: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console
[WARN ] 2018-12-18 17:49:40.285 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
[INFO ] 2018-12-18 17:49:40.300 [LogStash::Runner] runner - Starting Logstash {"logstash.version"=>"6.5.3"}
[INFO ] 2018-12-18 17:49:43.330 [Converge PipelineAction::Create<main>] pipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>16, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50}
[INFO ] 2018-12-18 17:49:43.733 [[main]-pipeline-manager] elasticsearch - Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>[http://127.0.0.1:9200/]}}
[WARN ] 2018-12-18 17:49:45.024 [[main]-pipeline-manager] elasticsearch - Restored connection to ES instance {:url=>"http://127.0.0.1:9200/"}
[INFO ] 2018-12-18 17:49:46.660 [[main]-pipeline-manager] elasticsearch - ES Output version determined {:es_version=>6}
[WARN ] 2018-12-18 17:49:46.663 [[main]-pipeline-manager] elasticsearch - Detected a 6.x and above cluster: the `type` event field won't be used to determine the document _type {:es_version=>6}
[INFO ] 2018-12-18 17:49:46.687 [[main]-pipeline-manager] elasticsearch - New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>["//127.0.0.1:9200"]}
[INFO ] 2018-12-18 17:49:46.701 [Ruby-0-Thread-5: :1] elasticsearch - Using mapping template from {:path=>nil}
[INFO ] 2018-12-18 17:49:46.711 [[main]-pipeline-manager] geoip - Using geoip database {:path=>"/usr/share/logstash/vendor/bundle/jruby/2.3.0/gems/logstash-filter-geoip-5.0.3-java/vendor/GeoLite2-City.mmdb"}
[INFO ] 2018-12-18 17:49:46.723 [Ruby-0-Thread-5: :1] elasticsearch - Attempting to install template {:manage_template=>{"template"=>"logstash-*", "version"=>60001, "settings"=>{"index.refresh_interval"=>"5s"}, "mappings"=>{"_default_"=>{"dynamic_templates"=>[{"message_field"=>{"path_match"=>"message", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false}}}, {"string_fields"=>{"match"=>"*", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false, "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}}}}], "properties"=>{"@timestamp"=>{"type"=>"date"}, "@version"=>{"type"=>"keyword"}, "geoip"=>{"dynamic"=>true, "properties"=>{"ip"=>{"type"=>"ip"}, "location"=>{"type"=>"geo_point"}, "latitude"=>{"type"=>"half_float"}, "longitude"=>{"type"=>"half_float"}}}}}}}}
[INFO ] 2018-12-18 17:49:46.989 [[main]>worker15] beats - Beats inputs: Starting input listener {:address=>"0.0.0.0:5054"}
[INFO ] 2018-12-18 17:49:47.006 [Converge PipelineAction::Create<main>] pipeline - Pipeline started successfully {:pipeline_id=>"main", :thread=>"#<Thread:0x31362ee1 run>"}
[INFO ] 2018-12-18 17:49:47.058 [Ruby-0-Thread-1: /usr/share/logstash/lib/bootstrap/environment.rb:6] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[INFO ] 2018-12-18 17:49:47.061 [[main]<beats] Server - Starting server on port: 5054
[INFO ] 2018-12-18 17:49:47.290 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9610}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

说明:

从这段日志当中,可以看出不少的信息,所以特别的拎出来了。

  • 1,第一个 WARNING 可以忽略,因为我们启动的时候已经指定配置文件了。
  • 2,启动之后开始连接配置当中指定的 127.0.0.1:9200。
  • 3,接着会看到一个输出:
geoip - Using geoip database {:path=>"/usr/share/logstash/vendor/bundle/jruby/2.3.0/gems/logstash-filter-geoip-5.0.3-java/vendor/GeoLite2-City.mmdb"}
1

这条输出的意思就是刚刚我提到的那个问题,系统其实已经有了对应的库,进行加载,当然,有可能这个库的新鲜度未必能够保证。需要注意的是,GeoLite 数据库由每月的第一个星期二的 MaxMind 更新,如果需要最新的,可以及时进行更新下载。

  • 4,接着可以看到 es 加载了初始定义好了的模板进行数据处理。
  • 5,直到一系列初始化完成,然后正式处理对应的日志到。

过一会儿,会看到有大量日志输出,说明日志已经成功转发给 es,此时也可以去 kibana 当中创建一个对应的索引了。

# 5,简单使用 kibana。

现在来访问 kibana 做一些简单查看:

img

  • 1,点击管理,进入到管理界面。
  • 2,点击索引管理,可以看到 es 已经创建的索引。
  • 3,点击索引模式,将 es 的索引引入到 kibana 当中。

现在我们点击第三步,去创建一下索引:

img

点击进来之后,就能看到刚刚我们定义的索引了,现在我创建一个以nginx-access*命名的索引(这个地方所列出来的索引,都是在 logstash 的配置当中定义了的索引),点击下一步。

img

选择索引的模式,这里一般都使用timestamp,即以时间作为标准。然后点击创建即可。

img

创建成功之后,能够看到一些我们前边定义好了的字段,这些字段也将成为我们日后分析日志的重要依据,可能你现在对字段是什么,还不能十分理解,不用着急,慢慢往后看,咱们一起边做边理解。

现在可以去看一下,前台日志展示页面是否成功了:

img

可以看到日志已经呈现在眼前了,到这里,可以说,基本上 elk 的整个流程就算是走通了。

貌似一般情况下,网上教程都是到这个地方就结束了,然而,事情难道不是刚刚开始么。

接着,我们先来看一下我们前边多次提到的字段是否如我们所愿的展示了,查看的方法也很简单,随便点击其中一条日志,查看其 json 的格式:

img

{
  "_index": "nginx-access-2018-12",
  "_type": "doc",
  "_id": "USJ_wWcBSQAerHbVQR9q",
  "_version": 1,
  "_score": null,
  "_source": {
    "xff": "183.214.48.249",
    "request_method": "POST",
    "host": "172.16.37.157",
    "agent": "-",
    "upstreamtime": "0.004",
    "@timestamp": "2018-12-18T13:26:40.000Z",
    "referer": "https://h5.51fanbei.com/h5/activity/201806/wxIndexHelp.html?inviteUser=NpCYtbHZVkqufRMsZvVqNg==&freeOrder=WHaDtQnCpE9BSOnAB9LVxQ==",
    "upstreamhost": "172.16.37.158:8080",
    "clientip": "172.16.37.161",
    "responsetime": 0.005,
    "url": "/fanbei-web/activity/freeOrder/showHelpGoods",
    "status": "200",
    "size": 76,
    "@version": "1",
    "type": "nginx-access",
    "path": "/logs/logstashfile/172.16.37.157/172.16.37.157_2018-12-18.log",
    "geoip": {
      "country_code2": "CN",
      "city_name": "Changsha",
      "region_name": "Hunan",
      "country_name": "China"
    },
    "http_host": "app.51fanbei.com"
  },
  "fields": {
    "@timestamp": ["2018-12-18T13:26:40.000Z"]
  },
  "sort": [1545139600000]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

这样一展示之后,就能看出,清晰多了,我们所想要的,都生成了,稍候就能够通过这些数据,来进行画图等操作。

微信 支付宝
#elk
上次更新: 2024/07/04, 22:40:37
elk基础环境安装
使用filebeat管理微服务日志

← elk基础环境安装 使用filebeat管理微服务日志→

最近更新
01
学习周刊-总第213期-2025年第22周
05-29
02
学习周刊-总第212期-2025年第21周
05-22
03
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式