0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

感觉学会log,程序就算入门了

STM32嵌入式开发 来源:STM32嵌入式开发 2023-08-02 16:39 次阅读
本文适用范围:Linux系统使用语言:C/C++

打log的原则

  • 异常分支或错误处理一定要打log
  • 重大操作时一定要打log,下面打log场景会讲述

log格式的原则

1、时间戳必须有,最好能够精确到微秒精确到秒的时间戳,相信很多人都熟悉,这能够确认问题的时间和系统uptime的对比,能够进一步还原问题的场景。至于到微秒,在多线程程序下,如果进程停止响应,可以从日志时间看是否死锁。

一般格式:

[2017-01-09 12:16:30.541]
2、打log位置的文件名和代码行数这个不用说,用于定位问题根源。其实最重要是防止扯皮。因为程序员大多喜欢copy-paste,如果你不加文件名和行数,某程序员copy了你的代码,修改了点,出错了,到时候把你拉下水。

一般格式:

[2017-01-09 12:16:30.541][network.c:541]

		3、有进程id有些log机制在进程重启时,不会重新生成一个日志文件,而是直接在同一个日志文件后面添加日志。或者,有时候同一程序的多个进程同时运行,可能也会写入到同一个日志文件。

一般格式:

[2017-01-09 12:16:30.541][network.c:541][pid=15529]

		4、有线程id在多线程程序,如果不加线程id,很难追溯程序的行为。

一般格式:


		
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345]

		5、有日志的级别日志是反映问题的,有不同紧急程序的问题,自然有不同的日志级别。一般采用Error,Warning,Info,Debug。定义不同级别,也可以方便在日志查找问题来源。

一般格式:


		
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345][Error]

		打log的场景1、申请内存时,失败的话,要把申请大小打印出来

以前我申请内存失败也是简单地打印:


		
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345][Error]Failedtoallocatememory

		后来在重构时遇到一个问题:进程跑的时间一久,大概一天多,别的程序向它发消息都会收到失败响应,在日志里就是一大堆内存失败的消息"Failed to allocate memory"。

用"free"命令来看,物理内存还有好几G空闲,而用“top”命令来看,该进程也只是占700M内存。当时我就怀疑是不是内存碎片导致。于是我把申请内存的大小也打印出来,就收到一堆这样的:


		
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345][Error]Failed to allocate memory of size 65536
[2017-01-09 12:16:30.588][network.c:541][pid=15529][thread=0x12345][Error]Failedtoallocatememoryofsize1048576

		当时就看那些代码引用的数据结构,最小也有64K,大的16M都有,基本一个结构包括很多个大数组。当时就把那些数组全改为指针,再进一步申请,代码繁琐了,但这种问题再也不会出现。再看bug系统,原来这个问题存在很多,在其它程序也存在,当时都找不到根因,只是用过一段时间重启进程来解决2、 函数参数非空判断时,要打印日志原因不说,看对比:

之前:

if ( ( pInfo == NULL ) || ( pHandler == NULL ) ) 
{
    log( ERROR, "invalid arguments" );
}

		

之后:

if ( ( pInfo == NULL ) || ( pHandler == NULL ) ) 
{
    log( ERROR, "invalid arguments:(pInfo, pHandler )=(%p,%p)", 
            pInfo, pHandler );
}

		3、加载和卸载模块,无论是正常还是异常情况都要打印

毕竟这些操作大多都是一次性操作。对性能影响不大。


		
[2017-01-09 12:16:30.588][modules.c:54][pid=15529][thread=0x12345][Error]Failedtoloadmodulelibftp.so,error=modulealreadyloaded

		4、操作文件目录时,失败要把文件名和错误码打印出来

如:


		
[2017-01-09 12:16:30.588][config.c:120][pid=15529][thread=0x12345][Error]Failedtoopenfileconf/ftp.xml,errno=(13:Permissiondenied)

		假设这个错误导致进程初始化失败,且环境在客户那边,维护人员就可以确认并自己解决这个问题。5、操作socket时,把IP,端口号或路径名(Unix socket )和错误码打印出来

如:


		
[2017-01-09 12:16:30.588][network.c:541][pid=15529][thread=0x12345][Error]Failedtoconnecttohost(10.17.128.10:9981),errno=(111:Connectionrefused)

		假设在客户环境出错,维护人员可以根据日志来确认10.17.128.10这台机器是否在线,是否开启了相应的服务,或者服务是开启了,可能只是端口配置错了(这种情况是扯皮最多的)6、操作数据库时,把相应操作的IP,端口,库,用户名,sql语句和错误打印出来

如:

[2017-01-09 12:16:30.588][dbmgr.c:781][pid=15529][thread=0x12345][Error]user tiger failed to operate in host (10.17.128.10:3365) with db test, sql="select * from users", error="no table users exists"
在客户环境下,维护人员可以通过命令行来验证这些问题,来确定问题。可能有人会考虑安全性,毕竟在日志中把IP,端口,库,用户名都暴露出来了,这样好像不妥。但如果是从事过通信行业的网上问题维护,就知道,可维护性比这种细节的安全性还要重要。7、创建新进程时,需要把程序名,参数和错误码打印出来

如:


		
[2017-01-09 12:16:30.588][process.c:154][pid=15529][thread=0x12345][Error]failed to execute program "iptables -L", errno=(2:No such file or directory)
往往在客户环境,由于运维人员水平参差不齐,可能误操作或漏操作,导致文件缺失或权限出错,这种错误在公司模拟环境根本不会出现。如果日志够详细,能够减少很多工作量。8、解析文件时,需要把文件名,字段,行号打印出来

如:

[2017-01-09 12:16:30.588][config.c:120][pid=15529][thread=0x12345][Error]Failed to parse file conf/ftp.xml, line:20, tag <host> is not closed
结语上面的原则,基本是每一条是血的教训。以前在H时见得太多因为日志不全导致的麻烦,前方的客户经理不断向客户恳求宽限时间,维护人员不断地在客户环境找出蛛丝马迹,后方领导也不断地调配资源来跟踪问题,后方测试人员不断地测试,尝试问题复现,后方开发人员就不断地看代码。在Z也见过因为日志不全,导致被客户罚钱次数过多,整个产品都亏损了。像?@帝都铁匠 说的“感觉学会log,程序就算入门了”。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    116

    文章

    3779

    浏览量

    80896
  • Log
    Log
    +关注

    关注

    0

    文章

    14

    浏览量

    11315
  • 线程
    +关注

    关注

    0

    文章

    504

    浏览量

    19660

原文标题:感觉学会log,程序就算入门了

文章出处:【微信号:c-stm32,微信公众号:STM32嵌入式开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA入门容易,关键是怎么进阶!

    本帖最后由 hughqfb 于 2013-1-19 17:34 编辑 FPGA总算入门,但接下来的学习疲软心理让我十分的懊恼。为什么我发现自己学习到一定程度后就不愿意学习呢?当时学习
    发表于 01-19 17:23

    教大家如何看懂电路图

    本帖最后由 wpf1633 于 2013-12-3 00:09 编辑 本附件适合初学者,包含各个电子元件的符号,以及一些最基本的电路图,弄懂这些电路,你就算入门
    发表于 12-03 00:06

    讨论labview如何算入门

    labview 和其他编程语言一样,(最起码都是编程语言)那么怎么才算入门入门之后怎么去有效率的研究学习呢?当然学无止境,但是 学要有方法,欢迎过来人指点迷津。
    发表于 12-07 08:50

    总结大佬经验,如何学习STM32?(入门、进阶)

    之内的不会的可以查资料,但是一定要要有自己的思想,完成了我觉得就算入门。------Llinuxu六、关于初学者是否要弄懂底层函数 初学者没必要弄懂底层函数。项目需要用到什么再去研究什么。比如你的项目
    发表于 06-10 09:15

    单片机开发怎么才算入门

    记得开始学单片机的时候,也很想知道自己到底学的怎样,到了什么水平,到处问人单片机开发怎么才算入门,最后老师跟我说:能做一个万年历出来就算入门
    发表于 01-19 06:27

    轻松入门开发ARM程序

    轻松入门开发ARM 程序(为初学者写的入门手册) 应该说,入门学会开发ST ARM 应用程序
    发表于 09-09 14:35 5次下载
    轻松<b class='flag-5'>入门</b>开发ARM<b class='flag-5'>程序</b>

    轻松入门开发ARM程序

    很多朋友都想自己动手开发ARM 应用程序,却不知从哪儿下手。我们编写本手册的目的就是想帮助这些初学者轻松的入门。应该说,入门学会开发ST ARM 应用
    发表于 01-19 22:20 31次下载

    云计算入门指南

    云计算入门指南:Sun 公司云计算技术可顺利地扩展您的基础设施,以抓住新的商业机会。 云计算在许多方面只是互联网的一个比喻词,亦即计算和数据资源日益迁移到 Web
    发表于 02-10 09:50 0次下载

    LOG112,LOG2112,pdf(Precision Logarithmic and Log Ratio Ampli

    The LOG112 and LOG2112 are versatile integrated circuits that compute the logarithm or log ratio
    发表于 09-26 01:10 38次下载

    LOG101/LOG104偏流调零电路

    LOG101/LOG104偏流调零电路 如图所示为LOG101/LOG104的偏流调零电路。 LOG101/
    发表于 05-13 16:10 1536次阅读
    <b class='flag-5'>LOG</b>101/<b class='flag-5'>LOG</b>104偏流调零电路

    模拟电路怎样才算入门

    模拟电子的相关知识学习教材资料——模拟电路怎样才算入门
    发表于 09-20 16:10 0次下载

    通信原理易入门 上手 轻松学会现代通信原理

    通信原理易入门 上手 轻松学会现代通信原理
    发表于 09-04 14:36 37次下载
    通信原理易<b class='flag-5'>入门</b> 上手 轻松<b class='flag-5'>学会</b>现代通信原理

    如何让应用程序感觉更快

    好的设计实际上可以让时间加快! ......好吧......不,不是真的,但是Luke W确实分享一些非常聪明的设计技巧,让你的应用程序感觉更快 - 令人着迷
    的头像 发表于 11-13 06:17 1895次阅读

    基于Rust的Log日志库介绍

    Rust是一门系统级编程语言,因其安全性、高性能和并发性而备受欢迎。在Rust应用程序中,日志记录是一项非常重要的任务,因为它可以帮助开发人员了解应用程序的运行情况并解决问题。Rust的Log库提供
    的头像 发表于 09-19 14:49 3431次阅读

    Log4cpp优势及优点

    1、log4cpp概述 Log4cpp是一个开源的C++类库,它提供C++程序中使用日志和跟踪调试的功能,它的优点如下: 提供应用程序运行
    的头像 发表于 11-09 14:27 679次阅读
    <b class='flag-5'>Log</b>4cpp优势及优点