动手编写TCP服务器系列之一:日志文件

动手编写TCP服务器系列之一:日志文件

前言

在几个月之前,笔者想自己实现一个性能比较良好的基于tcp的服务器。于是断断续续写了个把月,因为还需要找工,还有论文什么的。拖了这么久。现在开辟这样的一个博客,我想记录下自己的思路,也和大家分享自己的代码。个人觉得一个优秀的服务器,不能考虑各种通用性,平台无关性。我写的这个服务器只针对linux平台。

在写这个系列文章之前,我想把功能都独立出来。每一篇文章专注于一个功能。

本系列文章均系笔者所写,难免有一些错误或者纰漏,服务器空间,如果小伙伴们有好的建议或者更好的算法,请不吝赐教。

正文 目标

本篇文章主要是讲TCP Server的日志功能。那么在一个服务器当中日志功能是必不可少的。无论是定位错误或者打印一些信息等等。日志的预期目标如下图所示。

Time是记录日志时间;Level是日志级别;PID是进程ID;TID是线程ID;Function是日志所在函数;Line是文件行;File是日志文件;Message是所打印的信息。

#ifndef LOG_HPP_#define LOG_HPP_#include <string>#include <cstdio>#include <cstring>#include <stdarg.h>#include <syscall.h>#include <sys/time.h>#include <linux/limits.h>#define LOG_STRING_MAX 4096#define NEWLINE”\n”#define MAX_PATHSIZEPATH_MAX#define RETURN_OK0#define LOG(level,fmt,…)\do {\ if( _curPDLevel >= level )\ {\log(level,__func__,__FILE__,__LINE__,fmt,##__VA_ARGS__);\ }\}while( 0 )\#define CHECK( cond, retCode, gotoLabel, level, fmt, … )\do {\ if( !( cond ) )\ {\rc = ( retCode );\LOG( (level), fmt, ##__VA_ARGS__ );\goto gotoLabel;\ }\}while( 0 )\enum PDLEVEL{ PDSERVER=0, PDERROR, PDEVENT, PDWARNING, PDINFO, PDDEBUG};extern PDLEVEL _curPDLevel;const char * getPDLevelDesp( PDLEVEL level );#define PD_DFT_DIAGLEVEL PDWARNING* file,unsigned int line, const char * format, … );* file,unsigned int lne, std::string message );#endif

#include #include #include * PDLEVELSTRING[] ={,,,,,};const char * getLevelDesp( PDLEVEL level ){if( (unsigned int)level > (unsigned int)PDDEBUG ){;}return PDLEVELSTRING[(unsigned int)level];}* LOG_HEADER_FORMAT = \OSS_NEWLINE \OSS_NEWLINE \OSS_NEWLINE \OSS_NEWLINE\OSS_NEWLINE OSS_NEWLINE;LEVEL _curPDLevel = DFT_DIAGLEVEL;static char _diaglogPath[ OSS_MAX_PATHSIZE+1 ] = { 0 };Latch _logMutex;FileOperation _logFile; _pdLogFileReopen(){int rc = RETURN_OK;_logFile.Close();rc = _logFile.Open( _pdDiaglogPath );if( rc ){printf( , OSS_NEWLINE, rc );goto error;}_logFile.SeekToEnd();done:return rc;error:goto done;}_logFileWrite( const char * pData ){int rc = RETURN_OK;size_t dataSize = strlen( pData );_logMutex.get();if( !_logFile.IsValid() ){// open the filerc = _logFileReopen();if( rc ){printf( OSS_NEWLINE, rc);goto error;}}rc = _logFile.Write( pData, dataSize );if( rc ){printf( OSS_NEWLINE, rc );goto error;}done:_logMutex.release();return rc;error:goto done;}* file, unsigned int line, const char * format, … ){int rc = RETURN_OK;if( _curPDLevel < level ){return;}va_list ap;char userInfo[ PD_LOG_STRING_MAX ];char sysInfo[PD_LOG_STRING_MAX];struct tm otm;struct timeval tv;struct timezone tz;time_t tt;gettimeofday( &tv, &tz );tt = tv.tv_sec;localtime_r( &tt, &otm );// create user information va_start( ap, format );vsnprintf( userInfo, PD_LOG_STRING_MAX, format, ap );va_end( ap );snprintf( sysInfo, LOG_STRING_MAX, LOG_HEADER_FORMAT,otm.tm_year + 1900,otm.tm_mon + 1,otm.tm_mday,otm.tm_hour,otm.tm_min,otm.tm_sec,PDLEVELSTRING[level],getpid(),syscall(SYS_gettid),func,line,file,userInfo );printf( NEWLINE, sysInfo);/*if( _pdDiaglogPath[0] != ‘\0’ ){rc = _logFileWrite( sysInfo );if( rc ){printf( “Failed to write into log file, errno = %d”NEWLINE, rc );printf( “%s”NEWLINE, sysInfo );}}*/return;}/*int main( int argc, char ** argv ){PD_LOG( PDERROR, “%d”, 1 );return 0;}*/

代码仅供参考。可能中间用到了一些锁的机制或者一些写文件的类。比如FileOp在后续的文章中会慢慢呈现出来。

作者

出处:

本文版权归作者所有,香港服务器,欢迎转载,网站空间,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

posted on

可见内心底对旅行是多么的淡漠。

动手编写TCP服务器系列之一:日志文件

相关文章:

你感兴趣的文章:

标签云: