Linux应用——简易日志

news2024/11/27 5:26:41

1. 日志要求

对于一个日志来说,我们任认为其应该具有以下的内容

1. 日志时间

2. 日志等级

3. 日志内容

4. 文件名称与行号

在此基础上我们对不同的日志做出分级,即

info:        常规信息

warning: 报警信号

error:      严重信号,可能需要立即处理

fatal:       致命信号

Debug:   调试信息 

2. 代码实现

#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"

class Log
{
public:
    // 构造函数
    Log()
    {
        // 设置默认日志模式为向屏幕打印
        printMethod = Screen;
        path = "./log/";
    }

    // 调整日志模式
    void Enable(int method)
    {
        printMethod = method;
    }

    // 返回分级字符串
    std::string levelToString(int level)
    {
        switch (level)
        {
        case Info:
            return "Info";
        case Debug:
            return "Debug";
        case Warning:
            return "Warning";
        case Error:
            return "Error";
        case Fatal:
            return "Fatal";
        default:
            return "None";
        }
    }

    // 根据不同模式,向不同位置打印日志
    void printLog(int level, const std::string &logtxt)
    {
        switch (printMethod)
        {
        case Screen:
            std::cout << logtxt;
            break;
        case Onefile:
            printOneFile(LogFile, logtxt);
            break;
        case Classfile:
            printClassFile(level, logtxt);
            break;
        default:
            break;
        }
    }

    // 向一个文件中写入日志
    void printOneFile(const std::string &logname, const std::string &logtxt)
    {
        std::string _logname = path + logname;
        int fd = open(_logname.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666); // "log.txt"
        if (fd < 0)
            return;
        write(fd, logtxt.c_str(), logtxt.size());
        close(fd);
    }

    // 向一个文件夹中写入日志
    void printClassFile(int level, const std::string &logtxt)
    {
        std::string filename = LogFile;
        filename += ".";
        filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"
        printOneFile(filename, logtxt);
    }

    ~Log()
    {}

    // 运算符重载 便于直接使用
    void operator()(int level, const char *format, ...)
    {
        time_t t = time(nullptr);
        struct tm *ctime = localtime(&t);

        // leftbuffer - 存储等级信息与日期信息
        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);

        // 将可变参数中传入的参数写入到rightbuffer中
        // rightbuffer - 存储用户提示
        va_list s;
        va_start(s, format);
        char rightbuffer[SIZE];
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        va_end(s);

        // 格式:默认部分+自定义部分
        char logtxt[SIZE * 2];
        snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);

        printLog(level, logtxt);
    }

private:
    int printMethod;
    std::string path;
};

3. 使用测试

#include "Log.hpp"

int main()
{
    // 创建Log对象
    Log lg;

    lg(Info, "启动成功");
    sleep(1);
    lg(Debug, "这是一个调试信息");
    sleep(1);
    lg(Warning, "这是一个警告信息");
    sleep(1);
    lg(Error, "这是一个错误信息");
    sleep(1);
    lg(Fatal, "这是一个致命错误信息");

    return 0;
}

测试效果

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

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

相关文章

UNIAPP 动态菜单实现方法

1. 封装tabbar组件&#xff0c;组件UI使用uview的tabbar allList 定义出全部的菜单 list 定义当前用户能看到的菜单使用 u-tabbar 渲染出来 list 2. 权限判断处理 3. 使用方式 在 tab 页&#xff0c;底部放入该 tab 组件&#xff0c;并设置当前回显的页面&#xff0c;这里使用…

STM32F407寄存器操作(DMA+I2C)

1.前言 因为后面需要用到大量基础通讯传输的问题&#xff0c;于是今天折腾了一下DMA传输I2C与SPI的效果&#xff0c;其实我先是把DMASPI搞出来了。但是考虑到网上对于STM32的I2C微词颇多&#xff0c;基础的协议都没有调试出来&#xff0c;更遑论DMA控制了&#xff0c;前面调不…

排序算法之——归并排序,计数排序

文章目录 前言一、归并排序1. 归并排序的思想2. 归并排序时间复杂度及空间复杂度3. 归并排序代码实现1&#xff09;递归版本2&#xff09;非递归版本 二、计数排序1. 计数排序的思想2. 计数排序的时间复杂度及空间复杂度3. 计数排序代码实现 总结&#xff08;排序算法稳定性&am…

计算机毕业设计 基于Python的无人超市管理系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

深度学习基础—残差网络ResNets

1.残差网络结构 当网络训练的很深很深的时候&#xff0c;效果是否会很好&#xff1f;在这篇论文中&#xff0c;作者给出了答案&#xff1a;Deep Residual Learning for Image Recognitionhttps://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_…

使用html写一个能发起请求的登录界面

目录 head部分 内联样式部分 body部分 login-form类的div myModal类的div id script部分 总的代码 界面与操作演示 <!DOCTYPE html> <html lang"en"> <!DOCTYPE html> 这是文档类型声明&#xff0c;告诉浏览器这是一个 HTML文档。 <…

jmeter学习(1)线程组与发送请求

1、线程组 执行顺序 &#xff1a;setUp线程组 > 线程组 > tearDown线程组 2、 发送请求 可以发送http、java、dubbo 请求等 下面讲解发送http 1&#xff09;Http请求默认值 作用范围是该线程组下的所有HTTP请求&#xff0c;如果http请求设置的与默认值冲突&#xff0…

前端规范工程-3:CSS规范(Stylelint)

样式规范工具&#xff08;StyleLint&#xff09; Stylelint 是一个灵活且强大的工具&#xff0c;适用于保持 CSS 代码的质量和一致性。结合其他工具&#xff08;如 Prettier 和 ESLint&#xff09;&#xff0c;可以更全面地保障前端代码的整洁性和可维护性。 目录 样式规范工具…

oracle virtualBox 拖动文件到虚拟机内报错

DnD: Error: Drag and drop to guest not possible -- either the guest OS does not support this, or the.... 首先将拖放的双向选项打开 打开CD驱动器 根据操作系统是32还是64安装对应的安装包&#xff0c;amd64为64位系统&#xff0c;x86为32位系统 安装后重启即可向虚拟机…

【C语言】数组练习

【C语言】数组练习 练习1&#xff1a;多个字符从两端移动&#xff0c;向中间汇聚练习2、二分查找 练习1&#xff1a;多个字符从两端移动&#xff0c;向中间汇聚 编写代码&#xff0c;演示多个字符从两端移动&#xff0c;向中间汇聚 练习2、二分查找 在⼀个升序的数组中查找指…

sql语句牛客练习

文章目录 1. SQL21 浙江大学用户题目回答情况① 错误② 正确 2. SQL22 统计每个学校的答过题的用户的平均答题数① 错误② 正确 3. SQL23 统计每个学校各难度的用户平均刷题数4. SQL25 查找山东大学或者性别为男生的信息① 错误② 正确 5. SQL26 计算25岁以上和以下的用户数量①…

Wireshark 解析QQ、微信的通信协议|TCP|UDP

写在前面 QQ&#xff0c;微信这样的聊天软件。我们一般称为im&#xff0c;Instant Messaging&#xff0c;即时通讯系统。那大家会不会有疑问&#xff0c;自己聊天内容会不会被黑客或者不法分子知道&#xff1f;这种体量的im是基于tcp还是udp呢&#xff1f;这篇文章我们就来探索…

基于Springboot的在线订餐系统设计与实现(论文+源码)_kaic

摘 要 当今世界&#xff0c;互联网以及和互联网有关的行业都在不断的发展&#xff0c;也在持续走进人们的生活&#xff0c;在此趋势下人们对于通过互联网解决生活问题的需求愈来愈多&#xff0c;本文考虑到了这些情况后做出了该订餐系统。 本系统选择了MySQL作为主要存储单元…

搭建k8s集群服务(kubeadm方式)

准备工作 操作系统版本&#xff1a;CentOS Linux release 7.9.2009 (Core) 虚拟机硬件配置&#xff1a;2核8G内存&#xff08;最低2G&#xff09;&#xff0c;硬盘最低25G&#xff1b; linux内核版本&#xff08;3.10版本尝试失败&#xff09;&#xff1a;5.4.268-1.el7.elr…

每日读则推(三)

n.(事件的)发生地点,(活动的)场所 n.雄性大园丁鸟 n.多细枝的,苗条的 v.放大,扩大(声音);增强,加强 Male great bowerbirds build twiggy concert venues that amplify their raucous songs and n.园丁鸟 …

讲职场:不要经常说消极的话

1、不要经常说消极的话&#xff0c;不要接触让自己力量消失的人 习惯性用强大的语言加持自己&#xff0c;才能立起来 2、只要你下决心钻研一门技术&#xff0c;你就全身心扑在上面&#xff0c;把每一个细节研究透&#xff0c;只有这样&#xff0c;你才能在学会之后&#xff0…

投资精明之选,国内外低代码平台性价比排行榜

本文介绍了国内外10大低代码平台的特点及性价比&#xff0c;包括ZohoCreator、OutSystems等&#xff0c;强调低代码平台通过简化开发过程&#xff0c;提高应用开发效率和质量&#xff0c;适合不同规模企业。选择时考虑企业需求和预算&#xff0c;建议试用后再决策。 一、Zoho C…

Apache安装后无法启动的问题“不能再本地计算机启动apache”

首先安装 参考这位博主的小白下载和安装Apache的教程&#xff08;保姆级&#xff09; 遇到的问题 在启动的时候遇到问题 说apache不能在本地计算机启动 解决方法 1. 路径检查 首先&#xff01;&#xff01;&#xff01; 请仔细检查你的httpd.conf文件中的Apache路径是否…

基于Springboot+Vue的汉服交易小程序的设计与实现(含源码+数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

Git版本控制工具--关于命令

Git版本控制工具 学习前言 在项目开发中&#xff0c;总是需要多个人同时对一个项目进行修改&#xff0c;如何高效快速地进行修改&#xff0c;且控制各自修改的版本不会和他人的进行重叠&#xff0c;这就需要用到Git分布式版本控制器了 作用 解决了一致性&#xff0c;并发性…