难的不是技术,难的是业务。熟悉业务流程才是最难的。

其实搜索进来的每一个人的需求不一样,希望你能从我的这篇文章里面收获到。

建议还是看官方文档,更全面一些。

一、背景

1,收集nginx  access  error日志,nginx日志最开始是main日志,后来被我改成了json日志方便收集

2,收集php info  error日志,php日志就是标准的

3,每一个php服务都是docker容器启动

4,每一个php容器服务里面都有一个nginx服务

5,需要收集日志的php服务大概30个

6,k8s集群三台节点

7,需要收集qa,dev环境日志,qa,dev其实就是k8s集群里面的两个namespaces

8,需要提取特定的字段

1.1 日志目录

每一个php容器服务都是这个日志结构

/var/log/nginx/access.log
/var/log/nginx/error.log
/var/www/html/storage/logs/lumen.log
/var/www/html/storage/autoLogs/sysError/lumen.log

1.2 思考点&解决方案

1,采集的Beat用哪个

filebeat:轻量级,cpu 内存小,咱们的需求只是单纯的采集数据。进程稳定。

2,Beat的部署方式

filebeat部署在k8s 节点宿主机,二进制部署

3,日志的采集方式

Php容器日志目录挂载到宿主机

4,qa,dev环境怎么区分

kibana区分用index

容器日志目录挂载到宿主机。

$env=qa,dev

$appname=php所有的服务名称

/data/service-logs/${env}/${appname}/{nginx,storage/{logs,autoLogs/sysError/}}

例如:wxx 服务的dev环境宿主机目录结构

/data/service-logs/dev/wxx/nginx/      这个下面有access  error日志

/data/service-logs/dev/wxx/storage/logs/      php info日志

/data/service-logs/dev/wxx/storage/autoLogs/sysError/        php  error日志

5,怎么区分php服务

kibana:添加字段app_name

6,日志类型怎么区分

kibana:添加字段log_topics

二、集群服务器配置

我这里采用的是3节点,其实主要就是es集群。

这样的配置足够我这的需求了,你可以按照需求调整。

我这里大概每小时收集5万条数据。每天数据量大概是2G。

ip cpu mem 软件
192.168.31.61 4 8G es,kibana,cerebro
192.168.31.62 4 8G  
192.168.31.63 4 8G  

三、部署服务

3.1 部署es

3.1.1 下载

cd /opt/

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.12.1-linux-x86_64.tar.gz

3.1.2 配置

tar xf elasticsearch-7.12.1-linux-x86_64.tar.gz
cd /opt/elasticsearch-7.12.1/config node1
vim elasticsearch.yml
cluster.name: dev-qa-es # 集群的名称
node.name: 192.168.31.61 # node1节点的名称
path.data: /data/elasticsearch/data # 数据目录
path.logs: /data/elasticsearch/log # 日志目录
network.host: 192.168.31.61 # 节点的ip 就是监听的地址
http.port: 9200 # es端口
discovery.seed_hosts: ["192.168.31.62", "192.168.31.63"] # 除自己之外的两个节点
cluster.initial_master_nodes: ["192.168.31.61", "192.168.31.62", "192.168.31.63"] # 所有的master node2
cluster.name: dev-qa-es
node.name: 192.168.31.62
path.data: /data/elasticsearch/data
path.logs: /data/elasticsearch/log
network.host: 192.168.31.62
http.port: 9200
discovery.seed_hosts: ["192.168.31.61", "192.168.31.63"]
cluster.initial_master_nodes: ["192.168.31.61", "192.168.31.62", "192.168.31.63"] node3
cluster.name: dev-qa-es
node.name: 192.168.31.63
path.data: /data/elasticsearch/data
path.logs: /data/elasticsearch/log
network.host: 192.168.31.63
http.port: 9200
discovery.seed_hosts: ["192.168.31.61", "192.168.31.62"]
cluster.initial_master_nodes: ["192.168.31.61", "192.168.31.62", "192.168.31.63"]

3.1.3 配置jdk

1,因为elasticsearch是java写的,所以需要java环境。

2,可以自己手动在机器上面安装java。但是会造成这台机器上面的java环境固定。或者会对以前的java版本产生改变。

3,所以elasticsearch 7以上版本会自带jdk,所以我们只需要告诉elasticsearch使用自带的jdk即可。

其实主要控制es用不用自带java的 变量就俩 ES_JAVA_HOME   JAVA_HOME

cd /opt/elasticsearch-7.12.1/bin

vim elasticsearch-env
...
ES_HOME=`dirname "$SCRIPT"`
# now make ES_HOME absolute
ES_HOME=`cd "$ES_HOME"; pwd`
while [ "`basename "$ES_HOME"`" != "bin" ]; do
ES_HOME=`dirname "$ES_HOME"`
done
ES_HOME=`dirname "$ES_HOME"`
ES_JAVA_HOME=/opt/elasticsearch-7.12.1/jdk # 我只是添加了一个ES_JAVA_HOME变量,下面的if判断会判断这个变量。
# now set the classpath
ES_CLASSPATH="$ES_HOME/lib/*"
# now set the path to java
if [ ! -z "$ES_JAVA_HOME" ]; then # 会判断这个变量是否为空 !不为空 走下面的代码
JAVA="$ES_JAVA_HOME/bin/java" # 这样java环境就有了
JAVA_TYPE="ES_JAVA_HOME"
elif [ ! -z "$JAVA_HOME" ]; then
# fallback to JAVA_HOME
echo "warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME" >&2
JAVA="$JAVA_HOME/bin/java"
JAVA_TYPE="JAVA_HOME"
else
# use the bundled JDK (default)
if [ "$(uname -s)" = "Darwin" ]; then
# macOS has a different structure
JAVA="$ES_HOME/jdk.app/Contents/Home/bin/java"
else
JAVA="$ES_HOME/jdk/bin/java"
fi
JAVA_TYPE="bundled JDK"
fi
...

3.1.4 启动es

elasticsearch 7以后的版本都自带启动脚本,只需要执行一下就行

3.1.5 检查es集群

访问三个节点的其中一个的 9200端口 :http://192.168.31.61:9200/

查看一些接口:http://192.168.31.61:9200/_cat

查看index:http://192.168.31.61:9200/_cat/indices

3.2 部署cerebro

cerebro是一个es的监控工具,类似于es的插件一样。可以同时监控多个集群。

cd /opt/
wget https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.zip
unzip cerebro-0.9.4.zip
cd cerebro-0.9.4
 
配置
vim conf/application.conf
 
加入以下配置
hosts = [
{
host = "http://192.168.31.61:9200" # es地址
name = "dev-qa-es" # 集群名称
headers-whitelist = [ "x-proxy-user", "x-proxy-roles", "X-Forwarded-For" ]
}
]
启动
cd bin
nohup ./cerebro 2>&1 &

3.2.1 访问

可以看到es集群的一些常用的信息

http://192.168.31.61:9000

3.3 Kibana

3.3.1 下载

cd /opt/
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.12.1-linux-x86_64.tar.gz

3.3.2 配置

cd /opt/
tar xf kibana-7.12.1-linux-x86_64.tar.gz 配置
cd /opt/kibana-7.12.1
vim config/kibana.yml
server.port: 5601 # 监听端口
server.host: "192.168.31.61" # 监听地址
elasticsearch.hosts: ["http://192.168.31.61:9200", "http://192.168.31.62:9200", "http://192.168.31.63:9200"] # es hosts
i18n.locale: "zh-CN"

3.3.3 启动&访问

cd /opt/kibana-7.12.1-linux-x86_64/bin

nohup su - kibana -c "/opt/kibana-7.12.1-linux-x86_64/bin/kibana" &    # 前提是需要新建好kibana用户

访问:http://192.168.31.61:5601

3.4 部署filebeat

3.4.1 下载

cd /opt/
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.12.1-linux-x86_64.tar.gz
tar xf filebeat-7.12.1-linux-x86_64.tar.gz

