文件操作之日志文件

2023-10-27

一、前言

用户:“那谁,你的程序出问题了,来看看。”。
你:“问题是怎么出现的”。(为了复现)
用户:“我也不知道,就这样点点点就出问题了。”。
你:“。。。”。

这个时候,日志文件的重要性就凸显出来了。
别指望用户能描述清楚问题出现的经过,最靠谱的还是看日志文件。

二、多说两句

2.1、日志文件是分等级的。一般为:调试、警告、错误。
调试级别是在程序开发阶段打的,信息内容啰哩啰嗦,好吧,是很详细,基本记录了程序内部各接口的调用顺序,重要数据值。
警告级别一般是记录一些不重要的错误提示,这些错误不致命(重启程序后,它又活了),或当时不影响使用,过后就不敢保证程序死不死。
错误级别一般打印的是bug!!!对,就是bug。是由程序本身设计缺陷导致的问题。
在软件打包发布时,一般会把日志级别调到警告。这样,调试信息就不会记录到文件。一是记录的东西多了,怕硬盘占满。试想一个运行了一个月的服务器,他的调试记录得有多少个G,怕整个硬盘都要记满吧。二是软件都到发布阶段了,一般的问题都解决了,调试信息都不怎么重要了。

2.2、日志文件应该有专门的目录
写日志时应该为日志文件创建一个目录,存放所有日志文件。使用到的函数:

//判断路径是否存在
PathIsDirectory(char* path);

//创建文件夹,第二个参数是文件夹属性,null,使用默认属性。
CreateDirectory(char* path, nullptr);

2.3 日志文件名最好体现出日期
特别是服务器,连续运行几个月是标配。如果所有日志信息写在一个文件夹里,嘿嘿,几十万行的信息,头都会大。还有就是,若2018/8/26程序崩了,就能通过文件名中的日期信息直接定位到某个文件。
创建文件名我使用fstream::open

	string sday = getTimeForDay();  //这是我写的一个功能函数,返回2018826
	m_file.open(LOG_DIR + string("\\") + sday + ".txt", fstream::out | fstream::app);
	m_day = sday;  //记录文件创建日期,想想程序运行到第二天,
	               //就可以通过它创建新的文件了

2.4 日志文件写入方便
最好是能这样写入,log(“小编是一个傻逼, ID:%d”, 666);
这类似与sprintf(char* buff, char* fmt, …)
我就要参照它了,在vs中右键sprintf(),看它的实现代码,就可以移植了。

void log(char* fmt, ...)
{
	char buffer[1024] = {0};
	
	va_list args;
	va_start(args, fmt);
	vsprintf_s(buffer, fmt, args);
	va_end(args);
	
	//buferr就是你的菜
}

三、撸代码

撸啊撸啊撸代码_

FileLog.h

#pragma once

#include <string>
#include <fstream>
using namespace std;

class FileLog
{
public:
	enum eLevel { INFO, WARN, ERROR };

	FileLog();
	~FileLog();

	void setLevel(eLevel lvl);

	inline void log(eLevel lvl, const char* fmt, ...);

private:
	void createDir();
	void openFile();
	void closeFile();

private:
	eLevel		m_level;
	fstream		m_file;		//文件句柄
	string		m_day;		//日志记录日期
	string		m_levelText[3];	//等级文本信息
};

FileLog.cpp

#include "FileLog.h"
#include <shlwapi.h>
#include "../function/Time.h"

#pragma comment(lib, "shlwapi.lib") 

#define LOG_LEN    1024		//单条日志长度限制
#define LOG_DIR    "Log"	//日志目录

FileLog::FileLog()
	: m_day("")
	, m_level(FileLog::INFO)
{
	m_levelText[0] = "<INFO>";
	m_levelText[1] = "<WARN>";
	m_levelText[2] = "<ERR >";

	createDir();
}

FileLog::~FileLog()
{
	closeFile();
}

void FileLog::setLevel(eLevel lvl)
{
	m_level = lvl;
}

void FileLog::log(eLevel lvl, const char* fmt, ...)
{
	if (lvl >= m_level)
	{
		if (getTimeForDay() != m_day)
		{
			openFile();
		}

		char buffer[LOG_LEN] = { 0 };

		va_list args;
		va_start(args, fmt);
		vsprintf_s(buffer, fmt, args);
		va_end(args);

		m_file << m_levelText[lvl] << getTimeForMs() << " " << buffer << endl;
	}
}

