写日志

程序运行,写日志文件功能c++代码实现 很多程序运行时,容易出现这样那样的错误,为了方便查找错误,在程序运行过程中,每进行一次操作就记录日志是最简单有效的方法。本代码以c语言实现写日志的功能,封装成了函数,可直接放到工程中,进行调用。 立即下载

为什么记日志

日志记录是否完备,直接影响到软件产品维护和问题定位的难易程度。这主要源自以下几个因素:

第一、开发人员自己的环境无法覆盖100%的应用场景,某项功能在开发者的机器上一切正常,但是到了测试人员或用户的机器上就不能满足预期。

第二、当在用户现场出现问题时,往往无法再单步调试。如果要到用户现场架设一套开发环境成本太高。

第三、有些问题存在一定概率,并不能100%复现。而日志可以记录系统运行的行为,帮助分析问题。

因此,记录有效的日志对于一款成熟的软件产品而言不可或缺。一个优秀的软件设计师可以通过日志来分析定位问题,而一个普通的开发人员往往要依赖IDE的单步调试功能。

当然,每一个开发人员的学习过程几乎都是从单独调试开始的,它能让程序“慢”下来,让你清楚程序每一步的行为,能方便的查看系统中每一个状态。这当然是一种最方便直接的方法,也让开发人员对此产生了很大的依赖。但是在真实应用场景中,当程序的行为不符合预期时,我们无法通过这种方法去分析问题。日志就成为了一个有效的辅助手段。

另外单步调试在某些多线程的系统中往往会带来另外一些问题。你也许碰到过程序在单步调试时的运行结果和正常运行结果不一致,令人一头雾水。这主要时因为单步调试的引入破坏了系统的正常运行流程。断点只是让一个线程停了下来,而系统中的其它线程还照样在正常运行,此时的被测系统已经不是“正常状态”下的那个系统了。

再补充一点,在系统异常的大部分情况下,我不太赞成使用断言(assert)。因为断言会让系统停止运行,用户点击“确定”后还得重新运行系统,这样的体验很糟糕。而我们的软件需要在大部分异常场景进行容错或者自愈,以便系统能够继续运行,完成用户的预期要求。实际上日志和断言是异常处理的两个有效手段,它们各有所用,断言主要用在“不可能”出错的地方,这将在“代码看护”一节中进行讨论。

日志框架

物理学的测量体系中有一个基本原则:测量方法的引入不能对被测系统造成影响。比如我们可以用一根竹竿去测量一个游泳池中水的深度:把竹竿垂直插入水中并触及池底,然后再取出竹竿量一下其被水浸湿部分的长度。但是我们却不能用竹竿去测量一个玻璃杯中的水的深度。当竹竿插入玻璃杯时,竹竿本身对玻璃杯里的水会造成很大影响,会导致水面明显上升。而竹竿对游泳池中的水影响就可以忽略。

在软件系统中记录日志时,同样需要遵循此原则。本章中列举的日志框架会在每一次调用日志接口时将日志信息保存到硬盘上的一个日志文件中。在写文件时会有一次磁盘I/O,这个方法对于大多数应用场景不会造成太大影响。但如果你的系统对实时性要求很高,或者工作在系统内核层,那么就要充分评估这类磁盘I/O对系统带来的影响。也许需要考虑其它方法,比如只是将日志信息保存在内存块中,而不是将其写入磁盘文件。当然,如果你的系统中已经有了自己的日志框架,那么请忽略以下内容。

该框架是基于C++开发的,只有两个文件:Log.cpp和Log.h,可以在附件中进行下载(LodDemeo.rar提供了一个vs2008的demo工程),然后加入到你的工程中。其提供了两个日志接口logstr和logmem,前者用于记录一个字符串信息,用法和C语言的printf类似,可以支持若干个参数;后者则用于将一段内存信息打印为二进制码流的形式。

由于使用了C/C++宏__FILE__和__LINE__,在输出日志时可以同时打印出该行代码所在的文件名和行号,这样对于分析问题会带来很大的方便。比如OpSystem.cpp的第355行有一行写日志的代码:

logstr(“MyData = %d”, GetMyData() );

对应的日志文件中内容将是这样(在日志txt文件中):

FILE:.\OpSystem.cpp

LINE:355

MyData = 1

很直观的把日志和对应的代码关联起来,方便问题定位。