3.4.2 目录规划

/data/service-logs/{dev,qa}/$appname/{nginx,storage/{logs,autoLogs/sysError}}

$env=qa,dev

$appname=php所有的服务名称

/data/service-logs/${env}/${appname}/{nginx,storage/{logs,autoLogs/sysError/}}

例如:wxx 服务的dev环境宿主机目录结构

/data/service-logs/dev/wxx/nginx/      这个下面有access  error日志

/data/service-logs/dev/wxx/storage/logs/      php info日志

/data/service-logs/dev/wxx/storage/autoLogs/sysError/        php  error日志

3.4.3 服务日志挂载到宿主机

1,更改php服务容器的yaml文件的volumeMounts
比如这个dev环境的wxx服务 volumeMounts:
- mountPath: /var/log/nginx
name: pod-nginx-log
- mountPath: /var/www/html/storage/logs
name: pod-storage-logs
- mountPath: /var/www/html/storage/autoLogs/sysError
name: pod-storage-autologs
volumes:
- hostPath:
path: /data/service-logs/dev/wxx/nginx
type: ""
name: pod-nginx-log
- hostPath:
path: /data/service-logs/dev/wxx/storage/logs
type: ""
name: pod-storage-logs
- hostPath:
path: /data/service-logs/dev/wxx/storage/autoLogs/sysError
type: ""
name: pod-storage-autologs

3.4.4 nginx json格式输出

更改nginx.conf
加入json格式定义 log_format access_json_log escape=json '{"@timestamp":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"http_host":"$http_host",'
'"request_length":"$request_length",'
'"upstream_response_length":"$upstream_response_length",'
'"upstream_response_time":"$upstream_response_time",'
'"request_body":"$request_body",'
'"upstream_status":"$upstream_status",'
'"status":"$status",'
'"request":"$request",'
'"request_method":"$request_method",'
'"http_referrer":"$http_referrer",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"http_user_agent":"$http_user_agent"}'; access_log /var/log/nginx/access.log access_json_log;

3.4.5 php info日志提取匹配

原始日志:其实就是filebeat支持正则表达式,只要你能匹配出你想要的日志内容就行

我们提取[2021-07-05 13:00:00] 到下一个[2021-07-05 13:01:00] 中间的内容

所以匹配就可以写成,

multiline.pattern: '^\['    # 其实就是以[开头的行
multiline.negate: true
multiline.match: after
multiline.negate: true
multiline.match: after

这俩就是控制满足匹配之前的还是之后的,官方文档:https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.html

3.4.5 php error日志提取匹配

原始日志:

我们提取2021-07-05 15:00:00 到下一个 2021-07-05 15:01:00

multiline.pattern: '^[0-9]{4}-[0-9]{2}-'    # 以日期开头
multiline.negate: true
multiline.match: after

总结:各种不同的日志 可以用不同的正则表达式去匹配出来。

3.4.6 我的filebeat配置

cd /opt/k8s/efk/filebeat-7.12.1-linux-x86_64/

服务太多我只展示了一个服务的配置。其他的都是一样的
vim filebeat.yml
filebeat.inputs:
#########################################################################
#### 日志收集 ####
# 一个项目为一个#组,一个组里有4个收集规则
# collectLogStart
############################## operation-api ##############################
- type: log
enabled: true # 启用输入
encoding: utf-8 # 字符编码
paths:
- /data/service-logs/dev/operation-api/nginx/access.log # 日志路径
tail_files: true # true 从文件的末尾读取,false 从开头读取文件
json.keys_under_root: true # json解码
json.overwrite_keys: true # json解码
fields: # 额外增加字段
app_env: "dev"
app_name: "operation-api"
log_topics: "nginx-access"
fields_under_root: true # 增加的字段是否为顶级key
- type: log
enabled: true
encoding: utf-8
paths:
- /data/service-logs/dev/operation-api/nginx/error.log
tail_files: true
fields:
app_env: "dev"
app_name: "operation-api"
log_topics: "nginx-error"
fields_under_root: true
- type: log
enabled: true
encoding: utf-8
paths:
- /data/service-logs/dev/operation-api/storage/logs/lumen*.log
multiline.pattern: '^\['
multiline.negate: true
multiline.match: after
tail_files: true
fields:
app_env: "dev"
app_name: "operation-api"
log_topics: "php-logs"
fields_under_root: true
- type: log
enabled: true
encoding: utf-8
paths:
- /data/service-logs/dev/operation-api/storage/autoLogs/sysError/lumen*.log
multiline.pattern: '^[0-9]{4}-[0-9]{2}-'
multiline.negate: true
multiline.match: after
tail_files: true
fields:
app_env: "dev"
app_name: "operation-api"
log_topics: "php-errlogs"
fields_under_root: true
############################## operation-api ############################## # collectLogEnd
################################### 日志收集配置 ########################
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false # 自定义index
setup.template.name: "zm-log"
setup.template.pattern: "zm-log-*"
setup.template.overwrite: true
setup.template.enabled: true
setup.ilm.enabled: false # 这个配置至关重要,是关于ilm生命周期。可以查看官方文档。这个是关闭自带的,然后使用自定义的。 output.elasticsearch:
hosts: ["192.168.31.61:9200","192.168.31.62:9200","192.168.31.63:9200"]
loadbalance: true # 开启负载
pipelines: # 有关filebeat使用pipeline 我后期单独写一篇文章:https://www.cnblogs.com/fanfanfanlichun/p/14977166.html
- pipeline: "extract-traceid-pipeline"
when.contains:
log_topics: "php-errlogs" indices: # index的配置,这个配置就是说当app_env=qa的时候用index: "zm-log-qa-%{+yyyy.MM.dd-000001}"
- index: "zm-log-qa-%{+yyyy.MM.dd-000001}"
when.contains:
app_env: "qa" - index: "zm-log-dev-%{+yyyy.MM.dd}-000001"
when.contains:
app_env: "dev" processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~ - drop_fields: # 这个是丢弃哪些key
fields: ["host.mac","host.ip","host.os.name"]

3.4.7 启动

nohup /opt/k8s/efk/filebeat-7.12.1-linux-x86_64/filebeat -e -c /opt/k8s/efk/filebeat-7.12.1-linux-x86_64/filebeat.yml >/dev/null 2>&1 &

3.5 访问kibana

http://192.168.31.61:5601

3.5.1 字段解释

app_name:服务名称

log_topics:nginx-access    nginx-error    php-info   php-error

四、总结

1,其实我这个是按照我这边的业务场景配置的,希望对你有益。

2,官方文档才是最好的。

3,有问题留言,我会及时回复。

共同成长。共同进步。