void FileLog::createDir()
{
	if (!PathIsDirectory(LOG_DIR))
	{
		CreateDirectory(LOG_DIR, nullptr);
	}
}

void FileLog::openFile()
{
	closeFile();

	string sday = getTimeForDay();
	m_file.open(LOG_DIR + string("\\") + sday + ".txt", fstream::out | fstream::app);
	m_day = sday;
}

void FileLog::closeFile()
{
	if (m_file.is_open())
	{
		m_file.close();
	}
}

积累生活的点点滴滴,不为你看到,只怕突然回忆。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

文件操作之日志文件 的相关文章

  • Spring Boot——日志文件

    文章目录 1 日志的作用2 日志的用法3 自定义日志打印日志格式的说明 4 日志级别5 在配置文件中设置日志级别5 1设置全局的日志级别和局部文件夹的日志级别 6 日志持久化7 更简单的日志输出 lombok 1 日志的作用 日志的作用 x
  • SpringBoot 日志文件

    1 日志的作用2 日志怎么用3 自定义日志打印3 1 得到日志对象3 2 使用日志对象提供的方法打印日志3 3 日志格式说明 4 日志级别4 1 日志级别分类4 2 日志级别的配置 5 日志持久化6 更简单的实现自定义日志的打印6 1 准备
  • 日志文件xml

    lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt ConsoleAppender 控制台输出日志 gt lt appender name 61 34 STDOUT 34 cl
  • Spring Boot自定义log4j2日志文件 按天记录

    转载 https www cnblogs com advancing p 7922463 html Spring Boot自定义log4j2日志文件 背景 xff1a 因为从 Spring Boot 1 4开始的版本就要用log4j2 了
  • python脚本写log日志文件

    python脚本写log日志文件 一 定义Logger类二 实例化 调用 一 定义Logger类 span class token keyword import span logging span class token keyword f
  • 日志文件xml

    lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt ConsoleAppender 控制台输出日志 gt lt appender name 61 34 STDOUT 34 cl
  • win7 svn服务器搭建过程

    svn简介 https baike baidu com item subversion 7818587 fr aladdin SVN服务端分为 Subversion和VisualSVN Server 这里 我选择了VisualSVN Ser
  • iocp之简单实现

    一 步骤 二 代码 1 头文件 include
  • 文件操作之日志文件

    一 前言 用户 那谁 你的程序出问题了 来看看 你 问题是怎么出现的 为了复现 用户 我也不知道 就这样点点点就出问题了 你 这个时候 日志文件的重要性就凸显出来了 别指望用户能描述清楚问题出现的经过 最靠谱的还是看日志文件 二 多说两句
  • Linux命令行操作:使用“more“命令进行分页显示

    文章目录 1 引言 1 1 介绍Linux操作系统和命令行界面 什么是Linux操作系统 为什么命令行界面在Linux中如此重要 1 2 介绍Linux中的分页显示命令 分页显示命令的作用与意义 不同分页显示命令的比较 2 more 命令的
  • Modbus CRC和LRC算法研究及代码实现

    一 CRC 循环冗余校验 1 CRC16实现流程 XOR 异或 N 字节的信息位 POLY CRC16 多项式计算 1010 0000 0000 0001 生成多项式 1 x2 x15 x16 在CRC16中 发送的第一个字节位低字节 2
  • cocos2d-x 3.x 事件相关源码接口

    绝对干货 欢迎留下足迹 事件类及其子类 事件侦听及其子类 事件注册 分发
  • 七种经典排序算法小记

    首先要感谢MoreWindows的心得分享 通过他的文章 我更深入了解了这七种排序算法的思路 同时 也自己揣摩 手动敲代码实现了这些算法 为了加深理解 又给每一行代码加了注释 在此 特记下学习这七种排序算法的过程和心得 补充 冒泡排序 直接
  • 设计模式简述

    定义 设计模式是为解决某个问题的一套解决方案 优点 1 为某个问题提供了最优解决方案 2 A君以设计模式的思路写的代码 懂设计模式的B君 就很容易读懂A君的代码 设计模式类型 1 创建型模式 创建对象的同时隐藏创建逻辑的方式 2 结构型模式
  • 环形队列设计思路

    环形队列设计思路 一 数据结构 数据存储在一段连续的内存空间 通过写位置 读位置来控制数据的输入输出 二 数据操作 1 判断空逻辑 写位置 读位置 2 判断满逻辑 写位置 1 MAX SIZE 读位置 3 写数据逻辑 判断数据不满 在当前写
  • 实测C++变量长度、最小值、最大值

    说明 基本的内置变量类型 bool char wchar t int float double 类型修饰符 signed unsigned short long 环境 win7x64 VS2015 Debugx86 测试结果 补充 doub
  • 多线程小记

    创建线程的几种方法 C 多线程之 beginthread https blog csdn net u013043408 article details 83830181 C 多线程之CreateThread https blog csdn
  • Qt错误汇总

    1 error linker command failed with exit code 1 use v to see invocation 错误原因1 类中声明的方法没实现体 解决办法1 查找那个方法 在cpp中添加实现就行了 illeg
  • ADO方法操作数据库

    一 ADO连接数据库步骤 1 这行不能少 import C Program Files Common Files system ado msado60 tlb no namespace rename EOF adoEOF 2 初始化ado组
  • PLC学习札记

    PLC概念相关 PLC编程 PLC系统 通过了解概念 知道了plc的核心是对继电器编程 什么是继电器 继电器 最后 阅读PLC指导手册 结合之前学习的知识 融会贯通 PLC编程手册 FX系列 pdf 指令表运行机制 仅限于本项目

随机推荐

  • Linux中用stat命令查看文件时3个时间点解析

    有些时候 我们需要使用stat命令来查看文件的详细信息 另外联想下 ls l命令显示的是什么时间 touch命令修改文件的时间戳 修改的又是什么时间 在这里我们一起来试验下 首先 我们来看下stat情况 如图所示 会出现3个类型的时间 分别
  • CPU时间与系统时间(CPU time and wall clock time)

    CPU时间是指一段程序在CPU上面运行消耗的时间 也是内核时间 kernel time 在Linux Unix系统里面 C 程序的COU时间可以用一些第三方的库提供的函数测出 但是在Windows系统里面 没有可以直接使用的第三方函数 在这
  • Session和Cookie实现购物车

    来自森大科技官方博客 http www cnsendblog com index php p 342 GPS平台 网站建设 软件开发 系统运维 找森大网络科技 http cnsendnet taobao com 使用Session和Cook
  • 自定义Mybatis框架

    目录 自定义Mybatis分析 轮子缺少的配件 组装轮子 制定骨架 解析配置文件 类关系梳理 创建默认实现类 实现基于注解的查询 目录结构 流程图 通过快速入门示例 Mybatis快速入门 我们发现使用 mybatis 是非常容易的一件事情
  • easyui dialog 子窗口jsp(被弹出窗口)调用父jsp页面方法操作父jsp

    父jsp monthDuty jsp 选中tab2 var selectTabByIndex function tabId tabs select 1 中间js文件 monthDutyJs js var dialog parent sunn
  • 「Linux-基础」CentOS 8 LVM逻辑卷管理

    LVM逻辑卷管理 枫梓林 提示 建议按着步骤来 文章目录 LVM逻辑卷管理 1 简介 2 建立LVM的步骤 3 逻辑卷管理及部署 1 磁盘分区 2 物理卷管理 建立物理卷 扫描物理卷 显示物理卷 删除物理卷 3 卷组管理 建立卷组 扫描卷组
  • STM32(HAL库)通过ADC读取MQ2数据

    目录 1 简介 2 CubeMX初始化配置 2 1 基础配置 2 1 1 SYS配置 2 1 2 RCC配置 2 2 ADC外设配置 2 3 串口外设配置 2 4 项目生成 3 KEIL端程序整合 3 1 串口重映射 3 2 ADC数据采集
  • 实验5-8 使用函数求圆台体积 (10 分)

    实验5 8 使用函数求圆台体积 10 分 本题要求实现函数求圆台体积 定义并调用函数volume tc r lower r upper h 计算下底半径为r lower 上底半径为r upper 高度为h的圆台的体积 函数类型是double
  • 卷积学习与传统稀疏编码、ICA模型学习区别(逐步补充)

    逐步总结 有待补充 无监督学习知识框架 这种分类不合适 稀疏编码等也可以从统计学角度看做模型学习与参数选择 实际上 稀疏编码是从1维信号发展起来的表示方法 近年来 稀疏编码逐渐引入信号的先验信息 由非模型向基于模型的转变 学习特色字典 单层
  • iOS开发Swift-12-列表UI,TableViewController,动态响应Button勾选-待办事项App(1)

    1 创建新项目 为项目添加图标 2 将Table View Controller添加到界面中 将箭头移动到Table View上来 代表它是首页 根页面 选中ViewController 点击Delete 对它进行删除 将代码ViewCon
  • 网络/网络编程

    网络 网络编程部份 1 connect方法会阻塞 请问有什么方法可以避免其长时间阻塞 答 最通常的方法最有效的是加定时器 也可以采用非阻塞模式 2 网络中 如果客户端突然掉线或者重启 服务器端怎么样才能立刻知道 答 若客户端掉线或者重新启动
  • 服务器文件直接复制到本地,本地文件直接复制到云服务器

    本地文件直接复制到云服务器 内容精选 换一换 在本地主机和Windows弹性云服务器上分别安装QQ exe等工具进行数据传输 使用远程桌面连接mstsc方式进行数据传输 该方式不支持断点续传 可能存在传输中断的情况 因此不建议上传大文件 文
  • MySQL 5.6解压缩版安装配置方法图文教程(win10)

    MySQL 5 6解压缩版安装配置方法图文教程 win10 1 首先 我们需要得到这个安装包 解压下载到本地 可在小编网盘中找到 我已共享链接 可直接下载 比如 现在我们把他解压到我们本地的D MySQL文件夹下 现在我们就可以看到 当前目
  • 【WiFi】Wi-Fi 6(802.11ax)解析24:802.11ax中MU-MIMO和OFDMA的区别

    目录 1 序言 2 OFDMA 2 MU MIMO 3 MAC层部分 MU MIMO和OFDMA 4 结语 5 参考 1 序言 笔者将自己对于802 11ax中的MU MIMO和OFDMA的区别做了一个简单的总结 因为很多非通信技术专业的童
  • 临界区对象TCriticalSection(Delphi) 与 TRtlCriticalSection 的区别

    TRtlCriticalSection 是一个结构体 在windows单元中定义 TCriticalSection是在SyncObjs单元中实现的类 它对上面的那些临界区操作API函数进行了了封装 简化并方便了在Delphi的使用 如TCr
  • 用C语言开发一个BT下载软件 (四) ------ 代码实现-1-种子文件解析模块

    parse metafile h ifndef PARSE METAFILE define PARSE METAFILE 保存从种子文件中获取的tracker的URL typedef struct Announce list char an
  • 数据库建索引规则

    数据库建立索引常用的规则如下 1 表的主键 外键必须有索引 2 数据量超过300的表应该有索引 3 经常与其他表进行连接的表 在连接字段上应该建立索引 4 经常出现在Where子句中的字段 特别是大表的字段 应该建立索引 5 索引应该建在选
  • 微信小程序分包-主包尺寸 (不包合插件) 应小于 1.5 M

    目录 起因 分包 最后 起因 更新一个之前的小程序 上传的时候提示主包尺寸 不包合插件 应小于 1 5 M 怎么办 查看教程啊 开发者可通过开发者工具中的性能扫描工具提前发现代码中的可优化项 1 代码包不包含插件大小超过 1 5 M 建议
  • 迭代(iterable)和迭代器

    迭代 iterable 任何可迭代对象都可以作用于for循环 包括我们自定义的数据类型 只要符合迭代条件 就可以使用for循环 d a 1 b 2 c 3 对dict迭代 for k v in d items 如果要同时迭代key和valu
  • 文件操作之日志文件

    一 前言 用户 那谁 你的程序出问题了 来看看 你 问题是怎么出现的 为了复现 用户 我也不知道 就这样点点点就出问题了 你 这个时候 日志文件的重要性就凸显出来了 别指望用户能描述清楚问题出现的经过 最靠谱的还是看日志文件 二 多说两句