Go 错误日志处理

是不是所有的 if err != nil 的地方都应该输出错误日志?

打印过多的错误日志会导致日志文件变得冗长和难以阅读。

其次,重复的错误信息会增加冗余。

此外,每一层都打印错误日志,一旦错误信息设计不当,可能会导致上下文信息的丢失。

1、案例

假设我们有一个五层的Go函数调用栈,其中最底层的函数level4Function出现了一个错误 

package mainimport ("fmt""log"
)func main() {if err := topFunction(); err != nil {log.Printf("Error: %v", err)}
}func topFunction() error {err := level1Function()if err != nil {log.Printf("topFunction: %v", err)return err}return nil
}func level1Function() error {err := level2Function()if err != nil {log.Printf("level1Function: %v", err)return err}return nil
}func level2Function() error {err := level3Function()if err != nil {log.Printf("level2Function: %v", err)return err}return nil
}func level3Function() error {err := level4Function()if err != nil {log.Printf("level3Function: %v", err)return err}return nil
}func level4Function() error {err := fmt.Errorf("出了问题")if err != nil {log.Printf("level4Function: %v", err)return err}return nil
}

 每个函数中都输出错误日志并返回错误值

当我们运行程序时,日志文件会出现重复的错误信息,并且上下文信息不易于进行链式追踪,因为每个函数只打印了特定错误的信息,而没有提供之前错误的上下文。 

2. 实践技巧 

 应该只在最顶层的函数中输出错误日志,而在下层函数中返回错误值

package mainimport ("fmt""log"
)func main() {if err := topFunction(); err != nil {log.Printf("Error: %v", err)}
}func topFunction() error {err := level1Function()if err != nil {return fmt.Errorf("topFunction: %w", err)}return nil
}func level1Function() error {err := level2Function()if err != nil {return fmt.Errorf("level1Function: %w", err)}return nil
}func level2Function() error {err := level3Function()if err != nil {return fmt.Errorf("level2Function: %w", err)}return nil
}func level3Function() error {err := level4Function()if err != nil {return fmt.Errorf("level3Function: %w", err)}return nil
}func level4Function() error {err := fmt.Errorf("出现了问题")if err != nil {return fmt.Errorf("level4Function: %w", err)}return nil
}

3、总结

在编写Go代码时,请记住要么返回错误值,要么输出日志,不要两者都做。通过合理地处理错误,我们可以编写出更可靠、更易于调试的代码。

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

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

相关文章

消费者相关高效读写ZK作用

消费者分区分配策略 目录概述需求: 设计思路1.消费者分区分配策略2. 消费者offset的存储3. kafka消费者组案例4. kafka高效读写&Zk作用5. Ranger分区再分析 实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show …

MySQL建库

删除数据库 新建数据库 右键-新建数据库 字符集选中utf8(支持中文) 修改字符集 右键--数据库的属性 将字符集支持的数量变少可以修改

vue3 部署后修改配置文件

前端项目部署之后,运维可以自行修改配置文件里的接口IP,达到无需再次打包就可以使用的效果 vue2如何修改请看vue 部署后修改配置文件(接口IP)_vue部署后修改配置文件-CSDN博客 使用前提: vite搭建的vue3项目 使用setu…

大数据技术分享 | Kylin入门系列:基础介绍篇

Kylin入门教程 在大数据时代,如何高效地处理和分析海量数据成为了企业面临的挑战之一。Apache Kylin作为一个开源的分布式分析引擎,提供了Hadoop之上的SQL查询接口及多维分析(OLAP)能力,使得对超大规模数据集的分析变…

【leetcode——栈的题目】——1003. 检查替换后的词是否有效python

题目: 给你一个字符串 s ,请你判断它是否 有效 。 字符串 s 有效 需要满足:假设开始有一个空字符串 t "" ,你可以执行 任意次 下述操作将 t 转换为 s : 将字符串 "abc" 插入到 t 中的任意位置…

前缀和(下)

目录 热身: 寻找数组的中心下标 题解: 代码: 进阶: 除自身之外数组的乘积 题解: 代码: 和为K的子数组 题解: 代码: 和可被 K 整除的子数组 题解: 同余定理…

Python多进程加快for循环速度

Python多进程加快for循环速度 你可以使用Python的multiprocessing模块来将for循环改为多进程实现。下面是一个简单的示例代码,演示了如何使用multiprocessing.Pool来并行执行一个for循环: import multiprocessing# 定义一个函数,该函数会在…