对于JAVA开发者,JAVA框架也提供了相应的日志功能。比如Andriod系统中的android.util.Log包就提供了这类日志接口,你只需要定义好系统的标签,方便日志过滤:

Log.e(“MySystem”, logContent);

如何记日志

日志不能太多也不能太少。这听起来像是一句废话,但的确如此L。

日志太多的话会导致很多无效的信息,影响有效信息的获取。比如在一个执行频率很高的地方输出日志,有时甚至会很快把日志文件写满;日志太少的话缺乏足够的定位信息导致问题无法准确定位。

在所有要求对“度”进行把握的地方,往往总是要更多的依赖经验。你也许会常碰到类似的问题:在分析日志的过程中需要知道某个变的值,却发现日志中没有对该变量进行记录,令人沮丧。这种时候往往只能再添加日志,重新出新的临时版本到用户现场再次运行并进行定位。

如果你平时主要是依赖断点调试程序,当断点走到某处代码时,你可以很容易的就查看其中的变量,很容易的知道程序执行的轨迹。因此往往忽略了对关键信息进行日志记录的重要性。针对这种情况,你需要常常提醒自己:如果程序在这里运行失败了,我需要哪些信息才能足以分析失败的原因?然后把相应的信息记录到日志中。当然要做好这一点还是取决于你的经验,但只要你在日常编码时养成这样的习惯,情况就会向好的方向发展。

另一个办法来自日常的工作方式。当测试人员向你提交问题时,不要先急于在自己的环境上复现并定位问题。而是先尝试在测试人员的环境上通过日志进行定位。如果发现这样无法定位问题时,你就能知道是哪些日志信息不足,然后进行相应的补充。

除此之外,平时写代码时还有需要注意以下几点:

l  在错误分支增加日志

当用户点击一个按钮开始执行某个流程时,如果程序能正确的执行完成,并输出预期的结果,那么一切表现良好。但是如果程序出错并给用户弹出一个执行失败的窗口时,问题就随之而来了。在哪里失败?为何失败?如何修复?……当你打开代码开始查看时,会发现异常分支有很多个,如果没有日志的话,很难判断是哪一个分支出的问题。

一个函数的执行过程很长,当函数返回失败时,如果不能知道具体是哪一个分支失败,那么后续的问题分析就无法再继续了。因此如果能在每一个错误分支都增加日志,那当函数执行失败时,日志能够准确的告诉你失败在哪。

l  在程序运行的关键节点增加日志

程序80%的问题出在接口上,因此在模块的入口和出口和处增加日志,并记录足够的信息,这样能记录整个程序的执行流程,方便问题定位。
COCO数据集缺失文件补全方法 本文代码是以目标检测(object detection)和实例分割(instance segmentation)任务的标签文件为例,即文件。其他任务的标签文件内容略有不同,但是图片来源表示字段完全相同,因此代码可通用。另外如果是非2017版本COCO应该也通用。msgspec是一个高性能的序列化和验证库,支持 JSON、MessagePack、YAML 和 TOML 等多种格式。高性能:在常见协议的编码/解码中表现出色,通常比其他库快10-80倍。零成本的模式验证。 阅读详情

相关推荐

Computer Networks 和 Computer & Security投稿经验

论文投稿

qq_50604294的博客 9229

【JAVA开发规范】日志规范

写好代码很重要,日记记录也非常重要。我们可以通过日志记录代码的执行流程、运行状态、关键指标。

会飞的架狗师的博客 2497

本地如何安装midscene.js运行环境

手把手教你本地安装midscene.js运行环境

实践助梦想成长 2607

程序员该怎么写日志

撰写日志

河海大学研究生在读的学习笔记 3353

告别理论!用AXI-Stream实战摄像头数据流采集(附Verilog关键代码片段)

本文详细解析了如何通过AXI-Stream接口实现工业级可靠性的摄像头数据流采集系统,重点介绍了Verilog实战代码、AXI-Stream握手机制及数据反压处理方案。通过三级缓冲架构和带宽优化,有效解决了OV5640等摄像头在高速场景下的帧丢失问题,为FPGA图像处理项目提供了实用解决方案。

weixin_42563415的博客 157

告别环境报错:Qt Creator里配置Android SDK/NDK/JDK路径的完整避坑指南

本文详细解析了在Qt Creator中配置Android SDK/NDK/JDK路径的完整避坑指南,深入探讨了路径检测的内部机制、构建套件配置的隐藏逻辑以及项目级与全局配置的优先级。通过实际案例和高级排查技巧,帮助开发者解决常见的环境报错问题,提升Qt安卓开发效率。

weixin_42548829的博客 238

软件开发为什么写日志,怎样写日志,什么时候写日志?

因此,最佳写日志的时机是在开发功能代码时,这样能够确保日志覆盖关键的业务流转和异常处理,提高系统运维的效率和准确性。软件存在的目的是为了解决问题,作为工程的一部分,我们不仅需要关注软件开发(包括编码注释和文档),还应该关注软件的运维,即日志记录。没有任何软件是完美无瑕的,软件部署后一旦出现问题,如果没有适当的日志记录,我们将无法了解系统运行状态,从而难以解决问题。我们应当能够通过详尽的日志文件,复原程序的全部执行过程,详细到每个线程和每个操作的层面。:在算法或业务逻辑中的关键决策点,记录决策的依据和结果。

m0_65635427的博客 4434

振动能量采集技术:从原理到实战,破解物联网供电难题

能量采集技术旨在捕获环境中的废弃能量(如机械振动、热能、光能)并将其转化为电能,其核心原理在于通过压电、电磁、静电或摩擦电等物理效应实现能量形式的转换。这项技术的核心价值在于为物联网(IoT)中难以布线或更换电池的分布式传感器节点、植入式医疗设备等提供近乎永续的电力解决方案,从而解决物联网部署的“最后一米供电”瓶颈。其应用场景广泛覆盖工业预测性维护、结构健康监测、可穿戴设备及消费电子等领域。本文聚焦于振动能量采集这一细分方向,深入剖析了压电式、电磁式、电容式及摩擦纳米发电机(TENG)等主流技术路线的实战考

weixin_42660494的博客 565

写给开发者:记录日志的10个建议

http://blog.jobbole.com/52018/ 欢迎在新的一年来到我的博客。在一个巴黎devops maillist上回复了一个关于监控和日志监控之后,我想起了很久以前我的一个博客计划。 尽管在写这篇博文的时候,我是在负责运维工作,不过本文主要是写给开发者的。 对我来说,明白如何记录日志和记录什么,是软件工程师必须明了的最艰巨的任务之一。之所以这么说,是因为这项任务与预测(di...

weixin_34075551的博客 397

【若依(ruoyi)】BootstrapTable列宽定制实战:突破width属性限制的两种方案

本文针对若依(RuoYi)框架中BootstrapTable组件列宽设置失效的常见问题,提供了两种实战解决方案。通过CSS样式覆盖法强制定义列宽,或利用formatter函数进行动态HTML包裹,有效突破width属性限制,实现精准的表格列宽定制。

weixin_29013129的博客 174

Windows Docker + RK3588 部署 YOLO26-Pose 人体姿态检测

YOLO26-Pose 在 RK3588 上的部署流程是 Windows Docker 容器内 ONNX 导出 → RKNN 转换(INT8 量化)→ ADB 推送 → 板端 C++ 推理。YOLO26n-Pose 在 640 输入下全链路约 55 FPS,可以覆盖实时姿态检测需求。先在板端用单张图片验证关键点输出正确性,确认 C++ 后处理的解析逻辑无误后,再切换到摄像头实时推理。

m0_64661770的博客 98

再也不怕周报和日报了-一张表说清楚

导读: 程序员开发时间越久,跟文档打交道的时间越长,需要记忆的东西就越多。每到写周总结的时候,已经忘记本周做了哪些工作,为了防止这种情况,强烈建议养成日志习惯!工作日志的内容不限,可参考下面的模板 计划 当天的工作计划 ,具体到可以完成的一个很小的任务 学习 工作中接触的新内容,需要学习的地方,记录下来,及时充电 工作 实际完成的工作内容,周报主要参照内容 其他 包括会议,考勤,搬位置...

Murphy的博客 1万+

【原理图PCB专题】Cadence 17.4版本原理图及PCB 模块复用

在我们设计复杂板卡的时候,往往会遇到一部分电路被反复使用的情况。Cadence允许设计者一开始就将复用模块设计好,以后只要直接调用复用模块就可以直接用以设计更复杂的电路板了。这对于大规模集成设计无疑是非常好的选择,它不仅让设计者不必花费时间在相同模块反复设计上,更有利于电路的模块化设计。

