掌握结构化日志记录:全面指南

在当今复杂的软件生态系统中,应用程序日志非常宝贵。它们允许开发者窥视应用程序的内部,了解系统内部的真实情况。但是,传统的非结构化日志数据有很多不足之处。这些混乱的文本块无法提供完整的画面。要真正发挥日志的力量,我们需要采取更加深思熟虑的方法 - 一种为了消费而设计的日志生成方式。
在这里插入图片描述

引言:

这就是结构化日志记录登场的时刻。这种现代日志记录范式提供了解锁应用程序日志更深层次洞察力的缺失部分。与不透明的文本流不同,结构化日志在每条日志声明中嵌入重要的上下文元数据。这种机器可读的数据支持强大的搜索、过滤、分析和可视化。

通过结构化日志记录,麻烦的错误和性能问题不会隐藏太久。应用程序行为的趋势和异常变得更加明显。将日志数据解析并引入分析工具变得简单。简而言之,结构化日志记录为应用程序日志记录的狂野世界带来了理智、理解和透明度。

对于构建复杂、关键任务软件的开发者来说,结构化日志记录是观测性的必备工具。这篇博文深入探讨了结构化日志记录的关键概念及其为何应成为今天工程团队的最佳实践。我们将探索各种语言和框架的流行结构化日志记录库。通过理解结构化日志记录,你将提升设计、构建和监控在真实世界条件下运行良好的应用程序的能力。日志记录的未来已经到来 - 让我们一起探索吧!

什么是结构化日志记录?

结构化日志记录是一种现代的应用程序日志记录方法,旨在使日志数据更加可用。它通过输出结构化格式的日志声明,而不是非结构化的纯文本,来工作。

每条日志行包含键值对和标准化字段,而不是自由格式的消息。例如,一个Web请求日志可能有像“timestamp”、“latency”、“request_id”、“user_id”、“endpoint”等字段。这提供了关于日志声明的关键上下文。

所有相关的元数据都直接在日志行本身中,而不是埋藏在周围的文本中。这种机器可读的结构支持强大的搜索、过滤、聚合和可视化。结构化日志数据无缝集成到数据管道和分析工具中。

结构化日志记录的好处:

结构化日志记录的好处巨大。当你可以通过请求ID或用户ID过滤日志时,调试会变得更快。可以通过诸如延迟或CPU时间这样的字段监控性能模式和趋势。限速和聚合变得简单。上下文数据有助于调查问题。

总的

来说,结构化日志记录导致更高质量的日志数据,提供了更深入的洞察应用程序行为。它从将日志记录作为一个事后想法转变为针对消费和价值进行优化的日志。任何严肃的应用程序都可以通过采用结构化日志记录最佳实践获得观测性超能力。

设置日志级别:

日志记录的一个关键方面是设置适当的日志级别来控制日志输出的详细程度。常见的日志级别包括DEBUG、INFO、WARNING、ERROR和FATAL,每个级别在传达事件的严重性方面都有特定的用途。配置日志级别确保只捕获相关信息,提高日志清晰度并减少噪音。

import "github.com/sirupsen/logrus"// 使用期望的日志级别配置日志记录器
logrus.SetLevel(logrus.InfoLevel)

如何使用日志级别映射:

日志级别映射是日志记录器及其相应日志级别之间的映射。这种映射允许开发人员微调不同组件或环境的日志级别。通过根据上下文自定义日志级别,开发人员可以优先处理关键信息并抑制不那么重要的日志。

var loggerLevels = map[string]logrus.Level{"module1": logrus.DebugLevel,"module2": logrus.InfoLevel,
}func getLogger(module string) *logrus.Logger {logger := logrus.New()logger.SetLevel(loggerLevels[module])return logger
}

为不同环境使用不同日志级别的好处:

为各种环境(如开发、测试和生产)采用不同的日志级别提供了几个优势。在开发中,详细的日志记录有助于调试工作,而在生产中,最小化日志详细程度可以节省资源并简化日志分析。根据每个环境调整日志级别优化了日志记录行为,提高了操作效率。

使用结构化日志记录:

实现结构化日志记录涉及集成支持结构化日志格式的日志记录库。通过利用像Go中的Slog这样的库,开发人员可以无缝过渡到结构化日志记录并解锁其好处。结构化日志记录库提供了用于格式化、过滤和丰富日志数据的强大功能,使开发人员能够深入洞察他们的应用程序。

import "github.com/sirupsen/logrus"// 使用logrus的结构化日志记录示例
logger := logrus.New()
logger.WithFields(logrus.Fields{"user":    "john.doe","action":  "login","success": true,
}).Info("用户成功登录")

如何实现自定义日志处理程序:

自定义日志处理程序通过使开发人员能够自定义日志输出和行为来扩展日志记录库的功能。无论是添加额外的元数据、将日志发送到外部服务还是实现自定义日志格式化,自定义日志处理程序都提供了根据特定要求定制日志记录解决方案的灵活性。

上下文日志记录:

上下文日志记录通过向日志条目添加上下文信息(如请求ID、用户标识符和时间戳)来丰富日志条目。这些额外的元数据通过提供每个日志事件的关键上下文来增强日志的可追溯性,并简化根本原因分析。将上下文日志记录与中间件集成,允许开发人员自动将上下文注入日志

条目,简化日志生成和分析。

如何使用日志中间件将上下文信息附加到日志中:

日志中间件与Web框架无缝集成,捕获特定于请求的信息并将其注入日志条目中。通过将中间件纳入请求处理管道,开发人员可以自动将上下文数据(如请求ID和用户代理)附加到日志消息中。这种方法提高了日志的可理解性,并促进了日志与特定应用程序交互之间的关联。

在日志中拥有请求ID对调试目的的重要性:

请求ID作为单个请求的唯一标识符,有助于在分布式系统中进行请求跟踪和调试。在日志条目中包含请求ID使开发人员能够追踪请求在各个组件中的流动,并识别瓶颈或错误。有了请求ID,故障排除变得更加容易,因为开发人员可以关联不同服务的日志,并重建每个请求的执行路径。

存储您的日志:

应用程序日志的存储方式可能成就或破坏日志数据的有用性。选择最佳存储解决方案需要评估规模、速度、保留需求和访问模式等因素。对于严肃的生产系统来说,简单地记录到本地文本文件的日子已经一去不复返了。现代应用程序需要强大的后端基础设施,以有效地利用日志。

对于小规模用例,本地文件系统存储提供了简单性和易访问性。但随着数据量、用户和基础设施的增长,管理性、耐用性和聚合能力在管理性、耐用性和聚合能力方面出现了局限性。这就是集中式日志服务大放异彩的地方。

云托管平台,如AWS CloudWatch日志和Datadog,提供了从多样化基础设施自动实时日志聚合的功能。弹性可伸缩性、细粒度访问控制和强大的分析功能使得可以获得可操作的洞察力。然而,随着数据量的增加,成本也会增加。

开源日志存储,如Elasticsearch、Kafka和Redis,在本地或跨云环境中提供了类似的好处。它们可以集成到可扩展的日志管道中。但它们需要专业知识来操作、调整和保护。

法规合规性也应指导日志存储选择。一些框架,如HIPAA,规定了数据保护、保留政策和访问审计,这些并非所有解决方案都完全支持。

通过评估其独特的工作负载需求,DevOps团队可以选择日志存储架构,以获得最佳效用。本地文件的尾部提供了简单性,而基于云的分析揭示了隐藏的应用程序洞察力。结合两种方法将两全其美。

推荐存储日志的地方(文件、Cloudwatch、Data Dog):

对于中小型应用程序,将日志文件存储在本地可以是一个好选择。这在开发环境中提供了简单性。日志文件可以实时跟踪并直接访问以进行检查。然而,随着应用程序规模和复杂性的增长,本地日志文件变得更难管理。

以下是在Go中将消息记录到文件的简单示例:

package mainimport ("log""os"
)func main() {// 打开日志文件f, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)if err != nil {log.Fatal(err)}// 设置日志记录器以记录到文件logger := log.New(f, "", log.LstdFlags)// 记录消息logger.Println("启动应用程序...")logger.Printf("日志消息:%s", "Hello World")// 关闭文件f.Close()}

关键步骤是:

  1. 使用os.OpenFile()打开一个用于写入的文件。这将追加并在需要时创建文件。
  2. 创建一个写入打开文件的log.Logger
  3. 调用像Println()Printf()这样的logger方法来记录消息。
  4. 完成后关闭文件。

这会将消息记录到app.log文件中。文件轮转、日志分割和其他增强功能可以在这个基本日志记录之上添加。

对于规模较大的生产系统,AWS CloudWatch日志等基于云的日志聚合服务变得更加可取。CloudWatch提供了自动化的日志收集、高度可扩展的存储以及与其他AWS服务的集成。监控、警报和流式传输到其他数据平台等有用功能是可用的。通过日志过期策略等功能,成本可以优化。

以下是如何在Go中将应用程序日志发送到AWS CloudWatch日志的示例:

package mainimport ("github.com/aws/aws-sdk-go/aws""github.com/aws/aws-sdk-go/aws/session""github.com/aws/aws-sdk-go/service/cloudwatchlogs""log"
)func main() {// 创建CloudWatch日志客户端sess := session.Must(session.NewSessionWithOptions(session.Options{SharedConfigState: session.SharedConfigEnable,}))svc := cloudwatchlogs.New(sess)// 日志组和流名称logGroupName := "myAppLogs"logStreamName := "appLogStream"// 如果它们不存在,则创建日志组和流svc.CreateLogGroup(&cloudwatchlogs.CreateLogGroupInput{LogGroupName: aws.String(logGroupName), })svc.CreateLogStream(&cloudwatchlogs.CreateLogStreamInput{LogGroupName: aws.String(logGroupName),LogStreamName: aws.String(logStreamName),})// 记录消息logger := log.New(os.Stdout, "", log.LstdFlags) logger.Println("应用程序启动")// 将日志发送到CloudWatch_, err := svc.PutLogEvents(&cloudwatchlogs.PutLogEventsInput{ LogGroupName: aws.String(logGroupName),LogStreamName: aws.String(logStreamName),// 此处添加日志事件})if err != nil {logger.Printf("发送日志时出错:%v\n", err)}
}

关键步骤是:

  1. 使用AWS SDK创建CloudWatch日志客户端。
  2. 如果它们还不存在,则创建日志组和流。
  3. 本地记录消息。
  4. 使用PutLogEvents API调用将日志事件发送到CloudWatch。

这允许将应用程序日志发送到CloudWatch,无需管理文件上传。其他功能,如Kinesis流摄取、报警、保留等,也可以配置。

其他托管日志管理平台,如Datadog、Logz.io、SumoLogic等,也为大型或关键任务系统提供了强大的企业功能。高级分析、可视化、归档功能和基于机器学习的警报规则很常见。它们允许跨本地、云和混合环境集中日志。成本根据引入的数据量而变化。

以下是如何使用其Go库将日志从Go应用程序发送到Datadog的示例:

package mainimport ("github.com/DataDog/datadog-go/statsd"datadog "github.com/DataDog/datadog-go/v5/datadog"
)func main() {// 创建Datadog客户端ddClient, err := datadog.NewClient("<DATADOG_API_KEY>", "<DATADOG_APP_KEY>")if err != nil {log.Fatal(err) }// 创建statsd客户端statsd := statsd.New("127.0.0.1:8125")// 记录一些指标statsd.Gauge("requests.count", 100, []string{"version:1.0"}, 1) // 发送日志ddClient.Logs.Send(&datadog.LogsPayload{Series: []datadog.LogsSeries{{Context: "application",Source: "go",Service: "app",Status: datadog.LogsStatusInfo,Tags: []string{"env:dev"}, Logs: []datadog.LogsMessage{{Message:   "App started",Timestamp: datadog.CurrentEpochTime(),},},},},})}

关键步骤是:

  1. 使用API和应用密钥创建Datadog客户端。
  2. 创建Statsd客户端以获取自定义指标。
  3. 通过客户端将指标和日志发送到Datadog的平台。

这允许从Go应用程序发送指标和日志到Datadog的平台,进行监控和分析。

对于微服务架构,建议使用分布式日志管道。每个应用程序本地记录日志并流式传输到中央聚合器,如Kafka或Fluentd。这避免了中央依赖或瓶颈。Graylog和ELK堆栈等开源选项在这里表现良好。

总之,在选择日志存储解决方案时,评估规模、成本、团队技能和法规要求等因素。从本地文件开始简单,然后根据需要演变为云服务或自我管理平台。这在易用性和强大性之间为系统增长的长期日志管理平衡。

结论:

结构化日志记录代表了日志记录实践的范式转变,提供了增强的可读性、可搜索性和分析能力。通过采用结构化日志记录并利用Slog等工具和日志中间件,开发人员可以简化日志管理,深入洞察应用程序行为,并加快故障排除工作。拥抱结构化日志记录使开发人员能够释放他们日志数据的全部潜力,提升他们的应用程序监控和调试工作流程。

关键点回顾:

  • 结构化日志记录将日志消息组织成标准化格式,提高了可读性和分析性。设置适当的日志级别确保只捕获相关信息,优化了日志清晰度和效率。
  • 使用像Go中的Slog这样的结构化日志记录库可以无缝集成并解锁高级日志记录功能。
  • 上下文日志记录通过添加额外的元数据来丰富日志条目,便于故障排除和根本原因分析。
  • 选择正确的日志存储解决方案取决于可扩展性、可访问性和合规性要求等因素。

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

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

相关文章

浅析扩散模型与图像生成【应用篇】(三)——RDDM

3. Residual Denoising Diffusion Models 该文提出一种残差去噪扩散模型&#xff08;RDDM&#xff09;可用去图像生成和图像修复&#xff08;如去除阴影、去雨、暗光提升等&#xff09;。该文最大的特点是提出一种双扩散模型&#xff0c;在扩散过程中不仅包含噪声 ϵ \epsilon …

Windows WMI详解

WMI简介 WMI ( Windows Management Instrumentation, Windows管理规范)是Windows 2000/XP管理系统的核心&#xff0c;属于管理数据和操作的基础模块。设计WMI的初衷是达到一种通用性&#xff0c;通过WM操作系统、应用程序等来管理本地或者远程资源。它支持分布式组件对象模型(…

select * from 表 c=‘1‘ and b=‘2‘ and a=‘3‘; abc是联合索引,这样查询会命中索引吗?

倒叙也会命中索引 但是要注意&#xff0c;倒叙的时候必须要有a存在&#xff0c;否则就会索引失效 因为mysql底层会有优化器去进行优化&#xff0c;但是如果没有a的话&#xff0c;那么优化器就不知道要优化那个索引了&#xff0c;所以他走了全表&#xff0c;导致索引失效

[MYSQL数据库]--mysql的基础知识

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、数据库…

Redis数据类型--List类型详解及应用

数据结构 Redis无论什么数据类型&#xff0c;存储的时候都是以键值对key-value形势存储&#xff0c;并且所有的key都是String类型&#xff0c;本文讨论的数据类型是value的数据类型。 List类型 概述&#xff1a;list类型可以存储一个有序的字符串列表&#xff0c;为了方便理…

Tomcat服务部署

1、安装jdk、设置环境变量并测试 第一步&#xff1a;安装jdk 在部署 Tomcat 之前必须安装好 jdk&#xff0c;因为 jdk 是 Tomcat 运行的必要环境。 1. #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02. #将安装 Tomcat 所需软件包传到/opt…

备战蓝桥杯Day20 - 堆排序的实现

一、每日一题 蓝桥杯真题之互质数的个数 我的解法&#xff1a; 两个数互质&#xff0c;说明两个数的最大公约数是1&#xff0c;定义了一个函数判断两个数的最大公约数&#xff0c;再在循环中判断&#xff0c;并实现计数。可以实现运行&#xff0c;缺点是时间复杂度很高&#…

javaweb学习(day04-XML)

一、介绍 1 官方文档 地址: https://www.w3school.com.cn/xml/index.asp 2 为什么需要 XML 需求 1 : 两个程序间进行数据通信需求 2 : 给一台服务器&#xff0c;做一个配置文件&#xff0c;当服务器程序启动时&#xff0c;去读取它应当监听的端口号、还有连接数据库的用户名…

【Java程序设计】【C00321】基于Springboot的在线租房和招聘平台(有论文)

基于Springboot的在线租房和招聘平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的在线租房和招聘平台&#xff0c;本系统有管理员、用户、房东以及公司四种角色&#xff1b; 管理员&#xff1a;首页、个人中心…

spring boot集成Elasticsearch 7.16.3

环境&#xff1a;Elasticsearch 版本 7.16.3 Elasticsearch for windows下载地址 windows 若依 spring boot版本 2.6.0 pom文件添加 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch<…

【Kubernetes】K3S

目录 前言一、原理单体架构高可用架构 二、初始化1.配置yum源2.关掉防火墙3.关掉selinux4. 修改内核参数5.关掉swap交换分区 三、安装master节点1. 安装container2.启动master服务 四、安装node节点五、卸载六、总结 前言 各位小伙伴们&#xff0c;大家好&#xff0c;小涛又来…

面试数据库篇(mysql)- 10事务中的隔离性是如何保证

锁:排他锁(如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁mvcc : 多版本并发控制MVCC 全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突 MVCC的具体实现,主要依赖于数据库记录中的隐式字段…

Sui在AIBC Eurasia奖项评选中被评为2024年度最佳区块链解决方案

自2023年主网上线以来&#xff0c;经历了爆炸性增长的Layer1区块链Sui在2月25–27日迪拜举办的第二届AIBC Eurasia活动中获得“2024最佳区块链解决方案奖”&#xff08;Best Real World Application Award 2024&#xff09;。这个盛大的活动以世界级的参与者和往届获奖者而闻名…

mongoose源码解读(二) -- mg_mgr_init 初始化

在用 mongoose 源码开发的时候&#xff0c;这个初始化函数 mg_mgr_init&#xff08;&#xff09;则是必须的&#xff0c;我们看下它到底做了哪些初始化操作。 void mg_mgr_init(struct mg_mgr *m, void *user_data) {struct mg_mgr_init_opts opts;memset(&opts, 0, sizeo…

Leetcode : 移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 思路&#xff1a;遍历数组元素&#xff0c;判定为0&#xff0c;则采用erase从数组删除&…

算法修炼-动态规划之斐波那契数列模型

一、动态规划的算法原理 这是本人动态规划的第一篇文章&#xff0c;所以先阐述一下动态规划的算法原理以及做题步骤。动态规划本人的理解就是通过题目所给的条件正确地填满dp表&#xff08;一段数组&#xff09;。首先要先确定好dp表每个位置的值所代表的含义是什么&#xff0c…

JavaEE——简单认识JavaScript

文章目录 一、简单认识 JavaScript 的组成二、基本的输入输出和简单语法三、变量的使用四、JS 中的动态类型图示解释常见语言的类型形式 五、JS中的数组六、JS 中的函数七、JS 中的对象 一、简单认识 JavaScript 的组成 对于 JavaScript &#xff0c;其中的组成大致分为下面的…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的水果质量识别系统(Python+PySide6界面+训练代码)

摘要&#xff1a;本篇博客详尽介绍了一套基于深度学习的水果质量识别系统及其实现代码。系统采用了尖端的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等前代算法进行了详细的性能对比分析&#xff0c;提供在识别图像、视频、实时视频流和批量文件中水果方面的高效准确性…

【探索AI】探索未来-计算机专业必看的几部电影

计算机专业必看的几部电影 计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;…

【Java程序设计】【C00327】基于Springboot的高校教师教研信息填报系统(有论文)

基于Springboot的高校教师教研信息填报系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校教师教研信息填报系统&#xff0c;本系统有管理员、教研管理以及教研人员三种角色&#xff1b; 管理员&#xff1a…