C语言 指针——指针变量做函数参数

目录 指针变量的解引用 为什么要用指针变量做函数参数? 演示Call by value 指针变量的解引用 为什么要用指针变量做函数参数? 演示Call by value

本特利330130-040-01-00 PLC模块深度解析 询价联系ID

本特利330130-040-01-00 PLC模块深度解析 在工业自动化领域,准确、高效的数据采集和监控是确保生产安全、提高生产效率的关键。本特利(Bently Nevada)作为全球知名的工业自动化和监控设备制造商,其生产的330130-040-01-00 PLC模块…

半藏酒业新零售分红制度拆解,起盘运营服务商

半藏酱酒招商模式,白酒合伙人模式,顶层模式设计 社群玩法用这几年的互联网词汇描述叫私域营销。虽然不走传统商超,酒桌之外很少能看到,但随着核心消费者裂变和流量汇聚,现在能见度越来越高,并溢出到达公域。…

Jtti:怎么在香港服务器上实现多点备份?

在香港服务器上实现多点备份可以采用多种方法和工具,主要目标是将数据备份到不同的存储位置,以增加数据的安全性和可靠性。以下是实现多点备份的一些常用方法: 1. 使用云存储服务 利用云存储服务将数据备份到不同的云存储提供商,以…

2024黑龙江CCPC

2024黑龙江省赛 B. String 思路:栈模拟代码&#xff1a; /* * Author: Hfuubigstrength * email: 2854614012qq.com * Date: 2024-05-28 23:32:45 */ #include <bits/stdc.h> //#define int long long #define PII pair<int,int> #define LL long long #defi…

深度学习:手撕 RNN(2)-RNN 的常见模型架构

本文首次发表于知乎&#xff0c;欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后&#xff0c;就像搭积木一样&#xff0c;以 RNN 为基本单元&#xff0c;根据不同的任务或者需求&#xff0c;可以构建不同的模型架构。本节介绍的所有结构&#…

JS移动端设置mouseover,mouseleave有效么

在移动设备的浏览器环境中&#xff0c;mouseover 和 mouseleave 事件的行为与桌面浏览器有所不同&#xff0c;主要是因为移动设备的交互方式主要是基于触摸的&#xff0c;而不是基于鼠标的。 在移动设备上&#xff0c;当用户触摸屏幕时&#xff0c;通常会触发 touchstart 事件…

mysql查询的时间复杂度

SELECT * FROM customers WHERE age > 25; 首先是普通的select&#xff0c;如果没有建立任何的索引的话&#xff0c;假设数据量为N&#xff0c;那么时间复杂度为O(N) 如果对age添加了索引&#xff0c;那么复杂度为O(log n) 假设使用了in操作&#xff0c;总共查找M种&…

Codeforces Round 947 (Div. 1 + Div. 2) D. Paint the Tree 题解 DFS

Paint the Tree 题目描述 378QAQ has a tree with n n n vertices. Initially, all vertices are white. There are two chess pieces called P A P_A PA​ and P B P_B PB​ on the tree. P A P_A PA​ and P B P_B PB​ are initially located on vertices a a a an…

Spring Boot与MongoDB集成指南

1. 引言 在当今快速发展的软件开发领域&#xff0c;选择合适的技术栈对于构建高效、可扩展的应用程序至关重要。随着微服务架构和云原生应用的兴起&#xff0c;开发人员需要更灵活、更快速的解决方案来满足不断变化的业务需求。Spring Boot和MongoDB的结合正是这一需求的完美答…

运维开发.MySQL.范式与反范式化

运维开发 MySQL.三大范式 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/artic…

jest测试

文章目录 测试testexpecttoThrow asyncPromiseAsync/Await 作用域一次性设置 beforeAll and afterAll重复设置 beforeEach 和 afterEachdescribe 块 mockcli配置覆盖率测试报告 测试 test test(name, () > {function} }expect () > {expect(期望value).toBe(匹配value…

python海龟绘图(你的作业说不定就在这里)

三角形 from turtle import * for i in range(3):forward(100)left(120)基本绘图​​​​​ 让海龟前进 100 步: forward(100)你应该会看到&#xff08;最可能的情况&#xff0c;是在你的显示器的一个新窗口中&#xff09;海龟画出一条线段&#xff0c;方向朝东。 改变海龟的…