一点硬件 2016

PHP写日志

PHP写日志 1、调用类: <?php public function logAction(){ $time = time(); $dir = APP_PATH.'/data/share/test/'; $filename...

夏已微凉、 2237

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Log4j2写日志的艺术

Log4j2中的组件 从配置开始 API基本使用 小细节 写日志的原理 主要流程 同步写 异步写 顺便说一下ArrayBlockingQueue notFull 与 notEmpty 异步写是怎么玩的 巧妙的异步写设计 ByteBuffer与RandomAccessFile Garbage-free避免创建多余对象 异步Logger 性能 写在最后 在程序的世界里,抽象让人像是雾里看花。抽象让程

Schelor的专栏 5550

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Web客户端写日志javascript组件

在java web开发中,在服务端我们比较常用Log4j来进行写日志的控制,而在客户却多用alert来将中间的结果show出来,十分不方便,为此,我整理了一个在客户端通过javascript来进行写日志脚本,其使用方式与Log4j相似.1.javascript写日志组件脚本,可将其放在一个js文件中,如:clientlog.js,其代码如下:/** * write log at web clien

felore的专栏 4026

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

有为了积分写日志

honglove8的专栏 267

用CStdioFile写程序日志

用CStdioFile写程序日志假定日志保存在应用程序目录下,文件名为logfile.log调用下面的函数获得当前应用程序的目录,/* *//* Function name : GetAppDir */ /* Description : Get application directory. *//* *//**********************************************

qmimi的专栏 2110

MFC 写日志

个人自用写日志文件

qq_39047503的博客 308

python如何写日志_python写日志

导读热词写日志的办法多种多样,我这个是我喜欢的办法,可以做个参考没啥说的,直接上代码def write_log(value):now_time = time.time() #获取当前日期和时间time_format = '%Y-%m-%d %H:%M:%S' #指定日期和时间格式time_put = time.strftime(time_format,now_time) #格式化时间,时间变成YY...

weixin_29207149的博客 1450

小议 MySQL 的写前日志与 Redis 的写后日志

写前日志(Write-Ahead Logging, WAL)是一种先记录日志再更新数据的机制。在对数据进行修改之前,先将修改操作记录到日志中,以便在系统崩溃时通过日志恢复数据。写后日志(Write-Behind Logging, AOF)是一种先更新数据再记录日志的机制。在对数据进行修改后,将操作记录到日志中,以便在系统崩溃时通过日志重放恢复数据。MySQL 的写前日志(WAL)和 Redis 的写后日志(AOF)是两种经典的日志机制,它们分别在一致性和性能之间做出了不同的权衡。

【欢迎关注公众号:冬瓜白】 1397

用 live write 写日志了

   呵呵,可以用live write 写日志了,羡慕吧

木木的专栏 375

oracle停写日志的写法

这边有ORACLE里 做法, 参考一下 停写日志: alter database noarchiverlog恢复写日志: alter database archiverlog都是针对当前资料库.

foreveryday007's BLOG 1439

一个简单的c++写日志类

在开发当中有的直接调试很方便,有的就不太好调试,所以我经常使用写日志以及输出Debug信息来进行开发。尽管我比较喜欢使用以输出Debug的信息的方式来跟踪程序。因为直接一句话: OutputDebugString("你想输出的信息\r\n"); 就可以在非调试模式下直接在DebugView上面显示输出信息了。 但是除了这种方式之外有时侯我也会使用写日志的方式来输出调试信息,虽然写文件很简单,但还是记录一下吧。方便自己同时也可能方便需要的人吧。 首先是main()函数定义: .

huang714的专栏 543

写日志的那些事儿

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34059951的博客 288

多线程程序写日志时遇到加锁的问题

前段时间在做项目时,系统是个多线程程序,几个线程都需要写日志,主线程和通讯线程经常在写日志时打架,为了解决这个问题,考虑在写日志的方法中加锁。代码如下:    /// <summary> /// 写日志时加锁 /// </summary> private static object m_Lock = new object...

weixin_34384915的博客 404
上一篇: 关于软件工程的类比
下一篇: 用表驱动消除冗余代码
林 文
博客等级 码龄18年 14粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值