📄 log.cpp
字号:
/******************************************************************************** log.cpp: Logging method*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: log.cpp,v 1.6 2002/09/10 11:56:28 tooney Exp $** Authors: Benoit Steiner <benny@via.ecp.fr>** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**-------------------------------------------------------------------------------********************************************************************************///------------------------------------------------------------------------------// Preamble//------------------------------------------------------------------------------#include "defs.h"#include <stdlib.h>#include <stdio.h>#ifdef HAVE_OPENDIR#include <dirent.h>#endif#include <stdarg.h>#include <string.h>#include <time.h>#ifdef SYSLOG#include <syslog.h>#endif#include "common.h"#include "string.h"#include "vector.h"#include "exception.h"#include "file.h"#include "log.h"#include "debug.h"//******************************************************************************// Class C_LogClient//******************************************************************************// Class used to store client information// Internal to the file because it is a mechanism internal to the log module//******************************************************************************class C_LogClient{friend class C_Log; public: C_LogClient(const C_String& strClientDescr, u8 iFlags); ~C_LogClient(); protected: // Flags u8 iFlags; // Client description C_String strDescr;};//------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_LogClient::C_LogClient(const C_String& strName, u8 iOptions) : strDescr(strName){ iFlags = iOptions;}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------// No need to perform any check since their is no message buffering at that time// When there will be, we will must add a ref count for exemple//------------------------------------------------------------------------------C_LogClient::~C_LogClient(){}//******************************************************************************// Class C_Log//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_Log::C_Log(){ m_pLogFile = NULL;}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------C_Log::~C_Log(){ if(m_pLogFile) delete m_pLogFile;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Log::Init(const C_String& strLogName){ int iRc = NO_ERR; // In principe, Init is called to init the file // so there is no LOG_FILE flag to check // to perform what is bellow. try { // Open the log file for writing m_pLogFile = new C_File(strLogName); m_pLogFile->Open("a+"); } catch(E_Exception e) { printf("Unable to open the log file \"%s\": %s\n", strLogName.GetString(), e.Dump().GetString()); iRc = GEN_ERR; } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Log::End(){ int iRc = NO_ERR; // Close the file if it has been opened before: this behaviour helps error // handling since no specific action must be made if the file has not been // opened when the error occured. if(m_pLogFile) { try { m_pLogFile->Close(); } catch(E_Exception e) { iRc = GEN_ERR; } } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Set some flags that will be used to control the logging//------------------------------------------------------------------------------handle C_Log::Register(const C_String& strDescr, u8 iFlags){ C_LogClient* pClientDescr = new C_LogClient(strDescr, iFlags); return (void*)pClientDescr;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Log::Unregister(handle hModule){ delete (C_LogClient*)hModule; ZERO(hModule); // To avoid further undetected use} //------------------------------------------------------------------------------// Log: append a message to the log file//------------------------------------------------------------------------------void C_Log::Append(handle hModule, u8 iLevel, const C_String& strMsg){ time_t tTime; struct tm* ptmTime; time(&tTime); ptmTime = localtime(&tTime); C_String strBuff(""); ASSERT(hModule); // Verify that the module is well registered#define pClient ((C_LogClient*)hModule) // Check if the logging of the messages of that level is enabled if(iLevel < (pClient->iFlags & 0x0F)) { // Message must be discarded return; } // The message must be logged: add the necessary fields // First record the time C_String StrDateBuff(1900 + ptmTime->tm_year); StrDateBuff += "-"; if(ptmTime->tm_mon < 9) StrDateBuff += "0"; StrDateBuff += 1 + ptmTime->tm_mon; StrDateBuff += "-"; if(ptmTime->tm_mday < 10) StrDateBuff += "0"; StrDateBuff += ptmTime->tm_mday; StrDateBuff += " "; if(ptmTime->tm_hour < 10) StrDateBuff += "0"; StrDateBuff += ptmTime->tm_hour; StrDateBuff += ":"; if(ptmTime->tm_min < 10) StrDateBuff += "0"; StrDateBuff += ptmTime->tm_min; StrDateBuff += ":"; if(ptmTime->tm_sec < 10) StrDateBuff += "0"; StrDateBuff += ptmTime->tm_sec; StrDateBuff += " "; // Indicate the severity level of the message switch (iLevel) { case LOG_NOTE: strBuff += "[INFO/"; break; case LOG_WARN: strBuff += "[WARN/"; break; case LOG_ERROR: strBuff += "[ERROR/"; break; case LOG_DBG: strBuff += "[DEBUG/"; break; default: strBuff += "[EXCEPTION/"; break; } // Add the name of the module which logged the message strBuff += pClient->strDescr; // Add a separator strBuff += "] "; // Now add the log message to the buffer strBuff = strBuff + strMsg; // Add the final CR strBuff += "\n"; if (pClient->iFlags & LOG_SYSTEM) {#ifdef SYSLOG syslog(LOG_INFO,strBuff.GetString());#endif } strBuff = StrDateBuff + strBuff; // Now check to what devices the message must be outputed if(pClient->iFlags & LOG_FILE) { ASSERT(m_pLogFile); // Verify that Init() has been called before // Append the buffer to the logfile and discards errors const char* pszBuff = strBuff.GetString(); int iLen = strBuff.Length(); try { m_pLogFile->Write((const byte*)pszBuff, iLen); } catch(E_Exception e) {}; } if (pClient->iFlags & LOG_SCR) { // Print the message to stderr fprintf(stderr, "%s", strBuff.GetString()); } #undef pClient}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -