コード例 #1
0
ESR_ReturnCode SR_EventLogCreate(SR_EventLog** self)
{
  SR_EventLogImpl *impl, *any_existing_eventlog;
  ESR_ReturnCode rc;
  LCHAR* dataCaptureDir;
#define TIMESTAMP_LENGTH 18
  LCHAR timeStr[TIMESTAMP_LENGTH];
  struct tm *ct, ct_r;
  PTimeStamp timestamp;
#ifdef ANDROID
  struct timeval dir_stamp;
#endif

  if (self == NULL)
  {
    PLogError(L("ESR_INVALID_ARGUMENT"));
    return ESR_INVALID_ARGUMENT;
  }

  any_existing_eventlog = NULL;
  rc = ESR_SessionGetProperty(L("eventlog"), (void **)&any_existing_eventlog, TYPES_SR_EVENTLOG);
  if (rc == ESR_SUCCESS && any_existing_eventlog)
  {
    *self = (SR_EventLog*)any_existing_eventlog;
    PLogError("eventlog was already created");
    return ESR_SUCCESS;
  }

  impl = NEW(SR_EventLogImpl, MTAG);
  if (impl == NULL)
  {
    PLogError(L("ESR_OUT_OF_MEMORY"));
    return ESR_OUT_OF_MEMORY;
  }

  impl->Interface.destroy = &SR_EventLog_Destroy;
  impl->Interface.event = &SR_EventLog_Event;
  impl->Interface.token = &SR_EventLog_Token;
  impl->Interface.tokenInt = &SR_EventLog_TokenInt;
  impl->Interface.tokenPointer = &SR_EventLog_TokenPointer;
  impl->Interface.tokenUint16_t = &SR_EventLog_TokenUint16_t;
  impl->Interface.tokenSize_t = &SR_EventLog_TokenSize_t;
  impl->Interface.tokenBool = &SR_EventLog_TokenBool;
  impl->Interface.tokenFloat = &SR_EventLog_TokenFloat;
  impl->Interface.eventSession = &SR_EventLogEventSessionImpl;
  impl->Interface.audioOpen = &SR_EventLog_AudioOpen;
  impl->Interface.audioClose = &SR_EventLog_AudioClose;
  impl->Interface.audioWrite = &SR_EventLog_AudioWrite;
  impl->Interface.audioGetFilename = &SR_EventLog_AudioGetFilename;
  impl->sessionListenerPair.data = NULL;
  impl->sessionListenerPair.listener = &impl->sessionListener;
  impl->sessionListener.propertyChanged = &propertyChanged;
  impl->waveformCounter = 0;
  impl->logFile = NULL;
  impl->tokenBuf[0] = 0;
  impl->logFile_state = NO_FILE;
  impl->logLevel = 0;
  impl->waveformFile = NULL;
  LSTRCPY(impl->logFilename, L(""));

  CHKLOG(rc, ESR_SessionSetProperty(L("eventlog"), impl, TYPES_SR_EVENTLOG));
  rc = ESR_SessionGetSize_t(L("SREC.Recognizer.osi_log_level"), &impl->logLevel);
  if (rc == ESR_NO_MATCH_ERROR)
  {
    impl->logLevel = 7;
    CHKLOG(rc, ESR_SessionSetSize_t(L("SREC.Recognizer.osi_log_level"), impl->logLevel));
  }
  else if (rc != ESR_SUCCESS)
  {
    PLogError(ESR_rc2str(rc));
    goto CLEANUP;
  }

  if (impl->logLevel > 0)
  {
    CHKLOG(rc, ESR_SessionGetProperty(L("cmdline.DataCaptureDirectory"), (void**) &dataCaptureDir, TYPES_PLCHAR));

    LSTRCPY(impl->logFilename, dataCaptureDir);
#ifdef ANDROID
/*
 * The existing functions did not work on the desired platform, hence this code for the device.
 */
    gettimeofday ( &dir_stamp, NULL );
    sprintf(timeStr, "%lu", (unsigned long) dir_stamp.tv_sec );
#else
    PTimeStampSet(&timestamp);
    ct = localtime_r(&timestamp.secs, &ct_r);
    sprintf(timeStr, "%04d%02d%02d%02d%02d%02d",
            ct->tm_year + 1900, ct->tm_mon + 1, ct->tm_mday, ct->tm_hour,
            ct->tm_min, ct->tm_sec);
#endif
    /* create capture directory if it doesn't already exist */
    rc = pf_make_dir (impl->logFilename);
    if (rc != ESR_SUCCESS && rc != ESR_IDENTIFIER_COLLISION)
    {
      PLogError(ESR_rc2str(rc));
      goto CLEANUP;
    }

    /* create the directory for today's log if it doesn't already exist */
    LSTRCAT(impl->logFilename, L("/"));
    LSTRCAT(impl->logFilename, timeStr);
/*
 * There used to be a while forever loop here with a break, but that caused an infinite loop
 * for the customer. With 1 second resolution, a pre-existing directory probably means a bug.
 * It's not worth trying to handle this.
 */
    rc = pf_make_dir (impl->logFilename);
    if (rc != ESR_SUCCESS)
    {
      PLogError(ESR_rc2str(rc));
      goto CLEANUP;
    }

    /* create the log file */
    LSTRCAT(impl->logFilename, L("/SWIevent-"));
    LSTRCAT(impl->logFilename, timeStr);
    LSTRCAT(impl->logFilename, L(".log"));

    impl->logFile = pfopen ( impl->logFilename, L("w") );
/*    CHKLOG(rc, PFileSystemCreatePFile(impl->logFilename, ESR_TRUE, &impl->logFile));
    CHKLOG(rc, PFileOpen(impl->logFile, L("w")));*/

    if ( impl->logFile != NULL )
        impl->logFile_state = FILE_OK;
    else
        goto CLEANUP;
  }

  *self = (SR_EventLog*) impl;
  return ESR_SUCCESS;
CLEANUP:
  if (impl->logFile)
    pfclose (impl->logFile);
  return rc;
}
コード例 #2
0
ESR_ReturnCode logIt(SR_EventLogImpl *impl, LCHAR* evtt, LCHAR* log_record, size_t* writtenSize)
{
  struct tm *ct, ct_r;
  LCHAR header[128], header2[64];
  PTimeStamp timestamp;
  const size_t sizeof_LCHAR = sizeof(LCHAR);
  const LCHAR* bar = "|";
  const LCHAR* nl = "\n";
  size_t i, len;
  const LCHAR* toWrite[5];

  toWrite[0] = header;
  toWrite[1] = bar;
  toWrite[2] = evtt;
  toWrite[3] = log_record;
  toWrite[4] = nl;

  ct = &ct_r;
  memset(ct, 0, sizeof(struct tm));

  switch (impl->logFile_state)
  {
    case FILE_OK:
    case SPACE_SETTING:
      PTimeStampSet(&timestamp);
      ct = localtime_r(&timestamp.secs, &ct_r);

      sprintf(header, "TIME=%04d%02d%02d%02d%02d%02d%03d",
              ct->tm_year + 1900, ct->tm_mon + 1, ct->tm_mday, ct->tm_hour,
              ct->tm_min, ct->tm_sec, timestamp.msecs);
      quote_delimiter(header, 128);

      sprintf(header2, "CHAN=%s", L("0")); /* default is channel 0 in ESR */
      quote_delimiter(header2, 128);

      LSTRCAT(header, bar);
      LSTRCAT(header, header2);

      /* write the header,bar,evtt, and record */
      for (*writtenSize = 0, i = 0; i < 5; i++)
      {
        len = LSTRLEN(toWrite[i]);
        if (pfwrite(toWrite[i], sizeof_LCHAR, len, impl->logFile))
          *writtenSize += len;
      }

      if (*writtenSize <= 0)
      {
        PLogError(L("Could not write to log file; logging halted"));
        impl->logFile_state = FILE_ERROR;
        break;
      }
      else
      {
        pfflush(impl->logFile);
      }

      break;

      /* If couldn't open file or error previously, just return */
    case UNINITIALIZED:
    case NO_FILE:
    case FILE_ERROR:
    case SEEK_ERROR:
    default:
      return ESR_INVALID_STATE;

  }

  return ESR_SUCCESS;
}
コード例 #3
0
static ESR_ReturnCode logIt(const LCHAR *format, va_list args, ESR_BOOL showStackTrace)
{
  ESR_ReturnCode rc = ESR_SUCCESS;
  ESR_ReturnCode flushRC = ESR_SUCCESS;
#ifdef USE_STACKTRACE
#define BUFFER_SIZE P_MAX_STACKTRACE + 2000
#else
#define BUFFER_SIZE 2000
#endif
  LCHAR buffer[BUFFER_SIZE] = L("");

  // TODO: Remove once logging subsystem supports "warn" level
  if (strstr(format, "ESR_BUFFER_OVERFLOW")==format)
    return ESR_SUCCESS;
  
#ifdef USE_STACKTRACE
  if (Glogger == NULL)
  {
    /*
     * There are three possible scenerios for why logging would occur although the PLog module
     * is uninitialized:
     *
     * 1) The code fails before PLog is initialized (perhaps in other portable components)
     * 2) The user forgets to initialize the PLog module
     * 3) The code fails after PLog is uninitialized (on shutdown)
     *
     * We do our best by logging any errors but this might result in the memory leak of
     * the PStackTrace module in case 3.
     */
    rc = PStackTraceCreate();
    if (rc != ESR_SUCCESS)
    {
      PLOG_PANIC(L("PStackTraceCreate"), rc);
      goto CLEANUP;
    }
  }
  else
  {
#ifdef USE_THREAD
    rc = PtrdMutexLock(Gmutex);
    if (rc != ESR_SUCCESS)
      return rc;
#endif
  }
  if (locked)
    return ESR_INVALID_STATE;
  locked = ESR_TRUE;
  
  if (GlogFormat & LOG_OUTPUT_FORMAT_DATE_TIME)
  {
    PTimeStamp now;
    struct tm* loctime;
    LCHAR timeStr[TIME_BUF_SIZE];
    size_t timeStrSize;
    
    PTimeStampSet(&now);
    loctime = localtime(&now.secs);
    timeStrSize = LSTRFTIME(timeStr, TIME_BUF_SIZE, TIME_FORMAT, loctime);
    passert(timeStrSize == (TIME_BUF_SIZE - 5));
    psprintf(timeStr + (TIME_BUF_SIZE - 5), ".%03hu", now.msecs);
    
    psprintf(buffer + LSTRLEN(buffer), L("%s|"), timeStr);
    passert(LSTRLEN(buffer) < BUFFER_SIZE);
  }
  
  if (GlogFormat & LOG_OUTPUT_FORMAT_THREAD_ID)
  {
    rc = psprintf(buffer + LSTRLEN(buffer), L("trd=%u|"), PtrdGetCurrentThreadId());
    passert(LSTRLEN(buffer) < BUFFER_SIZE);
  }
  
  if (GlogFormat & LOG_OUTPUT_FORMAT_MODULE_NAME && showStackTrace)
  {
    size_t len = P_MAX_STACKTRACE;
    LCHAR text[P_MAX_STACKTRACE];
    LCHAR* index;
    size_t i;
    
    rc = PStackTraceGetValue((LCHAR*) & text, &len);
    if (rc == ESR_SUCCESS)
    {
      for (i = 0; i < 2; ++i)
      {
        rc = PStackTracePopLevel((LCHAR*) & text);
        if (rc != ESR_SUCCESS)
        {
          PLOG_PANIC(L("PStackTracePopLevel"), rc);
          goto CLEANUP;
        }
      }
      index = text;
      while (index)
      {
        index = LSTRSTR(index, L(" at\n"));
        if (index != NULL)
        {
          *(index + 1) = L('<');
          *(index + 2) = L('-');
          *(index + 3) = L(' ');
        }
      }
    }
    else if (rc == ESR_NOT_SUPPORTED)
      LSTRCPY(text, L(""));
    else if (rc != ESR_SUCCESS)
    {
      PLOG_PANIC(L("PStackTraceGetValue"), rc);
      goto CLEANUP;
    }
    rc = psprintf(buffer + LSTRLEN(buffer), L("Module=%s|"), text);
    passert(LSTRLEN(buffer) < BUFFER_SIZE);
  }
  
  pvsprintf(buffer + LSTRLEN(buffer), format, args);
#else
  pvsprintf(buffer + LSTRLEN(buffer), format, args);
#endif
  passert(LSTRLEN(buffer) < BUFFER_SIZE);
  
  psprintf(buffer + LSTRLEN(buffer), L("\n"));
  passert(LSTRLEN(buffer) < BUFFER_SIZE);
  
  if (Glogger != NULL)
  {
    rc = Glogger->printf(Glogger, L("%s"), buffer);
    if (rc != ESR_SUCCESS)
      goto CLEANUP;
    flushRC = Glogger->flush(Glogger);
  }
  else
  {
    /* We need to log but the logging module is disabled or is locked so we output to stderr instead */
    {
      pfprintf(PSTDERR, L("%s"), buffer);
      pfflush(PSTDERR);
    }
  }
  locked = ESR_FALSE;
#ifdef USE_THREAD
  PtrdMutexUnlock(Gmutex);
#endif
  return flushRC;
CLEANUP:
  if (Glogger != NULL && Glogger->flush != NULL)
    flushRC = Glogger->flush(Glogger);
  locked = ESR_FALSE;
#ifdef USE_THREAD
  PtrdMutexUnlock(Gmutex);
#endif
  return rc != ESR_SUCCESS ? rc : flushRC;
}