Logo Search packages:      
Sourcecode: pwlib version File versions  Download package

void PSystemLog::Output ( Level  level,
const char *  msg 
) [static]

Log an error into the system log.

Parameters:
level  Log level for this log message.
msg  Message to be logged

Definition at line 419 of file svcproc.cxx.

References PTime::AsString(), PThread::Current(), PServiceProcess::Current(), PString::GetLength(), PServiceProcess::GetLogLevel(), PProcess::GetName(), PThread::GetThreadName(), PString::IsEmpty(), PString::Left(), PString::Right(), PString::sprintf(), and PServiceProcess::systemLogFileName.

{
  PServiceProcess & process = PServiceProcess::Current();
  if (level > process.GetLogLevel())
    return;

  DWORD err = ::GetLastError();

  if (process.isWin95 || process.controlWindow != NULL) {
    static HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
    WaitForSingleObject(mutex, INFINITE);

    ostream * out;
    if (!process.systemLogFileName)
      out = new ofstream(process.systemLogFileName, ios::app);
    else
      out = new PStringStream;

    PTime now;
    *out << now.AsString("yyyy/MM/dd hh:mm:ss.uuu\t");
    PThread * thread = PThread::Current();
    if (thread == NULL)
      *out << "ThreadID=0x"
           << setfill('0') << hex
           << setw(8) << GetCurrentThreadId()
           << setfill(' ') << dec;
    else {
      PString threadName = thread->GetThreadName();
      if (threadName.GetLength() <= 23)
        *out << setw(23) << threadName;
      else
        *out << threadName.Left(10) << "..." << threadName.Right(10);
    }

    *out << '\t';
    if (level < 0)
      *out << "Message";
    else {
      static const char * const levelName[4] = {
        "Fatal error",
        "Error",
        "Warning",
        "Info"
      };
      if (level < PARRAYSIZE(levelName))
        *out << levelName[level];
      else
        *out << "Debug" << (level-Info);
    }

    *out << '\t' << msg;
    if (level < Info && err != 0)
      *out << " - error = " << err << endl;
    else if (msg[0] == '\0' || msg[strlen(msg)-1] != '\n')
      *out << endl;

    if (process.systemLogFileName.IsEmpty())
      process.DebugOutput(*(PStringStream*)out);

    delete out;
    ReleaseMutex(mutex);
    SetLastError(0);
  }
  else {
    // Use event logging to log the error.
    HANDLE hEventSource = RegisterEventSource(NULL, process.GetName());
    if (hEventSource == NULL)
      return;

    PString threadName;
    PThread * thread = PThread::Current();
    if (thread != NULL)
      threadName = thread->GetThreadName();
    else
      threadName.sprintf("%u", GetCurrentThreadId());

    char thrdbuf[16];
    if (threadName.IsEmpty())
      sprintf(thrdbuf, "0x%08X", thread);
    else {
      strncpy(thrdbuf, threadName, sizeof(thrdbuf)-1);
      thrdbuf[sizeof(thrdbuf)-1] = '\0';
    }

    char errbuf[25];
    if (level > StdError && level < Info && err != 0)
      ::sprintf(errbuf, "Error code = %d", err);
    else
      errbuf[0] = '\0';

    LPCTSTR strings[4];
    strings[0] = thrdbuf;
    strings[1] = msg;
    strings[2] = errbuf;
    strings[3] = level != Fatal ? "" : " Program aborted.";

    static const WORD levelType[Info+1] = {
      EVENTLOG_INFORMATION_TYPE,
      EVENTLOG_ERROR_TYPE,
      EVENTLOG_ERROR_TYPE,
      EVENTLOG_WARNING_TYPE
    };
    ReportEvent(hEventSource, // handle of event source
                (WORD)(level < Info ? levelType[level+1]
                                    : EVENTLOG_INFORMATION_TYPE), // event type
                (WORD)(level+1),      // event category
                0x1000,               // event ID
                NULL,                 // current user's SID
                PARRAYSIZE(strings),  // number of strings
                0,                    // no bytes of raw data
                strings,              // array of error strings
                NULL);                // no raw data
    DeregisterEventSource(hEventSource);
  }
}


Generated by  Doxygen 1.6.0   Back to index