【Linux】记录错误信息日志的实现

文章目录

  • 前言
  • 一、 目录实现(log.hpp)
  • 二、目录的具体使用
    • 1.comm.hpp(管道初始化)
    • 2.sever.cpp(为读端且令其创建命名管道)
    • 3.client.cpp(为写端)


前言

在这里插入图片描述

我们这个设计的日志可以自定以输出的方向,可以向显示器打印错误信息,也可以向指定目录写入,或者是分类写入

一、 目录实现(log.hpp)

#pragma once

#include <iostream>
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#define SIZE 1024

//对错误等级进行分级
#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4

//将错误信息打入到什么位置
#define Screen 1
#define Onefile 2
#define Classfile 3

//存储错误信息的文件默认名字
#define LogFile "log.txt"
using namespace std;


class Log{
public:
Log(){
    //默认打印方式往显示屏
    //规定好默认路径
    printMethod=Screen;
    path="./log/";
}


//自己改变默认答应方式
void Enable(int method){
    printMethod=method;
}


//将错误等级转换为字符串的形式
string levelTostring(int level){
    switch(level){
        case Info:
            return "Info";
        case Debug:
            return "Debuf";
        case Warning:
            return "Warning";
        case Error:
            return "Error";
        case Fatal:
            return "Fatal";
        default:
            return "None";
    }
}


//根据传出的信息,生成字符串logtxt,这个字符串中就是错误信息

void operator()(int level, const char *format, ...)
    {
        //报错信息 格式:默认部分+自定义部分
        time_t t = time(nullptr);
        struct tm *ctime = localtime(&t);
        char leftbuffer[SIZE];
        snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelTostring(level).c_str(),
                 ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,
                 ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        va_list s;
        va_start(s, format);
        //leftbuffer为获取的报错时间字符串,为默认部分

        //rightbuffer为我们的自定义部分
        char rightbuffer[SIZE];
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        va_end(s);

         
         //将leftbuffer 与rightbuffer合并成字符串logtxt
         //这就是我们的报错的错误信息
        char logtxt[SIZE * 2];
        snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);

        
        //将错误信息按指定方式打印到指定地方
        printLog(level, logtxt);
    }

//将错误信息按指定方式打印到指定地方
void printLog(int level,const string &logtxt){
    switch(printMethod){
        case Screen://打印到屏幕
            cout<<logtxt<<endl;
        case Onefile://打印到一个文件
            printOnefile(LogFile,logtxt);
            break;
        case Classfile://分错误信息打印到不同文件
            printClassfile(level,logtxt);
            break;
        default :
            break;
    }
}



void printOnefile(const string logname,const string logtxt){
    // printOnefile(LogFile,logtxt);
    string _logname=path+logname;  // ./log/log.txt
    int fd=open(_logname.c_str(),O_WRONLY|O_CREAT|O_APPEND,0666);
    if(fd<0)
        return;
    write(fd,logtxt.c_str(),logtxt.size());
    close(fd);
}

void printClassfile(int level,const string logtxt){
    // printClassfile(level,logtxt);
    string filename=LogFile;
    filename+=".";
    filename+=levelTostring(level);
    //  log.txt. (string)level

    //设置好文件名字后,再用单文件的打印方式写入文件
    printOnefile(filename,logtxt);
}

private:
int printMethod;//打印方法
string path;//打印路径
};

二、目录的具体使用

这里我们以命名管道之间两个进程传递信息为场景使用这个日志功能

1.comm.hpp(管道初始化)

 #pragma once
 #include<iostream>
 #include<string>
 #include<sys/types.h>
 #include<sys/stat.h>
#include<unistd.h>
#include<cerrno>
#include<string.h>
#include<fcntl.h>

//命名管道的名字与路径
 #define FIFO_FILE "./myfifo"
 #define MODE 0664

//返回的错误码
 enum{
    FIFO_CREAT_ERR=1,
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR
 };

//采用Init类,类似智能指针,我们在析构函数中调用删除命名管道的函数
//程序结束会自动调用析构函数
class Init{
public:
    Init(){
        int n=mkfifo(FIFO_FILE,MODE);
        if(n==-1){
            perror("mkfifo");
            exit(FIFO_CREAT_ERR);
        }

    }

    ~Init(){
        int m=unlink(FIFO_FILE);
        if(m==-1)
        {
            perror("unlink");
            exit(FIFO_DELETE_ERR);
        }
    }


};

2.sever.cpp(为读端且令其创建命名管道)

#include "comm.hpp"
#include "log.hpp"

using namespace std;

// 管理管道文件
int main()
{
    Init init;//创建命名管道
    Log log;
    
    log.Enable(Onefile);//重定向错误信息打入位置

    // 打开管道
    int fd = open(FIFO_FILE, O_RDONLY);  
    if (fd < 0)
    {
        //如果有错就打印错误信息
        log(Fatal, "error string: %s, error code: %d", strerror(errno), errno);
        exit(FIFO_OPEN_ERR);
    }

    log(Info, "server open file done, error string: %s, error code: %d", strerror(errno), errno);
    log(Warning, "server open file done, error string: %s, error code: %d", strerror(errno), errno);
    log(Fatal, "server open file done, error string: %s, error code: %d", strerror(errno), errno);
    log(Debug, "server open file done, error string: %s, error code: %d", strerror(errno), errno);


    // 开始通信
    while (true)
    {
        char buffer[1024] = {0};
        int x = read(fd, buffer, sizeof(buffer));
        if (x > 0)
        {
            buffer[x] = 0;
            cout << "client say# " << buffer << endl;
        }
        else if (x == 0)
        {
            log(Debug, "client quit, me too!, error string: %s, error code: %d", strerror(errno), errno);
            break;
        }
        else
            break;
    }

    close(fd);
    return 0;
}

3.client.cpp(为写端)

 #include <iostream>
#include "comm.hpp"

using namespace std;

int main()
{
    int fd = open(FIFO_FILE, O_WRONLY);//打开管道
    if(fd < 0)
    {
        perror("open");
        exit(FIFO_OPEN_ERR);
    }

    cout << "client open file done" << endl;

    string line;
    while(true)
    {
        cout << "Please Enter@ ";
        getline(cin, line);//因为可能有空格,cin不读入空格

        write(fd, line.c_str(), line.size());
    }

    close(fd);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

领域驱动设计总结——如何构造领域模型

领域驱动设计总结——如何构造领域模型 本文为领域驱动设计系列总结的第三篇&#xff0c;主要对领域驱动设计概念做个介绍&#xff0c;本系列领域驱动设计总结主要是在Eric Evans 所编写的《领域驱动设计》 一书的基础上进行归纳和总结。本文主要介绍在领域驱动设计中如何构造…

OpenWrt Lan口上网设置

LAN口上网设置 连接上openwrt&#xff0c;我用的 倍控N5105&#xff0c;eth0&#xff0c;看到Openwrt的IP是10.0.0.1 在 网络 -> 网口配置 -> 设置好 WAN 口和 LAN 口 初次使用经常重置 openwrt 所以我设置的是 静态IP模式 - 网络 -> 防火墙 -> 常规设置 ->…

【深度学习实验】图像处理(二):PIL 和 PyTorch(transforms)中的图像处理与随机图片增强

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 导入需要的工具包1. PIL图像处理a. 生成绿色和蓝色图像b. 缩放和合成图像c 在合成图像上添加文字d. 展示并保存图像 2. PIL随机图像增强a. 定义随机图像增强函数b. 实验结果展示 3. PyTorch&…

FloodFill

"绝境之中才窥见&#xff0c;Winner&#xff0c;Winner" FloodFill算法简介: floodfill又翻译成漫水填充。我们可以将下面的矩阵理解为一片具有一定高度的坡地&#xff0c;此时突发洪水&#xff0c;洪水会将高度<0的地方填满。 话句话来说&#xff0c;Fl…

uniapp+vue基于Android的校园二手跳蚤市场的设计与实现 微信小程序

实现功能&#xff1a; 用户管理&#xff1a;登陆、注册、注销、修改密码、上传头像、修改资料 发布与检索&#xff1a;发布商品、模糊搜索、人气排序、价格排序、时间排序、推送商品&#xff08;协同过滤算法实现个性化推荐&#xff09;&#xff0c;最新发布、分类检索 核心交易…

解密Kafka主题的分区策略:提升实时数据处理的关键

目录 一、Kafka主题的分区策略概述1.1 什么是Kafka主题的分区策略&#xff1f;1.2 为什么分区策略重要&#xff1f; 二、Kafka默认分区策略2.1 Round-Robin分区策略 三、自定义分区策略3.1 编写自定义分区器3.2 最佳实践&#xff1a;如何选择分区策略 四、分区策略的性能考量4.…

【数据中台】开源项目(2)-Dbus数据总线

1 背景 企业中大量业务数据保存在各个业务系统数据库中&#xff0c;过去通常的同步数据的方法有很多种&#xff0c;比如&#xff1a; 各个数据使用方在业务低峰期各种抽取所需数据&#xff08;缺点是存在重复抽取而且数据不一致&#xff09; 由统一的数仓平台通过sqoop到各个…

error LNK2038: 检测到“RuntimeLibrary”的不匹配项 解决方法

问题&#xff1a; 我们在使用Visual Studio编程的时候偶尔会遇到以下三种报错&#xff1a; error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MDd_DynamicDebug” &#xff08;引用的是release模式&#xff0c;但设置成debug模式了…

【研究中2】sql server权限用户设置

--更新时间2023.11.26 21&#xff1a;30 负责人&#xff1a;jerrysuse DBAliCMSIF EXISTS (select * from sysobjects where namehkcms_admin)--判断是否存在此表DROP TABLE hkcms_adminCREATE TABLE hkcms_admin (id int identity(1, 1),--id int primary key identity…

本地运行“李开复”的零一万物 34B 大模型

这篇文章&#xff0c;我们来聊聊如何本地运行最近争议颇多的&#xff0c;李开复带队的国产大模型&#xff1a;零一万物 34B。 写在前面 零一万物的模型争议有很多&#xff0c;不论是在海外的社交媒体平台&#xff0c;还是在国内的知乎和一种科技媒体上&#xff0c;不论是针对…

【Spring】Spring事务失效问题

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

058-第三代软件开发-文件Model

第三代软件开发-文件Model 文章目录 第三代软件开发-文件Model项目介绍文件Model 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#xff09;…

智能头盔天眼摄像头、单兵执法记录仪等配合MESH自组网在应急指挥调度中的应用

智能头盔、天眼摄像头、头盔记录仪、头盔摄像头、单兵执法记录仪等配合MESH自组网在应急指挥调度中的应用。 20人背负单兵自组网&#xff08;带手咪&#xff09;到训练场&#xff0c;戴头盔&#xff0c;头盔上放头盔式摄像头&#xff0c;大功率自组网设置在制高点&#xff0c;…

【办公软件】电脑开机密码忘记了如何重置?

这个案例是家人的电脑&#xff0c;已经使用多年&#xff0c;又是有小孩操作过的&#xff0c;所以电脑密码根本不记得是什么了&#xff1f;那难道这台电脑就废了吗&#xff1f;需要重新装机吗&#xff1f;那里面的资料不是没有了&#xff1f; 为了解决以上问题&#xff0c;一般…

数据结构——哈夫曼树结构总结

一直在找工作&#xff0c;没时间写博客&#xff0c;现在找到工作了&#xff0c;博客回归~ 哈夫曼树定义及构建教程

C#,《小白学程序》第三课:类class,类的数组及类数组的排序

类class把数值与功能巧妙的进行了结合&#xff0c;是编程技术的主要进步。 下面的程序你可以确立 分数 与 姓名 之间关系&#xff0c;并排序。 1 文本格式 /// <summary> /// 同学信息类 /// </summary> public class Classmate { /// <summary> /…

IDM(Internet Download Manager)PC版提升下载速度与效率的利器

你是否曾经因为下载速度慢而感到烦恼&#xff1f;或者在下载大型文件时&#xff0c;经历了长时间的等待&#xff1f;如果你有这样的困扰&#xff0c;那么IDM&#xff08;Internet Download Manager&#xff09;就是你的救星&#xff01; IDM是一款高效、实用的下载管理器&…

Day42力扣打卡

打卡记录 统计子串中的唯一字符&#xff08;找规律&#xff09; 链接 大佬的题解 class Solution:def uniqueLetterString(self, s: str) -> int:ans total 0last0, last1 {}, {}for i, c in enumerate(s):total i - 2 * last0.get(c, -1) last1.get(c, -1)ans tot…

如何深刻理解从二项式分布到泊松分布

泊松镇贴 二项分布和泊松分布的表达式 二项分布&#xff1a; P ( x k ) C n k p k ( 1 − p ) n − k P(xk) C_n^kp^k(1-p)^{n-k} P(xk)Cnk​pk(1−p)n−k 泊松分布&#xff1a; P ( x k ) λ k k ! e − λ P(xk) \frac{\lambda^k}{k!}e^{-\lambda} P(xk)k!λk​e−…

NX二次开发UF_CURVE_ask_trim 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_trim Defined in: uf_curve.h int UF_CURVE_ask_trim(tag_t trim_feature, UF_CURVE_trim_p_t trim_info ) overview 概述 Retrieve the current parameters of an a…