Made all sub systems for logging lower case
Log filtering is now based on an array of severitys per subsystem Added a LogIS call which takes an integer for the subsystem Added a LogTS call which allows to specify a user supplied time stamp
This commit is contained in:
366
logv2.c
366
logv2.c
@ -28,9 +28,11 @@ static unsigned int logDisabled = 0;
|
||||
static int unsigned logConfigured = 0;
|
||||
|
||||
/*================ The default log level =======================================*/
|
||||
static unsigned int globalLogLevel = 4;
|
||||
static unsigned int globalLogLevel = INFO;
|
||||
|
||||
/*========= The list of sub systems for which full logging is enabled ==========*/
|
||||
static int subList;
|
||||
unsigned int logEnabledArray[MAXSUB ];
|
||||
|
||||
/*================== Callback management =======================================*/
|
||||
typedef struct {
|
||||
LogCallback func;
|
||||
@ -94,6 +96,8 @@ void LogClose(void *data)
|
||||
static void checkLogFile(void)
|
||||
{
|
||||
char *filename = NULL;
|
||||
char *oldLogFile = NULL;
|
||||
char timeStamp[132];
|
||||
|
||||
if(logDisabled || logConfigured == 0){
|
||||
return;
|
||||
@ -103,6 +107,10 @@ static void checkLogFile(void)
|
||||
close when full
|
||||
*/
|
||||
if(logFile != NULL && lineCount >= MAXFILELINES){
|
||||
oldLogFile = strdup(logFilename);
|
||||
filename = makeLogFileName();
|
||||
formatTimeStamp(timeStamp,sizeof(timeStamp),0);
|
||||
fprintf(logFile,"%s:sys:%d:Next logfile %s\n",timeStamp,INFO,filename);
|
||||
LogClose(NULL);
|
||||
}
|
||||
|
||||
@ -110,10 +118,16 @@ static void checkLogFile(void)
|
||||
start a new log file
|
||||
*/
|
||||
if(logFile == NULL){
|
||||
filename = makeLogFileName();
|
||||
if(filename == NULL){
|
||||
filename = makeLogFileName();
|
||||
}
|
||||
if(filename != NULL){
|
||||
logFile = fopen(filename,"w");
|
||||
strncpy(logFilename,filename,sizeof(logFilename));
|
||||
if(oldLogFile != NULL){
|
||||
fprintf(logFile,"%s:sys:%d:Previous logfile %s\n",timeStamp,INFO,oldLogFile);
|
||||
free(oldLogFile);
|
||||
}
|
||||
free(filename);
|
||||
}
|
||||
}
|
||||
@ -144,39 +158,6 @@ static void writeLog(char *logMessage)
|
||||
}
|
||||
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
unsigned int logFilter(unsigned int severity, const char *subsystem)
|
||||
{
|
||||
int status;
|
||||
char buffer[1024];
|
||||
|
||||
if(logDisabled || logConfigured == 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If it is in the list of enabled subsystems, everything is logged
|
||||
*/
|
||||
status = LLDnodePtr2First(subList);
|
||||
while (status == 1) {
|
||||
LLDstringData(subList, buffer);
|
||||
if(strcmp(buffer,subsystem) == 0) {
|
||||
return 0;
|
||||
}
|
||||
status = LLDnodePtr2Next(subList);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
test against the global log level
|
||||
*/
|
||||
if(severity > globalLogLevel){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*=============================================================================*/
|
||||
void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength)
|
||||
{
|
||||
@ -194,6 +175,99 @@ void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLeng
|
||||
}
|
||||
strncpy(buffer,severityText[severity-1],bufferLength);
|
||||
}
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
static unsigned int sevFromText(const char *txt)
|
||||
{
|
||||
static const char *severityText[] = {"fatal",
|
||||
"error",
|
||||
"warn",
|
||||
"info",
|
||||
"verbose",
|
||||
"debug",
|
||||
NULL
|
||||
};
|
||||
int sev = 0;
|
||||
while(severityText[sev] != NULL){
|
||||
if(strcmp(txt,severityText[sev]) == 0){
|
||||
break;
|
||||
}
|
||||
sev++;
|
||||
}
|
||||
sev++; /* starting at 1 rather then 0 */
|
||||
return sev;
|
||||
}
|
||||
/*=============================================================================*/
|
||||
static unsigned int subsystemFromText(const char *text)
|
||||
{
|
||||
int i;
|
||||
static const char *subText[] = {"sys",
|
||||
"com",
|
||||
"asquio",
|
||||
"io",
|
||||
"dev",
|
||||
"par",
|
||||
"notify",
|
||||
"history",
|
||||
"INVALID",
|
||||
};
|
||||
|
||||
for(i = 0; i < MAXSUB; i++){
|
||||
if(strcmp(subText[i],text) == 0){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void formatSubsystem(unsigned int sub, char *buffer, unsigned int bufferLength)
|
||||
{
|
||||
static const char *subText[] = {"sys",
|
||||
"com",
|
||||
"asquio",
|
||||
"io",
|
||||
"dev",
|
||||
"par",
|
||||
"notify",
|
||||
"history",
|
||||
"INVALID",
|
||||
};
|
||||
|
||||
if(sub > SPAR){
|
||||
sub = SINVALID;
|
||||
}
|
||||
strncpy(buffer,subText[sub],bufferLength);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
unsigned int logFilter(unsigned int severity, const char *subsystem)
|
||||
{
|
||||
int status;
|
||||
char buffer[1024];
|
||||
unsigned int sub;
|
||||
|
||||
if(logDisabled || logConfigured == 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If it is in the list of enabled subsystems, everything is logged
|
||||
*/
|
||||
sub = subsystemFromText(subsystem);
|
||||
if(sub >= 0 && severity <= logEnabledArray[sub]){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
test against the global log level
|
||||
*/
|
||||
if(severity > globalLogLevel){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
I wish to avoid excessive dynamic memory allocation in logging. Thus I pass
|
||||
in generous preallocated buffers and allocate only when the passed in buffer
|
||||
@ -251,7 +325,7 @@ void RemoveLogCallback(LogCallback func)
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void notifyListeners(unsigned int severity, const char *subsystem,
|
||||
char *timeStamp, char *logData)
|
||||
const char *timeStamp, char *logData)
|
||||
{
|
||||
int status;
|
||||
LogCBData lcb;
|
||||
@ -264,22 +338,52 @@ static void notifyListeners(unsigned int severity, const char *subsystem,
|
||||
}
|
||||
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void Log(unsigned int severity, const char *subsystem,const char *format,...)
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
static void LogInternal(char *timeText, unsigned int severity, const char *subsystem,
|
||||
char *logMessage)
|
||||
{
|
||||
char severityTXT[60], logLine[3072], *fullMessage = NULL;
|
||||
|
||||
checkLogFile();
|
||||
|
||||
formatSeverity(severity,severityTXT,sizeof(severityTXT));
|
||||
|
||||
notifyListeners(severity,subsystem,timeText, logMessage);
|
||||
|
||||
|
||||
if(logFilter(severity,subsystem) == 1){
|
||||
return;
|
||||
}
|
||||
|
||||
fullMessage = formatLogLine(timeText,severityTXT,subsystem,
|
||||
logMessage, logLine, sizeof(logLine));
|
||||
|
||||
writeLog(fullMessage);
|
||||
|
||||
|
||||
/*
|
||||
clean up
|
||||
*/
|
||||
if(fullMessage != logLine){
|
||||
free(fullMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...)
|
||||
{
|
||||
char severityTXT[60];
|
||||
char timeStamp[132];
|
||||
char logData[2024], logLine[3072], *pPtr = NULL;
|
||||
char *dynMessage = NULL, *logMessage, *fullMessage = NULL;
|
||||
char subText[30];
|
||||
char logData[2024], *logMessage = NULL;
|
||||
char *dynMessage = NULL;
|
||||
va_list ap;
|
||||
int dataLength;
|
||||
|
||||
|
||||
formatSeverity(severity,severityTXT,sizeof(severityTXT));
|
||||
formatSubsystem(subsystem,subText,sizeof(subText));
|
||||
formatTimeStamp(timeStamp,sizeof(timeStamp),0);
|
||||
|
||||
checkLogFile();
|
||||
|
||||
/*
|
||||
If we have enough space put the logData into our generous buffer. Else
|
||||
allocate a dynamic buffer. I cannot do this in a subroutine as I need to
|
||||
@ -299,89 +403,117 @@ void Log(unsigned int severity, const char *subsystem,const char *format,...)
|
||||
}
|
||||
}
|
||||
|
||||
notifyListeners(severity,subsystem,timeStamp, logMessage);
|
||||
LogInternal(timeStamp, severity, subText,logMessage);
|
||||
|
||||
|
||||
|
||||
if(logFilter(severity,subsystem) == 1){
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fullMessage = formatLogLine(timeStamp,severityTXT,subsystem,
|
||||
logMessage, logLine, sizeof(logLine));
|
||||
|
||||
writeLog(fullMessage);
|
||||
|
||||
|
||||
/*
|
||||
clean up
|
||||
*/
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
if(fullMessage != logLine){
|
||||
free(fullMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
static unsigned int sevFromText(const char *txt)
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
void LogTS(const char *timeStamp, unsigned int severity, unsigned int subsystem,const char *format,...)
|
||||
{
|
||||
static const char *severityText[] = {"fatal",
|
||||
"error",
|
||||
"warn",
|
||||
"info",
|
||||
"verbose",
|
||||
"debug",
|
||||
NULL
|
||||
};
|
||||
int sev = 0;
|
||||
while(severityText[sev] != NULL){
|
||||
if(strcmp(txt,severityText[sev]) == 0){
|
||||
break;
|
||||
char subText[30];
|
||||
char logData[2024], *logMessage = NULL;
|
||||
char *dynMessage = NULL;
|
||||
va_list ap;
|
||||
int dataLength;
|
||||
|
||||
|
||||
formatSubsystem(subsystem,subText,sizeof(subText));
|
||||
|
||||
/*
|
||||
If we have enough space put the logData into our generous buffer. Else
|
||||
allocate a dynamic buffer. I cannot do this in a subroutine as I need to
|
||||
restart the vararg stuff.
|
||||
*/
|
||||
va_start(ap,format);
|
||||
dataLength = vsnprintf(logData,sizeof(logData),format,ap);
|
||||
logMessage = logData;
|
||||
va_end(ap);
|
||||
if(dataLength > sizeof(logData)){
|
||||
dynMessage = malloc((dataLength+1)*sizeof(char));
|
||||
if(dynMessage != NULL){
|
||||
va_start(ap,format);
|
||||
vsnprintf(dynMessage,(dataLength+1)*sizeof(char),format,ap);
|
||||
va_end(ap);
|
||||
logMessage = dynMessage;
|
||||
}
|
||||
sev++;
|
||||
}
|
||||
sev++; /* starting at 1 rather then 0 */
|
||||
return sev;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void DisableSub(char *sub)
|
||||
{
|
||||
int status;
|
||||
char buffer[1024];
|
||||
|
||||
LogInternal((char *)timeStamp, severity, subText,logMessage);
|
||||
|
||||
status = LLDnodePtr2First(subList);
|
||||
while (status == 1) {
|
||||
LLDstringData(subList, buffer);
|
||||
if(strcmp(buffer,sub) == 0) {
|
||||
LLDstringDelete(subList);
|
||||
}
|
||||
status = LLDnodePtr2Next(subList);
|
||||
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void Log(unsigned int severity, const char *subsystem,const char *format,...)
|
||||
{
|
||||
char timeStamp[132];
|
||||
char logData[2024], *logMessage = NULL;
|
||||
char *dynMessage = NULL;
|
||||
va_list ap;
|
||||
int dataLength;
|
||||
|
||||
|
||||
formatTimeStamp(timeStamp,sizeof(timeStamp),0);
|
||||
|
||||
/*
|
||||
If we have enough space put the logData into our generous buffer. Else
|
||||
allocate a dynamic buffer. I cannot do this in a subroutine as I need to
|
||||
restart the vararg stuff.
|
||||
*/
|
||||
va_start(ap,format);
|
||||
dataLength = vsnprintf(logData,sizeof(logData),format,ap);
|
||||
logMessage = logData;
|
||||
va_end(ap);
|
||||
if(dataLength > sizeof(logData)){
|
||||
dynMessage = malloc((dataLength+1)*sizeof(char));
|
||||
if(dynMessage != NULL){
|
||||
va_start(ap,format);
|
||||
vsnprintf(dynMessage,(dataLength+1)*sizeof(char),format,ap);
|
||||
va_end(ap);
|
||||
logMessage = dynMessage;
|
||||
}
|
||||
}
|
||||
|
||||
LogInternal(timeStamp, severity, subsystem,logMessage);
|
||||
|
||||
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static pDynString ListEnabled(void)
|
||||
{
|
||||
int status;
|
||||
char buffer[1024];
|
||||
int status, i;
|
||||
char buffer[1024], sub[30], sev[30];
|
||||
pDynString result = CreateDynString(64,64);
|
||||
|
||||
if(result == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = LLDnodePtr2First(subList);
|
||||
while (status == 1) {
|
||||
LLDstringData(subList, buffer);
|
||||
DynStringConcat(result,buffer);
|
||||
|
||||
for(i = 0; i < MAXSUB; i++){
|
||||
formatSeverity(logEnabledArray[i],sev,sizeof(sev));
|
||||
formatSubsystem(i,sub,sizeof(sub));
|
||||
DynStringConcat(result,sub);
|
||||
DynStringConcatChar(result,':');
|
||||
status = LLDnodePtr2Next(subList);
|
||||
DynStringConcat(result,sev);
|
||||
DynStringConcatChar(result,'\n');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
The Interpreter Interface
|
||||
==============================================================================*/
|
||||
@ -417,7 +549,7 @@ static int LogAction(SConnection * pCon, SicsInterp * pSics,
|
||||
static int LogConfigAction(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
unsigned int sev;
|
||||
unsigned int sev, sub;
|
||||
char buffer[64];
|
||||
pDynString result = NULL;
|
||||
|
||||
@ -470,7 +602,13 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics,
|
||||
SCWrite(pCon,"ERROR: subsystem name to long",eError);
|
||||
return 0;
|
||||
}
|
||||
LLDstringAppend(subList,argv[2]);
|
||||
sub = subsystemFromText(argv[2]);
|
||||
if(sub >= 0){
|
||||
logEnabledArray[sub] = DEBUG;
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: invalid subsystem %s requested", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: need subsystem argument for enable",eError);
|
||||
@ -478,7 +616,12 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics,
|
||||
}
|
||||
}else if (strcmp(argv[1],"disable") == 0) {
|
||||
if(argc > 2){
|
||||
DisableSub(argv[2]);
|
||||
sub = subsystemFromText(argv[2]);
|
||||
if(sub >= 0){
|
||||
logEnabledArray[sub] = ERROR;
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: invalid subsystem %s requested", argv[2]);
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: need subsystem argument for disable",eError);
|
||||
@ -505,11 +648,16 @@ void DisableLog(void)
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void Logv2Init(void)
|
||||
{
|
||||
subList = LLDstringCreate();
|
||||
callbackList = LLDcreate(sizeof(LogCBData));
|
||||
int i;
|
||||
|
||||
callbackList = LLDcreate(sizeof(LogCBData));
|
||||
strcpy(logTemplate,"unconfiguredLogTemplate");
|
||||
|
||||
AddCmd("log", LogAction);
|
||||
AddCommand(pServ->pSics,"logconfig", LogConfigAction,
|
||||
LogClose, NULL);
|
||||
|
||||
for(i = 0; i < MAXSUB; i++){
|
||||
logEnabledArray[i] = ERROR;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user