elk 日志收集 filebeat 集群搭建 php业务服务日志 nginx日志 json 7.12版本 ELK 解决方案的更多相关文章

  1. ELK+Kafka学习笔记之搭建ELK+Kafka日志收集系统集群

    0x00 概述 关于如何搭建ELK部分,请参考这篇文章,https://www.cnblogs.com/JetpropelledSnake/p/9893566.html. 该篇用户为非root,使用用 ...

  2. ELK+zookeeper+kafka+rsyslog集群搭建

    前言 环境困境: 1.开发人员无法登陆服务器 2.各系统都有日志,日志数据分散难以查找 3.日志数据量大,查询忙,不能实时 环境要求: 1.日志需要标准化   集群流程图:   角色:   软件: 以 ...

  3. [转载] 一共81个,开源大数据处理工具汇总(下),包括日志收集系统/集群管理/RPC等

    原文: http://www.36dsj.com/archives/25042 接上一部分:一共81个,开源大数据处理工具汇总(上),第二部分主要收集整理的内容主要有日志收集系统.消息系统.分布式服务 ...

  4. 一共81个,开源大数据处理工具汇总(下),包括日志收集系统/集群管理/RPC等

    作者:大数据女神-诺蓝(微信公号:dashujunvshen).本文是36大数据专稿,转载必须标明来源36大数据. 接上一部分:一共81个,开源大数据处理工具汇总(上),第二部分主要收集整理的内容主要 ...

  5. redis整合Spring集群搭建及业务中的使用

    1.redis安装 Redis是c语言开发的. 安装redis需要c语言的编译环境.如果没有gcc需要在线安装.yum install gcc-c++ 安装步骤: 第一步:redis的源码包上传到li ...

  6. 8分钟学会Consul集群搭建及微服务概念

    Consul介绍: Consul 是由 HashiCorp 公司推出的开源软件,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与 ...

  7. 每秒处理3百万请求的Web集群搭建-为最佳性能调优 Nginx

    这篇文章是<打造3百万次请求/秒的高性能服务器集群>系列的第2部分,在这个部分中你可以使用任何一种 WEB 服务器,不过我决定使用 Nginx,因其轻量级.高可靠及高性能的优点. 通常来说 ...

  8. 微服务注册发现集群搭建—单机版(Registrator+Consul+Consul-template+nginx)

    1.创建模板文件 docker-compose.yml #backend web application, scale this with docker-compose scale web=3 web ...

  9. apigateway-kong(五)集群搭建部署

    kong 集群将使得系统通过增加更多机器,从而实现水平扩展,承接更多的请求流量.它们将共享同样的配置且使用同一个数据库.kong 集群中的的所有节点都连接同一个数据库. 你需要在 kong 集群的上一 ...

随机推荐

  1. Linux学习之路-Linux-at及cron命令【7】---20171215

    Linux学习之路-Linux-at及cron命令[7]---20171215 DannyExia000人评论986人阅读2017-12-24 17:28:03   ntpdate 命令 [root@ ...

  2. dmesg -w 查看硬件参数

    dmesg -w 查看硬件参数 14,笔记本硬件问题,使用dmesg -w可以看到,内核不断受到硬件过来的热插拔信号

  3. Linux 目录管理

    tree命令的基本使用 tree 查看当前目录的树状结构 -a 查看所有包含隐藏文件 -L 1 查看目录层级 tree /root 指定目录 根目录下的主要文件 /bin 普通用户可以执行的二进制文件 ...

  4. JQuery Ajax 发送请求成功后却接收不到任何响应数据问题

    问题描述 使用 JQuery Ajax 向后端服务器发送请求,服务器也收到请求返回了响应数据,但是 Ajax 却收不到任何响应数据. 举例如下: $.ajax({ type: "post&q ...

  5. Java 自定义常量

    Java 中的常量就是初始化或赋值后不能再修改,而变量则可以重新赋值. 我们可以使用Java 关键字 final 定义一个常量,如下 final double PI = 3.14; 注意:为了区别 J ...

  6. git OpenSSL SSL_connect问题

    遇到这个问题,查找别人也遇到,省时间不写了直接复制 在使用Git来克隆仓库报了错误,如下: fatal: unable to access 'https://github.com/xingbuxing ...

  7. Lua的string库函数列表

    基本函数 函数 描述 示例 结果 len 计算字符串长度 string.len("abcd") 4 rep 返回字符串s的n个拷贝 string.rep("abcd&qu ...

  8. Java中生成唯一标识符的方法

    有时候业务需要生成唯一标识符,但又不能依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,此时我们就需要用程序来生成一个唯一的全局ID. UUID UUID是指在一台机器上 ...

  9. [LeetCode] 1074. 元素和为目标值的子矩阵数量

    矩阵前缀和.因为矩阵中可能包含负值,所以这题肯定不会存在什么剪枝,动态规划的可能性.所以这个题也就没什么弯弯绕绕.个人感觉算不上个Hard题目. 最直观的思路就是枚举子矩阵,既枚举矩阵的左上角节点和右 ...

  10. checkbox,select,radio 选取值,设定值,回显值

    获取一组radio被选中项的值var item = $('input[@name=items][@checked]').val();获取select被选中项的文本var item = $(" ...