使用Filebeat和AWS CloudWatch Logs将EC2上的Tomcat的access_log传送到ELK

news2024/12/27 1:05:47

文章目录

  • 背景和方案选择
  • 前提
    • 注册AWS账号
    • 创建EC2实例
      • 注意事项
  • 在EC2实例上安装aws-cloudwatch-agent
      • 注意事项
    • 测试aws-cloudwatch-agent是否可用
  • 使用Docker Compose部署ELK
  • 使用Docker Compose部署Filebeat
    • 配置文件说明
      • docker-compose.yml说明
      • filebeat配置文件说明
        • input配置AWS CloudWatch插件
        • output配置
        • processors的配置
        • Tomcat设置access_log输出格式
          • 在Tomat的server.xml中配置access_log配置
          • 在Spring Boot中配置access_log
    • 测试方法
  • 配置Logstash
    • 配置文件说明
  • 完整流程测试
  • 故障排除思路
  • 备注

背景和方案选择

最近一直在搞公司的日志系统,目前日志系统初步有两大部分:

  1. Tomcat的catalina.out
  2. Tomcat的access_log

机器都在AWS上,这两部分的日志都要发送到Docker搭建的ELK环境中。
对于第一点,使用Log4j2即可将应用日志实时传送到ELK中,详情参考使用Log4j2以ECS规范的格式将日志发送到Logstash中
对于第二点,方案则是:通过AWS CloudWatch Logs收集各个EC2 实例上的Tomcat的acceess_log,通过Filebeat拉取AWS CloudWatch Logs里收集到的日志,然后发送到ELK中。

注意:AWS CloudWatch 是一个很大的模块,里面既可以收集各种指标,也可以收集日志。详情参考AWS CloudWatch官方文档

前提

注册AWS账号

AWS注册成功之后,会有一年的免费套餐使用

创建EC2实例

在EC2控制台上找到EC2的文档
在这里插入图片描述
按照官方文档,启动EC2实例即可。

注意事项

  1. 要提前创建key pairs,检查是否存在kye pairs
  2. 要提前创建VPC,检查是否存在默认的VPC,如果没有,点击创建默认的VPC在这里插入图片描述
  3. 要提前创建security group,检查是否存在security group。要特别注意Inbound rules中HTTP,HTTPS,SSH端口的暴露配置,否则有可能无法通过EC2 console连接
  4. 上述三项都确认存在,则按照官方文档开始创建EC2,创建完毕之后测试是否能够通过EC2 console连接到实例。
  5. 连接成功之后,查看IAM下是否有名字ec2-user的用户(因为EC2实例默认的用户名字是ec2-user),如果没有的话,为当前EC2实例创建一个.详细步骤参考下列文档在这里插入图片描述
    记得创建完用户之后,保存用户的access key和secret key

在EC2实例上安装aws-cloudwatch-agent

按照官方文档一步一步来即可
在这里插入图片描述

注意事项

  1. 先下载agent和创建用于AWS CoudWatch Logs的IAM Role
  2. 接着去创建agent所需的文件,创建配置文件时有一个collectd的选项,选择no即可,其他的选项默认即可。到第二段配置的时候,会问你想要监控哪些日志文件,输入文件路径即可
  3. 最后才是将刚刚创建好的IAM Role Attach到EC2实例上,并启动agent

官方文档有点跳跃
在这里插入图片描述

测试aws-cloudwatch-agent是否可用

在EC2实例上启动agent之后,修改agent监控的文件的内容,在AWS CLoudWatch控制台查看,是否有新增的log group和log stream。二者的名字是配置agent时设置的
在这里插入图片描述
如果无法发送到日志到AWS CloudWatch,则检查agent的日志和查阅对应的官方文档

请确保上面的所有流程都正确并且可正常在控制台看到新加的日志再进行下一步

使用Docker Compose部署ELK

部署单节点的ELK可快速使用Github上非常受欢迎的docker-elk项目。
非常简单,代码一拉,改改配置或者都不需要改配置,就可以启动ELK的docker环境。
详细步骤请参考该项目的文档。

进行下一步时,务必确定docker环境的ELK三个组件都正常启动并能访问

使用Docker Compose部署Filebeat

因为上述官方主要提供ELK的docker compose,虽然filebeat也作为extension提供了。但是我自己测试的时候是使用单独的Filebeat,当然最终在产品环境部署的时候肯定是和上面的docker-compose.yml一起的。

mkdir filebeat
cd filebeat

在filebeat文件下建立三个文件

  1. docker-compose文件
    version: "3.7"
    services:
      filebeat-aws:
          image: docker.elastic.co/beats/filebeat:这里的版本号和上面ELK保持一致
          container_name: filebeat
          user: root
          env_file: 
            - .env
          volumes:
            - type: bind
              source: ./filebeat.docker.yml
              target: /usr/share/filebeat/filebeat.yml
            - type: bind
              source: /var/lib/docker/containers
              target: /var/lib/docker/containers
              read_only: true
            - type: bind
              source: /var/run/docker.sock
              target: /var/run/docker.sock
              read_only: true
          networks:
            - elk_elk
    networks:
      elk_elk:
        external: true
    
  2. filebeat配置文件filebeat.docker.yml
    filebeat.inputs:
     - type: aws-cloudwatch
       enabled: true
       log_group_arn: 替换成自己的log_group_arn
       scan_frequency: 15s
       start_position: end
       access_key_id: ${AWS_ACCESS_KEY_ID}
       secret_access_key: ${AWS_SECRET_ACCESS_KEY}
    logging.metrics.enabled: false
    processors:
     - dissect:
          tokenizer: '%{clientIp} - - [%{access_timestamp}] %{response_time|integer} %{session_id} "%{http_request_method} %{url_path} %{http_version}" %{status_code|integer} %{http_request_body_bytes|integer} "%{http_request_referrer}" "%{user_agent_original}"'
          field: "message"
          target_prefix: ""
          ignore_failure: false
     - timestamp:
          field: "access_timestamp"
          layouts:
            - '2006-01-02T15:04:05Z'
            - '2006-01-02T15:04:05.999Z'
            - '2006-01-02T15:04:05.999-07:00'
          test:
            - '2019-06-22T16:33:51Z'
            - '2019-11-18T04:59:51.123Z'
            - '2020-08-03T07:10:20.123456+02:00'
     - drop_fields:
          fields: ["agent","log","cloud","event","message"]
          ignore_missing: true
    #output.console:
    #  pretty: true
    output.logstash:
       hosts: ["logstash:5044"]
    
  3. 环境变量文件.env 这里配置的就是ec2-user的access_key和secret_key
    AWS_ACCESS_KEY_ID=
    AWS_SECRET_ACCESS_KEY=
    

配置文件说明

docker-compose.yml说明

  1. 第一个docker-compose文件中,关于networks的配置做一下说明。因为我们ELK的docker compose环境已经部署好了,它有自己的专属网络。我们此时想要在另外一个docker compose中访问此网络而不需要再自己创建网络,那么就需要做两个事情。第一:在具体service下的networks声明那里的名字要是ELK的docker compose的网络名字。第二:在根节点的networks那里要加一个external的参数并设置为true。更多详细内容参考Compose中external解释
  2. service下network的名字是否修改要看你的docker-compose.yml所在的文件目录,我这里所在的文件目录是elk,然后网络名字是elk,所以docker默认创建出来的网络是elk_elk,如果你的文件目录不是elk,务必要修改正确。关于docker compose中网络的命名,参考Docker Compose官方文档有关NetWork的配置和Compose文件书写规范关于Network一节
  3. 再扩展一下,如果是docker swarm的话,其他docker容器想要访问swarm的网络的话,需要在swarm中添加attachable参数。详情参考Compose文件书写规范关于Network一节和Docker Engine中关于Network的说明

filebeat配置文件说明

input配置AWS CloudWatch插件

具体配置项含义参考官方文档

output配置

因为经过上面的配置,filebeat已经可以访问ELK的网络了。所以这里输出的host直接写ELK的docker-compose.yml中logstash的配置名即可。
注意:filebeat只能配置一个output,不能配置多个output

processors的配置

这里就比较灵活了,看实际情况中Tomcat中关于access_log的配置格式是什么样的。以我的Tomcat配置的access_log为例说明

Tomcat设置access_log输出格式

在Tomat的server.xml中配置access_log配置
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
			prefix="access_log" suffix=".txt"
			pattern="%h %l %u [%{yyyy-MM-dd'T'HH:mm:ss.SSSZ}t] %D %S &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot;"
			renameOnRotate="true"
			requestAttributesEnabled="true" />

上面各个配置的具体含义参考Tomcat官方文档关于Access Log的配置
过滤掉局域网IP

<Valve className="org.apache.catalina.valves.RemoteIpValve"
			internalProxies="172\.16\.\d{1,3}\.\d{1,3}" />

各项配置的具体含义参考Access_Control下的RemoteIp的配置

在Spring Boot中配置access_log

具体配置项的名字在
在这里插入图片描述
Spring Boot文档 > Application Properties > Server Properties下查看

server:
  port: 18081
  servlet:
    context-path: /pool2
  tomcat:
    accesslog:
      enabled: true
      pattern: "%h %l %u [%{yyyy-MM-dd'T'HH:mm:ss.SSSZ}t] %D %S '%r' %s %b '%{Referer}i' '%{User-Agent}i'"
      directory: /tmp/logs/tomcat
      prefix: access_log
    basedir: /var

需要指定basedir,否则tomcat的access_log也是不能生成的.详细文章参考这位博主的分享

对于RemoteIp的配置则是使用默认的,Spring Boot的默认值是

10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1|::1

进入下一步之前,务必确保filebeat能够正常连接到AWS CloudWatch Log并可以正常拉取日志

测试方法

  1. 可以先将filebeat的输出改为输出到控制台,启动filebeat,并确定无报错
  2. 在EC2中向监控的日志添加内容。例如加一条本地Tomcat的access_log
  3. 查看AWS CloudWatch控制台的log group下的log stream是否有刚才新添加的内容。正常情况下,一般2秒左右就可以在观察到有新的日志产生
  4. 查看filebeat日志,是否打印出刚刚在EC2实例中添加的日志,例如使用如下命令
    docker logs --tail 10 -f filebeat
    

配置Logstash

下面根据上面的access_log的格式给出一个示例配置文件

input { 
  beats {
    port => 5044
    client_inactivity_timeout => 3600
    codec => "json"
    tags => [aws_access_log]
  }
}
filter {
  if "aws_access_log" in [tags] {
       #       handle internal ip
        if [clientIp] =~ "^10.0.*|^192.168.*|^172.16.*|^127.0.*|0.0.0.0|^0:0:0:0*" {
                mutate {
                        add_tag => ["private internets"]
                }
        }
#       convert ip to IP type from String Type
        if [clientIp] and "private internets" not in [tags] {
                geoip {
                        source => "clientIp"
                        target => "[client][geo]"
                }
        }
        useragent {
           source => 'user_agent_original'
        }
        date {
           match => ["access_timestamp", "yyyy-MM-dd'T'HH:mm:ss.SSSZ"]
        }
        mutate {
                add_field => {
                       "[@metadata][server_name]" => "%{[awscloudwatch][log_stream]}"
                }
                rename => {
                        "clientIp" => "[client][ip]"
                        "status_code" => "[http][response][status_code]"
                        "http_request_method" => "[http][request][method]"
                        "http_request_referrer" => "[http][request][referrer]"
                        "http_request_body_bytes" => "[http][request][body][bytes]"
                        "http_version" => "[http][version]"
                        "url_path" => "[url][path]"
                        "log.file.path" => "[log][file][path]"
                        "user_agent_original" => "[user_agent][original]"
                        "ecs.version" => "[ecs][version]"
                }
                remove_field => ["[input]","[host]","access_timestamp"]
        }
        if [client][geo]{
                mutate {
                        remove_field => ["[client][geo][ip]"]
                }
        }
  }
}
output {
       
       if "aws_access_log" in [tags] {
                elasticsearch {
                        hosts => "elasticsearch:9200"
                        user => "logstash_internal"
                        password => "${LOGSTASH_INTERNAL_PASSWORD}"
                        index => "ecs-logstash-aws-access-log-%{[@metadata][server_name]}-%{+YYYY.MM.dd}"
               }
        }
}

配置文件说明

  1. 建议所有input都加入专属的tags,方便在filter中同其他input的处理隔离,因为实际情况中,很可能Logstash有多个input,每个input的处理逻辑都不相同。所以最好是用tags区分开
  2. 这里直接使用Elasticsearch自带的ecs-logstash的index template
  3. 在access_log中,将私有IP地址打上标记,并不去解析IP,因为这些IP解析不出来,还会报错
  4. 如果是正常的IP则使用logstash的geoip插件解析
  5. 对于access_log中的user agent使用logstash的useragent插件解析
  6. 使用logstash的date插件将access_log中的时间戳由字符串转为@timestamp字段
  7. 使用logstash的mutate插件将字段重命名为符合ECS规范的字段
  8. 为了便于查看具体的index,index命名时加入EC2的服务器名字以区分各个服务器的access_log,通过使用logstash的@metadata来达到此目的

完整流程测试

  1. 重启logstash,并确保无错误
  2. 将filebeat的输出配置改为logstash,并重启filebeat并确保无错误
  3. 在EC2中向监控的日志文件添加一些日志
  4. 在Kibana中查看是否有新的ecs-logstash-*的index产生

故障排除思路

如果进行每一步时都按照博客中说的步骤进行验证正确了之后才进行的下一步。那么最终完整流程应该非常顺利的串起来。
如果最终日志没发送到ES中,提供几个排查的思路

  1. 在Logstash中的output中加入stdout打印一下,看看是否真的收到了filebeat推送过了的日志
  2. 如果上一步没问题,则观察ES的日志,看看是否有错误产生.例如
    docker logs --tail 5 -f elasticsearch
    

备注

  1. 上述很多配置都需要仔细阅读对应的官方文档,这篇博文更多的是整体的思路分享而不是手把手教学
  2. AWS所有的文档我这里没有给出链接,因为都可以登录到具体服务的控制台,在控制台页面那里仔细找找,就可以找到对应文档的入口点
  3. 上述配置文件如果真的看懂了,在实际解决问题中,应该经过简单修改或者照葫芦画瓢就可以基本满足你的实际业务需要

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为智能基座实验【计算机组成原理】

华为智能基座实验【计算机组成原理】前言推荐华为智能基座实验【计算机组成原理】1 课程介绍1.1 简介1.2 内容描述1.3 读者知识背景1.4 实验环境说明2 实验 1&#xff1a;hello-world 示例程序2.1 实验介绍2.1.1 关于本实验2.1.2 教学目标2.1.3 实验内容介绍2.2 实验任务操作指…

宝宝多大戒尿不湿?不看年龄看表现,用对方法轻松戒掉尿不湿

宝宝刚出生的时候&#xff0c;大小便次数比较多&#xff0c;宝宝自己也控制不了。这时&#xff0c;使用尿布可以减少父母的大量工作。但使用尿布只是暂时的。当宝宝到了一定年龄&#xff0c;就应该戒掉。宝宝能戒尿多大&#xff1f;既然尿布是用来兜宝宝大小便的&#xff0c;如…

从零学习 InfiniBand-network架构(十一) —— 管理器的介绍

从零学习 InfiniBand-network架构&#xff08;十一&#xff09; —— 管理器的介绍 &#x1f508;声明&#xff1a; &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN主页 &#x1f511;未经作者允许&#xff0c;禁止转载 &#x1f6a9;本专题部分内容源于《InfiniBand-network…

作为QA,我们要如何思考?

随着测试人员陆续开始尝试角色转变&#xff0c;坚守的QA需要找到自己的发展之路。兴趣和性格是客观因素&#xff0c;好奇心和发散性思维则是帮助成为优秀QA的必要因素。我想通过一些小的例子来与大家互动探讨。 测试你做对了吗&#xff1f; 让我们从这样一个现实中的小例子来…

【历史上的今天】12 月 30 日:C++ 之父诞生;Hotmail 创始人出生;Facebook 注册破百万

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2022 年 12 月 30 日&#xff0c;在 1930 年的这一天&#xff0c;“青蒿素之母”屠呦呦出生。2015 年 10 月 5 日&#xff0c;屠呦呦获得诺贝尔生理学或医学奖&#xf…

【Java基础知识】对Object类wait()和notify()方法的理解

wait()/notify()原理 当前线程必须拥有此对象的monitor监视器&#xff08;锁&#xff09;。&#xff08;不获取锁直接用Object对象调用wait和notify,会报错java.lang.IllegalMonitorStateException&#xff09;当前线程调用wait() 方法&#xff0c;线程就会释放此锁的所有权&a…

动态库和静态库

文章目录感性认识库动态库和静态库从库的设计者来看库制作静态库制作动态库库的使用者的角度静态库的使用使用动态库1.把头文件和库文件拷贝到系统的路径下2.修改对应的环境变量更改文件 ld.so.conf.d在系统的库路径下建立对应的软链接动态库如何加载感性认识库 首先&#xff…

关于GNSS关键性能测试,应该如何选择?

现在&#xff0c;GPS/GNSS信号无处不在&#xff0c;而GNSS接收机芯片的低成本和高性能也让在不同设备中安装GNSS接收机变得更为容易。然而&#xff0c;与此同时又存在一个问题&#xff0c;如果想将这些接收器芯片集成到一个设备或系统中&#xff0c;该如何对其进行全面的GNSS测…

方法注解@Bean与对象注入

1.类注解是添加到某个类上的&#xff0c;⽽⽅法注解是放到某个⽅法上的&#xff0c;如以下代码的实现&#xff1a; 注&#xff1a;方法注解一定要搭配类注解使用&#xff0c;否则会报错 2.重命名Bean 多个重命名&#xff0c;使用多个名称获取的对象都是同一个 3.获取 Bean 对象…

全网惟一面向软件测试人员的Python基础教程-在Python中列表是什么?

全网惟一面向软件测试人员的Python基础教程 起点&#xff1a;《python软件测试实战宝典》介绍 第一章 为什么软件测试人员要学习Python 第二章 学Python之前要搞懂的道理 第三章 你知道Python代码是怎样运行的吗&#xff1f; 第四章 Python数据类型中有那些故事呢&#xff1f;…

TTL(RGB)接口液晶显示屏的调试方法

TTL接口的液晶显示屏一般会使用DE模式驱动它。首先需要CPU带有LCD控制器&#xff0c;能够产生出液晶显示屏所需要的以下几个信号&#xff1a; 1.时钟信号(DOTCLK) 2.行同步信号(HSYNC) 3.场同步信号(VSYNC) 4.DEN(数据允许信号) 6.数据信号&#xff08;R0-R7;G0-G7;B0-B7)…

第02讲:Git分支操作

一、什么是分支 在版本控制过程中&#xff0c;同时推进多个任务&#xff0c;为每个任务&#xff0c;我们就可以创建每个任务的单独 分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来&#xff0c;开发自己分支的时 候&#xff0c;不会影响主线分支的运行。对于…

剑指 Offer 17. 打印从1到最大的n位数

题目 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 思路 本题应该考虑的是大数问题&#xff0c;但是返回数组为int[]。。。所以两种方法都做一下 方法一&#xff1a;普通解法&#xff…

天翼云服务器性能评测,4H8G贵阳节点性能跑分

天翼云号称全球运营商云第一、中国公有云用户数第二、政务云公有云第一。那么天翼云服务器用起来到底怎么样呢&#xff1f; 目前&#xff0c;蓝队云这边一共有19个天翼云节点云服务器&#xff0c;覆盖全国多个核心省市及地区&#xff0c;节点选择的话一般就是按照就近原则。 …

权威报告出炉:2022年移动机器人出货量增长53%!2023年移动机器人迎来发展新拐点?

原创/文 BFT机器人 近日&#xff0c;全球权威研究机构Interact Analysis重磅发布移动机器人领域的“风向标”——《2022年移动机器人市场报告》&#xff08;The Mobile Robot Market 2022&#xff09;&#xff0c;深入探究真实市场数据&#xff0c;对全球移动机器人领域的发展现…

当压力传感器遇到汽车电子系统 智芯传感打造车规级智能感知传感器产品

汽车电子系统是汽车数字化的发端和基础&#xff0c;更是汽车智能化的前提。近年来&#xff0c;伴随着汽车电子技术的快速发展与应用&#xff0c;汽车电子系统在车辆控制精度、范围、适应性和智能化等方面&#xff0c;都实现了大幅优化提升。而压力传感器作为汽车电子系统的主要…

RHCSA 第五天笔记

用户和组管理 用户分为三类&#xff1a; 超级用户 root 普通用户 只能切换到自己有的用户 系统用户&#xff08;不常用&#xff0c;没办法登录&#xff09; 组分为两类 定义概念 基本组&#xff08;私有组&#xff09; 没指定所属组&#xff0c;系统建立和用户同名的组 附加…

诺依文件上传支持阿里云oss

文章目录描述后端引入依赖application.yml 添加访问oss需要的参数编写oss工具类编写controller前端更改调用接口![在这里插入图片描述](https://img-blog.csdnimg.cn/efc28eb8244e4da482d46327ab29a999.png)去掉baseUrl回调成功后url改成真实urlmain.js中挂在该组件具体调用代码…

华为手表开发:GT3(1)配置调试设备

华为手表开发&#xff1a;GT3&#xff08;1&#xff09;配置调试设备初环境与设备获取手表UUID登录 AppGallery Connect 点击用户与访问初 希望能写一些简单的教程和案例分享给需要的人 环境与设备 系统&#xff1a;window 设备&#xff1a;HUAWEI WATCH 3 Pro 开发工具&…

自动化测试到底该怎么学?

从功能测试到自动化测试 &#xff0c;待遇翻倍&#xff0c;我整理的超全学习指南&#xff01; 首选你需要拥有一个全网最牛最全面的软件测试全职业生涯进阶从零基础到测试开发学习路线图。 其次跟着大纲的内容慢慢学习&#xff0c;当然配套的【教学视频配套的学习资料】肯定是…