📄 staflogservice.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001, 2004, 2005 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include <map>#include <list>#include "STAFLogService.h"#include "STAF_fstream.h"#include "STAF_iostream.h"#include "STAFString.h"#include "STAFException.h"#include "STAFRefPtr.h"#include "STAFMutexSem.h"#include "STAFCommandParser.h"#include "STAFServiceInterface.h"#include "STAFTimestamp.h"#include "STAFUtil.h"#include "STAFInternalUtil.h"#include "STAFFileSystem.h"#include "STAFRWSem.h"//#define STAF_DO_TIMING#include "STAFTiming.h"// Note: The handleXXX functions for the Log service behave slightly differently// from other services. They parse the input before checking the trust// of the requester. This is necessary since requests may be forwarded// from another system. These requests may contain RMTMACHINE options,// which specify the originating system.// Type definitions// The STAFLogFileLocks class represents the necessary locks needed to access// a specific log file. The static acquireLocks() method is used to obtain// access to the appropriate locks.//// Internally, this class maintains a map of all the locks for "active" logs.// An "active" log is one for which there is a request currently being// processed. Once no more requests are working on a log, the log is no// longer "active" and is removed from the map. This is handled by maintaining// a "count" of all requests using the locks for a given log. When the lock// structure is deleted, the count is decremented, and, if it is zero, the// lock structure is removed from the map.//// This internal mechanism is used so that the map of log locks doesn't continue// to grow, which could lead to resource exhaustion (more likely OS semaphores// than memory). With this, the map stays very small, which also aids in// performance (of lookups).class STAFLogFileLocks;typedef STAFRefPtr<STAFLogFileLocks> STAFLogFileLocksPtr;class STAFLogFileLocks{public: // This is the method used to get access to the locks for a given // log file. static STAFLogFileLocksPtr acquireLocks(const STAFString &logFile); // DEBUG static void dumpLockData(); // The logAccess sem allows general access to the log. // A read lock should be obtained for any general read/write operation. // A write lock should be obtainef for any destructive type of change, such // as a purge/delete STAFRWSemPtr logAccess; // The recordAccess sem allows access to individual records. You should // acquire this sem before attempting to read or write any log records // from/to the file. // Note: You should already have a logAccess lock before acquiring this lock STAFMutexSemPtr recordAccess; ~STAFLogFileLocks() { releaseLocks(logFile); }private: // This is private so that users must go through acquireLocks() STAFLogFileLocks(STAFRWSemPtr theLogAccess, STAFMutexSemPtr theRecordAccess, const STAFString &theLogFile) : logAccess(theLogAccess), recordAccess(theRecordAccess), logFile(theLogFile) { /* Do nothing */ } STAFString logFile; // This is private so that is only called by the destructor static void releaseLocks(const STAFString &logFile); // This structure holds the real semaphores and access count struct LogLocks { LogLocks() : logAccess(new STAFRWSem, STAFRWSemPtr::INIT), recordAccess(new STAFMutexSem, STAFMutexSemPtr::INIT), count(1) { /* Do nothing */ } STAFRWSemPtr logAccess; STAFMutexSemPtr recordAccess; unsigned int count; }; typedef std::map<STAFString, LogLocks> LogLocksMap; static STAFMutexSem logLocksMutex; static std::map<STAFString, LogLocks> logLocks;};STAFMutexSem STAFLogFileLocks::logLocksMutex;STAFLogFileLocks::LogLocksMap STAFLogFileLocks::logLocks;void STAFLogFileLocks::dumpLockData(){ STAFMutexSemLock lock(logLocksMutex); for (LogLocksMap::iterator iter = logLocks.begin(); iter != logLocks.end(); ++iter) { cout << iter->first << ": " << iter->second.count << endl; }}STAFLogFileLocksPtr STAFLogFileLocks::acquireLocks(const STAFString &logFile){ STAFString logFileName = logFile.toLowerCase(); STAFMutexSemLock lock(logLocksMutex); LogLocksMap::iterator iter = logLocks.find(logFileName); if (iter != logLocks.end()) { ++iter->second.count; return STAFLogFileLocksPtr(new STAFLogFileLocks( iter->second.logAccess, iter->second.recordAccess, logFileName), STAFLogFileLocksPtr::INIT); } else { LogLocks theLogLocks; logLocks[logFileName] = theLogLocks; return STAFLogFileLocksPtr(new STAFLogFileLocks( theLogLocks.logAccess, theLogLocks.recordAccess, logFileName), STAFLogFileLocksPtr::INIT); }}void STAFLogFileLocks::releaseLocks(const STAFString &logFile){ STAFMutexSemLock lock(logLocksMutex); LogLocksMap::iterator iter = logLocks.find(logFile); if ((iter != logLocks.end()) && (--iter->second.count == 0)) { logLocks.erase(iter); }}typedef STAFRefPtr<STAFCommandParser> STAFCommandParserPtr;struct LogServiceData{ unsigned int fDebugMode; // Not used, currently STAFString fName; // Registered service name STAFString fShortName; // Short service name STAFString fResolveLogMaskString; // String for resolve log mask STAFString fResolveMessageString; // String for resolve message var STAFString fRoot; // Root of log directory STAFString fRemoteLogServer; // Name of remote log server STAFString fRemoteLogService; // Name of remote log service STAFHandlePtr fHandle; // Log service's STAF handle unsigned int fDefaultResolveMessage; // Default for resolving messages unsigned int fMaxRecordSize; // Maximum log record size unsigned int fDefaultMaxQueryRecords; // Default maximum records to return // on a generic QUERY request unsigned int fUseResolveMessageVar; // Honor S/S/Log/ResolveMessage unsigned int fRLogMode; // Are we in RLog mode? STAFCommandParserPtr fParmsParser; STAFCommandParserPtr fLogParser; STAFCommandParserPtr fQueryParser; STAFCommandParserPtr fListParser; STAFCommandParserPtr fDeleteParser; STAFCommandParserPtr fPurgeParser; STAFCommandParserPtr fSetParser; STAFString fDefaultAuthenticator; // Default Authenticator STAFString fLocalMachineName; // Map Class Definitions for marshalled results STAFMapClassDefinitionPtr fLogRecordClass; STAFMapClassDefinitionPtr fLogRecordLongClass; STAFMapClassDefinitionPtr fQueryStatsClass; STAFMapClassDefinitionPtr fPurgeStatsClass; STAFMapClassDefinitionPtr fListLocalSettingsClass; STAFMapClassDefinitionPtr fListRemoteSettingsClass; STAFMapClassDefinitionPtr fListLogsClass;};struct LogRecord{ LogRecord() : recordFormatID(0), date(0), secondsPastMidnight(0), logLevel(0), handle(0), recordNumber(0) { /* Do Nothing */ } LogRecord(unsigned int aDate, unsigned int seconds, unsigned int level, const STAFString &aMachine, const STAFString &aHandleName, STAFHandle_t aHandle, const STAFString(&aUser), const STAFString(&aEndpoint), const STAFString &aMessage) : recordFormatID(0), date(aDate), secondsPastMidnight(seconds), logLevel(level), machine(aMachine), handleName(aHandleName), handle(aHandle), user(aUser), endpoint(aEndpoint), message(aMessage), recordNumber(0) { /* Do Nothing */ } unsigned int recordFormatID; unsigned int date; unsigned int secondsPastMidnight; unsigned int logLevel; STAFString machine; STAFString handleName; STAFHandle_t handle; STAFString user; STAFString endpoint; STAFString message; // Note: Record number is not stored in the logfile unsigned int recordNumber;};typedef std::deque<STAFString> StringList;typedef std::deque<STAFHandle_t> HandleList;typedef struct{ unsigned int date; unsigned int seconds;} LogTimestamp;struct LogRecordFilter{ LogRecordFilter() : useLevelMask(false), useFrom(false), useAfter(false), useBefore(false), useTo(false) { /* Do Nothing */ } StringList contains; StringList cscontains; StringList startswith; StringList csstartswith; StringList qMachines; StringList names; StringList users; StringList endpoints; HandleList qHandles; bool useLevelMask; unsigned int levelMask; bool useFrom; LogTimestamp fromTimestamp; bool useAfter; LogTimestamp afterTimestamp; bool useBefore; LogTimestamp beforeTimestamp; bool useTo; LogTimestamp toTimestamp;};enum ReadLogRecordRC{ kReadLogOk = 0, kReadLogEndOfFile = 1, kReadLogInvalidFormat = 2};struct LogStats{ unsigned int fatal; unsigned int error; unsigned int warning; unsigned int info; unsigned int trace; unsigned int trace2; unsigned int trace3; unsigned int debug; unsigned int debug2; unsigned int debug3; unsigned int start; unsigned int stop; unsigned int pass; unsigned int fail; unsigned int status; unsigned int user1; unsigned int user2; unsigned int user3; unsigned int user4; unsigned int user5; unsigned int user6; unsigned int user7; unsigned int user8;};// Some global variablesstatic STAFString sVersionInfo("3.2.1");static STAFString sZeroOne("01");static STAFString sOne("1");static STAFString sLogExt("log");static STAFString sTmpExt("tmp");static STAFString sLeftCurly(kUTF8_LCURLY);static STAFString sSpace(kUTF8_SPACE);static STAFString sEqual(kUTF8_EQUAL);static STAFString sSlash(kUTF8_SLASH);static STAFString sColon(kUTF8_COLON);static const STAFString sSpecSeparator(sColon + sSlash + sSlash);static STAFString sTimestampSeps("-@");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -