当前位置: 首页 > 科技观察

了解SAE日志收集架构

时间:2023-03-14 17:54:49 科技观察

log对于一个程序的重要性不言而喻。无论是作为排查问题的手段、记录关键节点信息,还是提供预警、配置和监控行情等,都发挥着至关重要的作用。是每节课乃至每一次申请都需要记录和复习的重要内容。云原生时代,无论是采集方案还是采集架构,日志采集都与传统的日志采集有所区别。我们总结过,在日志收集的过程中,我们经常会遇到一些实际的常见问题,比如:部署在K8s上的应用,磁盘大小会比物理机低很多,所有的日志不能长期保存,以及有查询历史数据要求,日志数据非常关键,不能丢失。即便是重启应用,重建实例,希望在日志上对一些关键字等信息进行告警,监控盘的权限控制非常严格。无法使用或查询SLS等日志系统。JAVA、PHP等应用的异常栈需要导入到自己的日志采集系统中,会产生换行,栈异常会打印成多行。如何总结和看待它们?那么在实际生产环境中,用户如何使用日志功能进行采集呢?面对不同的业务场景、不同的业务需求,哪种采集方案更好?ServerlessApplicationEngineSAE(ServerlessAppEngine)作为一个全托管、免运维、高度灵活的通用PaaS平台,提供SLS采集、挂载NAS采集、Kafka采集等多种采集方式,供用户在不同领域使用场景。使用。本文将重点介绍各种日志采集方式的特点、最佳使用场景,帮助您设计合适的采集架构,避免一些常见问题。SAE的日志采集方式SLS采集架构SLS日志采集是SAE推荐的日志采集方案。一站式提供数据采集、处理、查询分析、可视化、告警、消费和交付能力。SAE内置集成SLS采集,可以方便的采集业务日志和容器标准输出到SLS。SAE集成SLS的架构图如下图所示:SAE会在pod中挂载一个logtail(SLScollector)的sidecar。然后将客户配置的需要采集的文件或路径以卷的形式共享给业务Container和logtailSidecar。这就是为什么不能为SAE日志收集配置/home/admin。因为服务的启动容器放在/home/admin,挂载卷会覆盖启动容器。同时logtail的数据上报是通过SLS内网地址上报的,不需要开通外网。为了不影响业务容器的运行,SLS的sidecar获取会设置资源限制,比如CPU限制为0.25C,内存限制为100M。SLS适用于大部分业务场景,支持配置告警和监控图。大多数适合直接选择SLS。NAS采集架构NAS是一个共享访问、弹性扩展、高可靠、高性能的分布式文件系统。它提供高吞吐量和高IOPS,同时支持文件的随机读写和在线修改。更适合日志场景。如果想在本地保存更多或更大的日志,可以挂载NAS,然后将日志文件的保存路径指向NAS的挂载目录。NAS挂载SAE,涉及的技术点和架构不多,这里略过,不做过多介绍。当NAS用于日志采集时,可以看成是本地盘。即使实例崩溃重建等,也不会有日志丢失。对于非常重要的不允许数据丢失的场景,可以考虑这种方案。Kafka采集架构用户自己也可以采集日志文件的内容到Kafka,然后通过消费Kafka数据来采集日志。后续用户可以根据自己的需要将Kafka中的日志导入ElasticSearch,或者编程消费Kafka数据进行处理。收集日志到Kafka自身的方式有很多种,比如最常见的logstach,比较轻量级的收集组件如filebeat、vector等。SAE使用的集合组件是vector。SAE整合vector的架构图如下图所示:SAE会在pod中挂载一个logtail(vectorcollector)的sidecar。然后将客户配置的需要采集的文件或路径以卷的形式共享给业务Container和vectorSidecar,采集的日志数据会定时发送给Kafka。Vector本身有比较丰富的参数设置,可以设置采集数据压缩,数据发送间隔,采集指标等。Kafkacollection可以看作是SLScollection的一个补充。在实际生产环境中,有些客户对权限的控制非常严格。他们可能只有SAE权限,但没有SLS权限。因此,需要将日志采集到Kafka进行后续查看,或者对日志进行二次处理等场景,也可以选择Kafka日志采集方案。下面是一部分基础的vector.toml配置:data_dir="/etc/vector"[sinks.sae_logs_to_kafka]type="kafka"bootstrap_servers="kafka_endpoint"encoding.codec="json"encoding.except_fields=["source_type","timestamp"]inputs=["add_tags_0"]topic="{{topic}}"[sources.sae_logs_0]type="file"read_from="end"max_line_bytes=1048576max_read_bytes=1048576multiline.start_pattern='^[^\s]'multiline.mode="continue_through"multiline.condition_pattern='(?m)^[\s|\W].*$|(?m)^(Caused|java|org|com|net).+$|(?m)^}.*$'multiline.timeout_ms=1000include=["/sae-stdlog/kafka-select/0.log"][transforms.add_tags_0]type="remap"inputs=["sae_logs_0"]source='.topic="test1"'[sources.internal_metrics]scrape_interval_secs=15type="internal_metrics_ext"[sources.internal_metrics.tags]host_key="host"pid_key="pid"[transforms.internal_metrics_filter]type="filter"inputs=["internal_metrics"]condition='.tags.component_type=="file"||.tags.component_type=="kafka"||starts_with!(.name,"vector")'[sinks.internal_metrics_to_prom]type="prometheus_remote_write"inputs=["internal_metrics_filter"]endpoint="prometheus_endpoint"重要参数分析:multiline.start_pattern是检测到这种规律性的时候multiline.condition_pattern检测到符合此规则的行,它将与上一行合并并视为一行。配置sinks.internal_metrics_to_prom后,会将一些vector收集到的元数据上报给Prometheus。下面是vector收集到Prometheus的元数据的配置。Grafana的监控面板配置了一些vector元数据的采集监控图:实际使用中的好习惯,可以根据自己的业务需求选择不同的日志采集方式logback日志采集策略本身需要对文件进行限制文件的大小和数量,否则更容易填满pod磁盘。以JAVA为例,下面的配置会保留最多7个文件,每个文件最大100M。${user.home}/logs/test/test.log${user.home}/logs/test/test.%i.log17100MB<编码器类="ch.qos.logback.classic.encoder.PatternLayoutEncoder">UTF-8%d{yyyy-MM-ddHH:mm:ss}|%msg%n这一段log4j的配置是比较常见的日志轮转配置。常见的日志轮转方式有两种,一种是create方式,一种是copytruncate方式。不同的日志采集组件对两者的支持存在一些差异。create方式是将原来的日志文件重命名,创建一个新的日志文件来代替。log4j使用这种模式。详细步骤如下图所示:在写入日志的事件日志之前,会判断是否已经达到文件设置的最大容量。如果没有,写作将完成。如果已经达到,则进入阶段2,首先关闭currentlyActiveFile指向的文件,然后重命名原文件,并新建一个文件。这个文件的名字和之前currentlyActiveFile指向的名字一样。currentlyActiveFile指向的文件成为stage2新创建的文件。copytruncate模式的思路是对输出的日志做一份拷贝,然后清除原来的日志。目前主流组件的支持等级如下:ActualCaseDemo下面介绍客户实际生产环境中的一些真实场景。客户A通过日志轮转设置程序的日志,并将日志收集到SLS。并通过关键字配置相关告警,监控行情等。首先,通过log4j的配置,最多保留10个日志文件,每个大小为200M,并进行磁盘监控。日志文件保存在/home/admin/logs路径中。这里就不多介绍了,大家可以介绍最佳实践场景的配置。然后使用SAE的SLS日志收集功能将日志收集到SLS中。最后在程序中通过日志中的一些关键字,或者其他一些规则,比如200状态码的比例等进行告警配置。通过Nginx日志完成监控磁盘的配置。常见问题日志合并简介很多时候,我们需要收集日志,并不是简单的一行一行收集,而是需要将多行日志合并为一行进行收集,比如JAVA异常日志。这时候就需要用到日志合并功能了。在SLS中,有一个集合模式,带有多行模式。这种模式需要用户设置一个正则表达式来合并多行。矢量集合也有类似的参数。multiline.start_pattern用于设置换行的规律性,如果满足这个规律,则认为是换行。可以与multiline.mode参数结合使用。更多参数请参考vector官网。日志采集丢失分析无论是SLS采集还是vector采集到Kafka,都是为了保证采集到的日志不丢失。收集到的点(CheckPoint)信息会保存在本地。如果服务器意外关机,进程崩溃等异常情况,数据会从上次记录的位置开始采集,尽可能保证数据不丢失。但这并不能保证日志不会丢失。在某些极端场景下,日志收集可能会丢失。比如K8s的pod进程崩溃、liveness失效等异常导致pod重建日志轮转极快,比如每秒一次。日志采集速度长时间达不到日志生成速度。对于场景2和3,需要检查自己的应用,是否打印了太多不必要的日志,或者日志轮转设置是否异常。因为在正常情况下,这些情况是不应该发生的。对于场景一,如果对日志要求非常严格,pod重建后不能丢失,可以使用挂载的NAS作为日志存储路径,这样即使pod重建后日志也不会丢失。总结本文主要介绍SAE提供的各种日志采集方案,以及相关的架构和场景使用特点。总结起来有三点:SLS采集适应性强,适用于大部分场景。NAS采集在任何场景下都不会丢失,适用于对日志要求非常严格的场景。Kafkacollection是SLScollection的补充。对于二次处理,或者由于权限等原因无法使用SLS的场景,可以选择将日志收集到Kafka中自行收集处理。