淘宝内部卷网站怎么做,建立网站建设考核激励制度,个人手机网站建设,商城高中目录
日志功能开发
常见的日志等级
日志功能代码
编译功能开发
创建子进程和程序替换
重定向
编译功能代码 日志功能开发
日志在软件开发和运维中起着至关重要的作用#xff0c;目前我们不谈运维只谈软件开发#xff1b;日志最大的作用就是用于故障排查和调试#x…目录
日志功能开发
常见的日志等级
日志功能代码
编译功能开发
创建子进程和程序替换
重定向
编译功能代码 日志功能开发
日志在软件开发和运维中起着至关重要的作用目前我们不谈运维只谈软件开发日志最大的作用就是用于故障排查和调试
当系统出现问题时日志记录可以帮助开发人员追踪问题的根源。通过查看日志文件开发人员可以了解系统在发生故障之前的行为识别错误发生的时间、地点和原因并快速定位到错误的代码或功能模块。
因此我们要为目前这个项目编写一个简单的日志模块这个模块可能被项目中的任何一个部分使用我们将其放在公共模块的一个文件中。
常见的日志等级 DEBUG调试 用于记录程序的详细运行信息通常用于开发和调试阶段帮助开发人员定位问题和追踪程序流程。 INFO信息 用于记录程序正常运行时的重要信息例如启动信息、关键操作记录等可用于了解系统的基本运行情况。 WARNING警告 用于记录一些潜在的问题或异常情况虽然不会导致系统崩溃或功能失效但需要开发人员注意和处理以避免可能的错误。 ERROR错误 用于记录错误事件表示程序发生了一些可恢复的错误但并未导致程序完全失败通常需要开发人员及时处理以保证系统的正常运行。 FATAL致命错误 用于记录严重错误事件表示程序发生了无法恢复的错误导致程序崩溃或功能失效需要立即进行修复和处理以保证系统的稳定性和可靠性。 基于这个项目目前我们实现的时文件版本因此我们需要打印出日志等级、文件名称、报错行、时间戳。
日志功能代码
Log.hpp
#pragma once
#include iostream
#include string
#include util.hpp
using namespace std;
namespace ns_log
{using namespace ns_util;// 日志等级enum{INFO, // 就是整数0DEBUG, // 1WARNING, // 2ERROR, // 3FATAL // 4};// 参数// 日志等级// 文件名// 行数// 标准输出流返回给用户inline ostream Log(const string level, const string file_name, const int line){// 添加日志等级string message [;message level;message ];// 添加报错文件名称message [;message file_name;message ];// 添加报错行message [;message to_string(line);message ];// 日志时间戳message [;message TimeUtil::GetTimeStamp();message ];// cout 本质内部是包含缓冲区的//cout message; // 不要endl刷新// 此时message 就在缓冲区中return cout;}
// LOG(INFO)messageendl;
// 开放日志
#define LOG(level) Log(#level, __FILE__, __LINE__)
}
最后我们宏定义这个函数调用参数#level 用于将参数 level 转换成一个字符串参数__FILE__ 和 __LINE__ 是预定义的宏在编译时由编译器自动替换为当前源文件的文件名和代码行号。
时间信息也是一个公用的信息我们会在另一个文件中实现。 编译功能开发 首先我们要明白这个模块只负责进行代码编译那么意味着我们目前默认是能够接收远端提交的代码文件并且这个文件对于我们编译模块来说是一个临时文件如果编译成功后也会形成一个临时的可执行文件因此在这个模块中我们还需要一个临时文件的文件夹。但是对于这个模块中目前的进程是用来接收代码文件的对于提交的代码文件我们如何处理呢
创建子进程和程序替换
因为编译对于操作系统来也是执行了一个程序只不过这个程序很小过程快而已因此我们可以创建一个子进程让子进程进行程序替换替换我们的编译指令程序。
重定向
编译代码就两种结果编译成功或者编译失败编译成功就是我们想要的结果可以通过判断是否生成可执行文件判断这个结果对于编译失败编译失败的信息会向我们的显示器打印但是我们是要将信息返回给使用者的因此我们就需要将错误信息重定向到一个错误文件中。
编译功能代码
compiler.hpp
// 主要进行编译服务
#pragma once// 编译服务器
#include iostream
#includeunistd.h
#includesys/wait.h
#includesys/stat.h
#includefcntl.h
#include../comm/util.hpp
#include../comm/Log.hpp
using namespace std;// 只负责进行代码编译// 默认代码能够接收// 远端提交代码// 一定要能够形成临时文件// 第一种编译通过
// 第二种编译出错
// 本质是像stderr错误中打印----需要形成临时文件 帮助我们保存编译出错的结果的// 不能让这个进程编译
// 核心思路创建子进程(fork())----子进程完成编译代码 编译错误向stderr中打印(默认是向显示屏打印) 需要重定向到stderr中
// 父进程继续执行namespace ns_compiler
{//引入路径拼接功能using namespace ns_util;using namespace ns_log;class Compiler{public:Compiler(){}~Compiler(){}//编译//返回值编译成功true 编译失败false//参数编译代码的文件名//1234//./temp/1234.cpp//./tmep/1234.exe//./temp/1234.stderr//编译错误临时文件static bool Compile(const std::string file_name)//temp文件夹保存临时文件{pid_t pid fork();if(pid0){//创建子进程失败LOG(ERROR)内部错误创建子进程失败\n;return false;}else if(pid0){//需要一个错误文件int _stderr open(PathUtil::Stderr(file_name).c_str(),O_CREAT|O_WRONLY,644);//if(_stderr0){//打开文件失败LOG(WARNING)没有成功形成stderr文件\n;exit(1);}//编译错误时才会向文件中写入//重定向dup2(_stderr,2);//子进程调用编译器完成对代码的编译工作//程序替换//不需要冗余的路径//g -o target src -stdc11//程序替换并不影响文件描述符表//我想执行谁怎么执行execlp(g,g,-o,PathUtil::Exe(file_name).c_str(),PathUtil::Src(file_name).c_str(),-stdc11,nullptr/*不要忘记*/);LOG(ERROR) 启动编译器g失败可能是参数错误\n;exit(2);}else {//父进程waitpid(pid,nullptr,0);//编译是否成功----是否形成可执行程序if(FileUtil::IsFileExists(PathUtil::Exe(file_name))){LOG(INFO)PathUtil::Src(file_name) 编译成功\n;return true;}}LOG(ERROR)编译失败没有形成可执行程序\n;return false;}};
}
until.hpp
#pragma once
#include iostream
#include string
#include sys/stat.h
#include sys/types.h
#include unistd.h
#include sys/time.h
using namespace std;
namespace ns_util
{const std::string temp_path ./temp/;// 路径class PathUtil{public:static std::string AddSuffix(const std::string file_name, const std::string suffix){std::string path_name temp_path;path_name file_name;path_name suffix;return path_name;}// 构建源文件路径后缀的完整文件名// 1234-./temp/1234.cppstatic std::string Src(const std::string file_name){return AddSuffix(file_name, .cpp);}// 构建可执行程序的完整路径后缀static std::string Exe(const std::string file_name){return AddSuffix(file_name, .exe);}// 构建该程序对应的标准错误完整的的路径后缀名static std::string Stderr(const std::string file_name){return AddSuffix(file_name, .stderr);}};class FileUtil{public:static bool IsFileExists(const std::string path_name){// 通过判断获取文件属性判断文件是否存在struct stat st;if (stat(path_name.c_str(), st) 0){// 获取文件属性成功代表文件存在return true;}return false;}};class TimeUtil{public:static string GetTimeStamp(){struct timeval _time;gettimeofday(_time, nullptr);return to_string(_time.tv_sec);}};
} 今天对项目编译和日志功能开发的分享到这就结束了希望大家读完后有很大的收获也可以在评论区点评文章中的内容和分享自己的看法个人主页还有很多精彩的内容。您三连的支持就是我前进的动力感谢大家的支持!