/* HTMemLog.c
** MEMORY BUFFERED DATA LOGGING UTILITIES
**
** (c) COPYRIGHT MIT 1996.
** Please first read the full copyright statement in the file COPYRIGH.
** @(#) $Id: HTMemLog.c,v 2.16 1998/03/20 17:53:01 frystyk Exp $
**
** 26 Nov 96 (EGP) started
*/
/* Library include files */
#include "sysdep.h"
#include "HTUtils.h"
#include "HTInet.h"
#include "HTMemLog.h"
#include "HTTimer.h"
#ifdef WWW_MSWINDOWS
#define OPEN_FLAGS O_WRONLY|O_CREAT|O_TRUNC
#else /* WWW_MSWINDOWS */
#define OPEN_FLAGS O_WRONLY|O_CREAT|O_TRUNC|O_SYNC
#endif /* !WWW_MSWINDOWS */
PRIVATE size_t LogBuffSize = 1024; /* default size is 1k */
PRIVATE int LogFd = 2;
PRIVATE const char * LogName = NULL;
PRIVATE char * LogBuff = NULL;
PRIVATE size_t LogLen = 0;
PRIVATE BOOL KeepOpen = YES;
PRIVATE HTTimer * Timer = NULL;
PRIVATE int MemLogTimeout (HTTimer * timer, void * param, HTEventType type)
{
int ret;
if (WWWTRACE) HTTrace("MemLog...... flushing on timeout\n");
ret = HTMemLog_flush();
#if 0
/* Force flush */
if (close(LogFd) == -1 || (LogFd = open(LogName, OPEN_FLAGS, 0666)) == -1)
return HT_ERROR;
#endif
return ret;
}
PUBLIC int HTMemLog_open (char * logName, size_t size, BOOL keepOpen)
{
#ifdef USE_SYSLOG
openlog(LogName, LOG_NDELAY, LOG_USER);
#else /* USE_SYSLOG */
LogName = logName;
KeepOpen = keepOpen;
if ((LogFd = open(LogName, OPEN_FLAGS, 0666)) == -1)
return HT_ERROR;
if (!KeepOpen)
close(LogFd);
LogBuffSize = size;
if ((LogBuff = (char *) HT_MALLOC(size)) == NULL)
HT_OUTOFMEM("HTMemLog_open");
LogLen = 0;
#endif /* !USE_SYSLOG */
HTTraceData_setCallback(HTMemLog_callback);
Timer = HTTimer_new(NULL, MemLogTimeout, NULL, 10000, YES);
return HT_OK;
}
PUBLIC int HTMemLog_flush(void)
{
if (LogLen) {
if (!KeepOpen)
if ((LogFd = open(LogName, O_WRONLY|O_CREAT|O_APPEND, 0666)) == -1)
return HT_ERROR;
write(LogFd, LogBuff, LogLen);
LogLen = 0;
}
if (!KeepOpen)
close(LogFd);
return HT_OK;
}
PUBLIC int HTMemLog_add(char * buf, size_t len)
{
if (LogBuff) {
/*
** Dump everything that won't fit in buffer
*/
while (len + LogLen > LogBuffSize) {
size_t toWrite = LogBuffSize-LogLen;
memcpy(LogBuff+LogLen, buf, toWrite);
LogLen = LogBuffSize; /* same as += toWrite */
HTMemLog_flush();
buf += toWrite;
len -= toWrite;
}
memcpy(LogBuff+LogLen, buf, len);
LogLen += len;
return HT_OK;
}
return HT_ERROR;
}
PRIVATE ms_t HTMemLog_addTime(void)
{
char buff[20];
ms_t ms = HTGetTimeInMillis();
int len = sprintf(buff, "%lu", ms);
HTMemLog_add(buff, len);
return ms;
}
PUBLIC void HTMemLog_close (void)
{
#ifdef USE_SYSLOG
closelog();
#else /* USE_SYSLOG */
HTMemLog_flush();
if (LogFd > 2)
close(LogFd);
if (LogBuff != NULL)
HT_FREE(LogBuff);
#endif /* !USE_SYSLOG */
}
#ifdef USE_SYSLOG
#define PRINT_BUFF_SIZE 8200
#else /* USE_SYSLOG */
#define PRINT_BUFF_SIZE 200
#endif /* !USE_SYSLOG */
#ifdef USE_EXCLUDES
typedef struct {char * str; int len;} StrIndexIndex;
PRIVATE int StrIndex (char * str, StrIndexIndex element[], int elements)
{
int i;
for (i = 0; i < elements; i++)
if (!strncmp(element[i].str, str, element[i].len))
return i + 1;
return 0;
}
PRIVATE StrIndexIndex Excludes[] = {{"HTReader_read", 13}, {"HTWriter_write", 14}, {"HTEventList_loop", 16}};
#endif /* USE_EXCLUDES */
PUBLIC int HTMemLog_callback (char * data, size_t len, char * fmt, va_list pArgs)
{
char buff[PRINT_BUFF_SIZE];
int ret;
#ifdef USE_EXCLUDES
if (StrIndex(fmt, Excludes, sizeof(Excludes)/sizeof(Excludes[0])))
return 0;
#endif /* USE_EXCLUDES */
#ifdef USE_SYSLOG
ret = vsprintf(buff, fmt, pArgs);
syslog(LOG_DEBUG, "%s\n", buff);
if (len > 8192)
len = 8192;
strncpy(buff, data, len);
buff[len] = 0;
syslog(LOG_DEBUG, "%s\n", buff);
#else /* USE_SYSLOG */
HTMemLog_addTime();
#ifdef HAVE_LONG_SIZE_T
ret = sprintf(buff, " %ld ", len);
#else
ret = sprintf(buff, " %d ", len);
#endif
HTMemLog_add(buff, ret);
if (fmt) {
ret = vsprintf(buff, fmt, pArgs);
HTMemLog_add(buff, ret);
}
HTMemLog_add("\n", 1);
HTMemLog_add(data, len);
HTMemLog_add("\n", 1);
#endif /* !USE_SYSLOG */
return ret;
}
Webmaster