项目中需要分类日志功能,且日志由多个进程产生,所以写了这个类。 
#ifndef CAPPLOG_H_
#define CAPPLOG_H_
#include "Generic.h"
enum LOG_TYPE
{
LOG_DEAGNOSTIC_MSG  = 0x00000000,
LOG_EVENT           = 0x00000001,
LOG_ACTIVITY        = 0x00000002,
LOG_ERROR           = 0x00000004,
};
class CAppLog {
public:
CAppLog();
virtual ~CAppLog();
static void appendDeagnosticMsg( const char * lpszFmt, ...);
static void appendEvent( const char * lpszFmt, ...);
static void appendActivity( const char * lpszFmt, ...);
static void appendError( const char * lpszFmt, ...);
private:
static sem_t *      s_pLogFileSem;
static void append(LOG_TYPE emType, const char * lpszText);
};
#endif /* CAPPLOG_H_ */
以下是它的实现
/*
* CAppLog.cpp
*
*  Created on: Jan 1, 2009
*      Author: root
*/
#include "CAppLog.h"
#include "CSystemHelper.h"
#define LOG_SEM_NAME    "LogFileSem"
sem_t * CAppLog::s_pLogFileSem = NULL;
CAppLog g_oAppLog;
CAppLog::CAppLog() {
if( s_pLogFileSem == NULL )
{
s_pLogFileSem = sem_open( LOG_SEM_NAME, O_CREAT, 0666, 1);
}
}
CAppLog::~CAppLog() {
if( s_pLogFileSem != NULL )
{
sem_close(s_pLogFileSem);
s_pLogFileSem = NULL;
}
}
void CAppLog::append(LOG_TYPE emType, const char * lpszText)
{
char szBuffer[10240] = {0};
int nRet = readlink("/proc/self/exe", szBuffer, sizeof(szBuffer));
if( nRet <= 0 || nRet >= PATH_MAX )
return;
string strTemp(szBuffer);
string strDir = strTemp.substr(0, strTemp.rfind( '/') + 1);
string strExe = strTemp.substr(strTemp.rfind( '/') + 1);
time_t ulNow = {0};
time(&ulNow);
tm * pNow = localtime(&ulNow);
memset( szBuffer, 0, sizeof(szBuffer));
sprintf( szBuffer, "%sLog/%04d/%04d-%02d/"
, strDir.c_str()
, 1900 + pNow->tm_year
, 1900 + pNow->tm_year
, 1 + pNow->tm_mon
);
CSystemHelper::createDirectory(szBuffer);
sprintf( szBuffer, "%sLog/%04d/%04d-%02d/%04d-%02d-%02d.log"
, strDir.c_str()
, 1900 + pNow->tm_year
, 1900 + pNow->tm_year
, 1 + pNow->tm_mon
, 1900 + pNow->tm_year
, 1 + pNow->tm_mon
, pNow->tm_mday
);
sem_wait(s_pLogFileSem);
{
ofstream stream( szBuffer,ios::out | ios::app);
if( stream )
{
char szFormated[20480] = {0};
sprintf( szFormated, "\r\n%02d[%02d:%02d:%02d PID=%05d TID=%05ld EXE=%-15s] %s"
, emType
, pNow->tm_hour
, pNow->tm_min
, pNow->tm_sec
, getpid()
, (long)syscall(SYS_gettid)
, strExe.c_str()
, lpszText
);
stream << szFormated;
stream.flush();
stream.close();
}
}
sem_post(s_pLogFileSem);
}
void CAppLog::appendDeagnosticMsg( const char * lpszFmt, ...)
{
va_list arg;
va_start(arg, lpszFmt);
char szBuffer[10240] = {0};
vsprintf( szBuffer, lpszFmt, arg);
va_end(arg);
CAppLog::append( LOG_DEAGNOSTIC_MSG, szBuffer);
}
void CAppLog::appendEvent( const char * lpszFmt, ...)
{
va_list arg;
va_start(arg, lpszFmt);
char szBuffer[10240] = {0};
vsprintf( szBuffer, lpszFmt, arg);
va_end(arg);
CAppLog::append( LOG_EVENT, szBuffer);
}
void CAppLog::appendActivity( const char * lpszFmt, ...)
{
va_list arg;
va_start(arg, lpszFmt);
char szBuffer[10240] = {0};
vsprintf( szBuffer, lpszFmt, arg);
va_end(arg);
CAppLog::append( LOG_ACTIVITY, szBuffer);
}
void CAppLog::appendError( const char * lpszFmt, ...)
{
va_list arg;
va_start(arg, lpszFmt);
char szBuffer[10240] = {0};
vsprintf( szBuffer, lpszFmt, arg);
va_end(arg);
CAppLog::append( LOG_ERROR, szBuffer);
}
使用起来很简单,将类加入到工程,然后在需要的地方包含此类的头文件,然后直接调用静态方法。这里用到了一个辅助类的函数 CSystemHelper::createDirectory,它的实现如下:
void CSystemHelper::createDirectory(const char * lpszDir)
{
string strDir(lpszDir);
int nIndex = 0;
while(nIndex != string::npos)
{
int nFind = strDir.find( "/", nIndex+1);
string strTemp = strDir.substr( 0, nFind+1);
DIR *dir = opendir(strTemp.c_str());
if( dir != NULL )
closedir(dir);
else
mkdir( strTemp.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
nIndex = nFind;
}
}

一个进程安全的日志类, Linux实现相关推荐

  1. linux如何启动一个进程而不阻塞,当你在 Linux 上启动一个进程时会发生什么? | Linux 中国...

    原标题:当你在 Linux 上启动一个进程时会发生什么? | Linux 中国 本文是关于 fork 和 exec 是如何在 Unix 上工作的.你或许已经知道,也有人还不知道.几年前当我了解到这些时 ...

  2. Android动态日志,一个简单的Android日志类

    Android自带的日志类不支持显示文件名和行号,调试时很不方便.而第三方日志库往往又太重.所以自己对Android自带的日志类做了一个简单的封装,主要是调试时使用,不考虑日志丢失和性能问题.日志的输 ...

  3. linux启动一个进程吗,当你在Linux上启动一个进程时会发生什么?

    本文是关于 fork 和 exec 是如何在 Unix 上工作的.你或许已经知道,也有人还不知道.几年前当我了解到这些时,我惊叹不已. 我们要做的是启动一个进程.我们已经在博客上讨论了很多关于系统调用 ...

  4. C++11实战——多线程的日志类

    C++11实战--多线程的日志类 C++标准库的std::cout和std::ofstream重载了operator<<,单线程使用非常简单.但由于其并非线程安全,在多线程中使用则需要自己 ...

  5. Linux下进程的建立 并附Linux exec函数族

    我们都知道,进程就是正在执行的程序.而在Linux中,可以使用一个进程来创建另外一个进程.这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看 ...

  6. python open文件被另一个进程打开怎么办,在Windows上,如何打开一个已经被另一个进程打开进行写入的文件?...

    我试图打开另一个进程打开的日志文件并删除前几行. 在Unix上,我只需做一个os.open('/tmp/file.log', os.O_NONBLOCK),这样就可以更接近我的目标.在 现在我被Win ...

  7. Qt一个进程运行另一个进程

    Qt 进程间通信 1. 一个进程运行另一个进程 2. 例程代码 1. 一个进程运行另一个进程 Qt 的 QProcess 类用来启动一个外部程序并与其进行通信. 使用 start() 函数运行一个进程 ...

  8. 编写VC++日志类(Logger) ---- 方便调试

    目录 前言 实现 思路 设置控制台属性 介绍 使用示例 旧版 日志类的打印方法 日志类的使用示例 运行效果 新版 改动 日志打印方法 日志使用示例 运行效果 代码下载 前言 在写较大型的程序时,往往不 ...

  9. Linux安装supervisor:一个进程控制系统

    文章目录 0.使用Supervisor 0.1安装 0.2配置supervisord.conf 0.3启动supervisord 0.4启动Elasticsearch 0.5启动Kibana 0.6启 ...

最新文章

  1. Git Flow—Git团队协作最佳实践
  2. leetcode 289. Game of Life | 289. 生命游戏(Java)
  3. dede 验证码不显示 vdimgck.php,Dede后台验证码不显示解决方法详解(dedecms 5.7)
  4. javascript中函数和方法的区别
  5. Build 2017 | 一文看懂微软 Build 2017 大会:让 AI 走向边缘
  6. [js] js怎样避免原型链上的对象共享?
  7. 前端学习(1543):MVC的组成部分
  8. 美国计算机研究生学校排名2015,2015USNews美国大学研究生计算机工程专业排名
  9. 求1000的阶乘c语言编程,用C语言编写程序,求出1000的阶乘?
  10. 有人回嘴顶撞过驾校教练吗?后果怎样?
  11. IP多播技术[为软件高校杯做准备]
  12. 【一天一个C++小知识】015:c++11线程创建的三种方法
  13. 用例图中三种关系详解(转)
  14. 共享一款基于 jQuery 的多功能对话框插件 jBox,强不强大,用了才知道:)
  15. Linux软件安装方法之rpm包安装
  16. STM32F7 架构和资源分析
  17. P4188 [USACO18JAN]Lifeguards S
  18. 验证网站代码的免费在线工具
  19. 产品经理在路上之二——用户/行业调研
  20. 什么是SaaS,SaaS有哪些优缺点?

热门文章

  1. Java 多线程 之 银行ATM实例
  2. js实现数据结构及算法之图和图算法(Graphs)
  3. 在C#中用COM操作CAD
  4. 安装python爬虫scrapy踩过的那些坑和编程外的思考
  5. BZOJ4196:[NOI2015]软件包管理器——题解
  6. html防止iOS将数字识别为电话号码
  7. JPA的Column注解总结
  8. C#-datagridview隐藏行头
  9. Jmeter学习——11
  10. 逃离伪PHP程序员应该做的事