Commit bc038ca1 authored by Marc Ariberti's avatar Marc Ariberti

Done a new logging system (easily adaptable to the new vlcs)

* logmethod has been removed
* logs are sent to a list of outputs (with a type for each)
* only one logfile can be used because of the way config is managed now
* log outputs are referenced by their FILE* (for removing for eg)
* it allows telnetd to draw logs on its ouput using FIFOs
parent 7e2309bf
......@@ -9,6 +9,7 @@ N: Marc Ariberti
E: marcari@via.ecp.fr
C: marcari
D: communication with vlc
D: logger
N: Brieuc Jeunhomme
E: bbp@via.ecp.fr
......
......@@ -3,6 +3,8 @@
#==========================#
HEAD
* Changed the logger system : now there's a list of logging output
referenced by their FILE* associated with a format type (screen/file)
*
0.0.1
......
......@@ -26,7 +26,7 @@ Difficulty: Easy
Urgency: Normal
Description: LOG: Wrapping
Wrap lines to 80 char.
Status: Done
Status: Done, Marcari
Task: 0x0c
Difficulty: Medium
......
......@@ -3,7 +3,7 @@
* Generate a parser for the config file
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: config.fl,v 1.20 2001/05/15 22:57:23 marcari Exp $
* $Id: config.fl,v 1.21 2001/05/20 23:12:05 marcari Exp $
*
* Authors: Brieuc Jeunhomme <bbp@via.ecp.fr>
*
......@@ -104,7 +104,7 @@ DNS ([A-Za-z0-9-]+[.])*[A-Za-z0-9-]+[.]*
logfile{BL}{NONBLANK}+ {
log{BL}output{BL}file{BL}{NONBLANK}+ {
if (cfg->logfile!=NULL)
{
VS_log(LOGERROR,CFG,"Parse error in %s on line %u : duplicated "\
......@@ -121,26 +121,17 @@ logfile{BL}{NONBLANK}+ {
}
memcpy(cfg->logfile,CFG_yytext+ui1,CFG_yyleng-ui1);
cfg->logfile[CFG_yyleng-ui1]=0;
}
}
logmethod{BL}{INT} {
if (cfg->logmethod)
log{BL}output{BL}screen {
if (cfg->logscreen)
{
VS_log(LOGERROR,CFG,"Parse error in %s on line %u : logmethod has "\
"already been defined",filename,line_num);
return VS_R_PARSE;
VS_log(LOGERROR,CFG,"Parse error in %s on line %u : logscreen has "\
"already been defined",filename,line_num);
}
sscanf(CFG_yytext+sizeof("logmethod")/sizeof(char)-1," %lu",&ul1);
if (ul1>LOG_BOTH)
{
VS_log(LOGERROR,CFG,"Parse error in %s on line %u : logmethod out "\
"of range",filename,line_num);
return VS_R_PARSE;
}
cfg->logmethod=ul1;
cfg->logscreen=1;
}
nchannels{BL}{INT} {
......
......@@ -3,7 +3,7 @@
* Header file for config.c (once generated)
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: config.h,v 1.6 2001/04/29 03:41:49 nitrox Exp $
* $Id: config.h,v 1.7 2001/05/20 23:12:05 marcari Exp $
*
* Authors: Brieuc Jeunhomme <bbp@via.ecp.fr>
*
......@@ -85,7 +85,7 @@ struct VS_config
char *vlanbridge_login; /* the login on the vlanbridge */
char *vlanbridge_password; /* the password on the vlanbridge */
char *logfile; /* the file where we will log */
unsigned char logmethod; /* the log method we will use */
unsigned char logscreen; /* the log to screen if !=0 */
};
/* parses the command line arguments and the configuration file, just feed it
......
# vlanserver's configuration file
logmethod 3 # 2 means Screen
# 1 means File
# 0 means none
# add the numbers to have more than one output
log output screen # enables log to screen
log output file test.log # the name of the file where to log
# warning : for instance one output file at most is accepted
# it will be changed in the new vlcs
logfile test.log # the name of the file where to log
nchannels 7 # the number of channels, they will range from 0 to 6
......
......@@ -3,7 +3,7 @@
* Print a log to a file or to screen
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: logger.c,v 1.18 2001/05/15 22:57:23 marcari Exp $
* $Id: logger.c,v 1.19 2001/05/20 23:12:05 marcari Exp $
*
* Authors: Damien Lucas <nitrox@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
......@@ -27,20 +27,21 @@
#include <stdarg.h> /* va_arg */
#include <time.h> /* time */
#include <stdio.h> /* fflush , ... */
#include <stdlib.h>
#include "types.h"
#include "logger.h"
/* Local Functions prototypes */
static FILE * fdLogFile;
static unsigned char method;
static pthread_mutex_t ptmLogFile;
static pthread_mutex_t ptmLogScreen;
#define FALSE 0
#define TRUE 1
/* Local Functions prototypes */
static struct LOG_stream * ls_none;
static pthread_mutex_t ptm_log_available;
static int is_log_available=FALSE;
/*****************************************************************************
......@@ -48,6 +49,7 @@ static pthread_mutex_t ptmLogScreen;
*****************************************************************************/
static void VS_log_File(LOG_LEVELS level,
LOG_MODULES module,
struct LOG_stream * output_stream,
char* format,
va_list ap)
{
......@@ -137,23 +139,23 @@ static void VS_log_File(LOG_LEVELS level,
sprintf(FooterBuff,"\n");
pthread_mutex_lock(&ptmLogFile);
fputs(HeaderBuff, fdLogFile);
pthread_mutex_lock(&output_stream->ptm_log);
fputs(HeaderBuff, output_stream->fd_output);
MessageLength = strlen(MsgBuff);
MessagePosition = 0;
while ( (MessageLength-MessagePosition) > LOGBUFF_LINESIZE )
{
snprintf( LineBuff, LOGBUFF_LINESIZE+1, MsgBuff + MessagePosition );
fputs( LineBuff, fdLogFile );
fputs( "\n ", fdLogFile );
fputs( LineBuff, output_stream->fd_output );
fputs( "\n ", output_stream->fd_output );
MessagePosition += LOGBUFF_LINESIZE;
}
fputs( MsgBuff + MessagePosition, fdLogFile);
fputs( MsgBuff + MessagePosition, output_stream->fd_output);
fputs(FooterBuff, fdLogFile);
fflush(fdLogFile);
pthread_mutex_unlock(&ptmLogFile);
fputs(FooterBuff, output_stream->fd_output);
fflush(output_stream->fd_output);
pthread_mutex_unlock(&output_stream->ptm_log);
#ifndef DEBUG
}
......@@ -167,6 +169,7 @@ static void VS_log_File(LOG_LEVELS level,
*****************************************************************************/
static void VS_log_Screen(LOG_LEVELS level,
LOG_MODULES module,
struct LOG_stream * output_stream,
char* format,
va_list ap)
{
......@@ -264,26 +267,25 @@ static void VS_log_Screen(LOG_LEVELS level,
#else
sprintf(FooterBuff,"\n");
#endif
pthread_mutex_lock(&ptmLogScreen);
/* Now the message is completely build, it can be displayed */
fputs( HeaderBuff, stderr );
pthread_mutex_lock(&output_stream->ptm_log);
fputs(HeaderBuff, output_stream->fd_output);
MessageLength = strlen(MsgBuff);
MessagePosition = 0;
while ( (MessageLength-MessagePosition) > LOGBUFF_LINESIZE )
{
snprintf( LineBuff, LOGBUFF_LINESIZE+1, MsgBuff + MessagePosition );
fputs( LineBuff, stderr );
fputs( "\n ", stderr );
fputs( LineBuff, output_stream->fd_output );
fputs( "\n ", output_stream->fd_output );
MessagePosition += LOGBUFF_LINESIZE;
}
fputs( MsgBuff + MessagePosition, stderr);
fputs(FooterBuff, stderr);
fputs( MsgBuff + MessagePosition, output_stream->fd_output);
pthread_mutex_unlock(&ptmLogScreen);
fputs(FooterBuff, output_stream->fd_output);
fflush(output_stream->fd_output);
pthread_mutex_unlock(&output_stream->ptm_log);
#ifndef DEBUG
}
#endif
......@@ -297,17 +299,31 @@ static void VS_log_Screen(LOG_LEVELS level,
*****************************************************************************/
void VS_log(LOG_LEVELS level, LOG_MODULES module, char* format, ...)
{
va_list ap;
struct LOG_stream * ls_current=ls_none->next_stream;
va_list ap;
va_start(ap,format);
if (method & LOG_FILE)
/* check whether the logging system is available or not */
pthread_mutex_lock(&ptm_log_available);
if (is_log_available==FALSE)
{
VS_log_File(level, module,format,ap);
return;
}
pthread_mutex_unlock(&ptm_log_available);
if (method & LOG_SCREEN)
while(ls_current != NULL)
{
VS_log_Screen(level, module,format,ap);
switch(ls_current->type)
{
case LOGTYPE_FILE:
VS_log_File(level, module, ls_current, format, ap);
break;
case LOGTYPE_SCREEN:
VS_log_Screen(level, module, ls_current, format, ap);
break;
default:
}
ls_current=ls_current->next_stream;
}
va_end(ap);
......@@ -316,13 +332,17 @@ void VS_log(LOG_LEVELS level, LOG_MODULES module, char* format, ...)
/*****************************************************************************
* Open the log file
* Open a log file
******************
* opens a new file for logging and returns if no error the file descriptor
* in order to be able to close it later
*****************************************************************************/
int OpenLogFile (char * sLogName)
FILE * LOG_file (char * sLogName)
{
int iRc;
FILE * fdLogFile;
iRc=0;
if( !(fdLogFile = fopen (sLogName, "w+")))
{
iRc=1;
......@@ -330,15 +350,22 @@ int OpenLogFile (char * sLogName)
}
else
{
/* Init the mutex */
iRc = pthread_mutex_init (&ptmLogFile, NULL);
LOG_create(fdLogFile, LOGTYPE_FILE);
}
if (iRc==1)
{
return NULL;
}
else
{
return fdLogFile;
}
return iRc;
}
#if 0
/*****************************************************************************
* Close the LogFile
*****************************************************************************/
......@@ -365,7 +392,7 @@ int CloseLogFile ()
}
#endif
/*****************************************************************************
......@@ -373,87 +400,117 @@ int CloseLogFile ()
*****************************************************************************
* TODO Gestion d'erreurs
*****************************************************************************/
int LOG_init(char * sLogName, unsigned char ucM)
int LOG_init()
{
method=0;
if (ucM!=LOG_NONE)
/* initialization of the logs chain */
ls_none = malloc(sizeof(struct LOG_stream));
if(ls_none==NULL)
{
if (ucM & LOG_SCREEN)
{
method |= LOG_SCREEN;
pthread_mutex_init(&ptmLogScreen, NULL);
VS_log(LOGINFO, LOGGER, "Logs inited on screen");
}
if (ucM & LOG_FILE)
{
method |= LOG_FILE;
OpenLogFile(sLogName);
VS_log(LOGINFO, LOGGER, "Logs inited with file : %s", sLogName);
}
return(-1);
}
ls_none->fd_output=NULL;
ls_none->type=LOGTYPE_NONE;
ls_none->next_stream=NULL;
pthread_mutex_init(&ptm_log_available, NULL);
is_log_available=TRUE;
return 0;
}
/*****************************************************************************
* LOG_change() : Change the log method
* LOG_create : add a new log output to the list
*****************************************************************************
* Note that if no method change is ask, LogFile could have change ...
* TODO Error Checking
*
*****************************************************************************/
int LOG_change(char * sLogName, unsigned char ucM)
int LOG_create(FILE * output_stream, int type)
{
int old_method = method;
method = 0; /* reinit the log method */
/*
* Deals with the logs on file
*/
if (old_method & LOG_FILE)
{ /* if a log file was opened : close it */
CloseLogFile();
}
if (ucM & LOG_FILE)
{ /* open a log file if requested */
OpenLogFile(sLogName);
method |= LOG_FILE;
VS_log(LOGINFO,LOGGER,"Logs inited with file: %s",sLogName);
}
struct LOG_stream * ls_new;
struct LOG_stream * ls_current;
/*
* Deals with the logs on screen
*/
if (ucM & LOG_SCREEN)
ls_new = malloc(sizeof(struct LOG_stream));
if (ls_new==NULL)
{
if ( !(old_method & LOG_SCREEN) )
{ /* if the log on screen wasn't already inited */
pthread_mutex_init(&ptmLogScreen, NULL);
}
method |= LOG_SCREEN;
VS_log(LOGINFO,LOGGER,"Logs inited on screen");
return(-1);
}
else
ls_new->fd_output=output_stream;
ls_new->type=type;
pthread_mutex_init( &(ls_new->ptm_log), NULL );
ls_new->next_stream=NULL;
/* inserts the new log stream et the end of the queue */
ls_current=ls_none;
while(ls_current->next_stream!=NULL)
{
if ( old_method & LOG_SCREEN )
{ /* if it is requested to stop screen logging, stop it ! */
pthread_mutex_destroy(&ptmLogScreen);
}
ls_current=ls_current->next_stream;
}
ls_current->next_stream = ls_new;
return 0;
}
/**********
* LOG_delete : removes a log output from the list
************
*
************/
int LOG_delete(FILE * output_stream)
{
struct LOG_stream * ls_current;
struct LOG_stream * ls_previous;
/* searches for the log stream */
ls_previous=NULL;
ls_current=ls_none;
while (ls_current->fd_output!=output_stream)
{
ls_previous=ls_current;
ls_current=ls_current->next_stream;
if (ls_current==NULL)
{ /* error : log stream not found */
return -1;
}
}
ls_previous->next_stream=ls_current->next_stream;
pthread_mutex_destroy(&ls_current->ptm_log);
free(ls_current);
return 0;
}
/****************************************************************************
* LOG_close() : Close the log process
* LOG_close() : terminates le the log system
****************************************************************************
* TODO Write a maybe more complete function.
* DONE
****************************************************************************/
int LOG_close()
{
/* switch back to the no-logs option*/
return LOG_change(NULL, LOG_NONE);
struct LOG_stream * ls_current;
struct LOG_stream * ls_next;
VS_log(LOGINFO, SERVER, "Terminating log system");
pthread_mutex_lock(&ptm_log_available);
is_log_available=FALSE;
pthread_mutex_unlock(&ptm_log_available);
ls_current=ls_none;
while (ls_current != NULL)
{
ls_next=ls_current->next_stream;
pthread_mutex_destroy(&ls_current->ptm_log);
free(ls_current);
ls_current=ls_next;
}
return 0;
}
/****************************************************************************
......
......@@ -3,9 +3,10 @@
* Header file for logger.c
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: logger.h,v 1.11 2001/05/15 22:57:23 marcari Exp $
* $Id: logger.h,v 1.12 2001/05/20 23:12:05 marcari Exp $
*
* Authors: Damien Lucas <nitrox@via.ecp.fr>
* Marc Ariberti <marcari@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -25,19 +26,36 @@
#ifndef __LOGGER_H__
#define __LOGGER_H__
/* Methods for logger */
#define LOG_NONE 0
#define LOG_FILE 1
#define LOG_SCREEN 2
#define LOGBUFF_MAXSIZE 460
#define LOGBUFF_LINESIZE 46
/* different types the LOG can be */
#define LOGTYPE_NONE 0
#define LOGTYPE_FILE 1
#define LOGTYPE_SCREEN 2
/* Structure that represents a log stream :
* there is one structure for each log output
* the different output are chained
* the root element is ls_none
* the last element has next_stream=NULL
* no log is caracterized by : ls_none.next_stream==NULL
* */
struct LOG_stream
{
FILE * fd_output;
int type;
pthread_mutex_t ptm_log;
struct LOG_stream * next_stream;
};
char * VS_log_errstr(ERR_CODE err);
void VS_log(LOG_LEVELS level, LOG_MODULES module, char * format, ...);
int LOG_init(char * sLogName, unsigned char ucM);
int LOG_change(char * sLogName, unsigned char ucM);
int LOG_init();
int LOG_create(FILE * , int type);
int LOG_delete(FILE *);
int LOG_close();
FILE * LOG_file(char * filename);
#endif
......@@ -3,7 +3,7 @@
* Init of the VLANserver
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: types.c,v 1.22 2001/05/15 22:57:23 marcari Exp $
* $Id: types.c,v 1.23 2001/05/20 23:12:05 marcari Exp $
*
* Authors: Brieuc Jeunhomme <bbp@via.ecp.fr>
*
......@@ -33,6 +33,7 @@
#include <ucd-snmp/snmp_api.h> /* if_snmp.h */
#include <ucd-snmp/snmp_client.h> /* if_snmp.h */
#include <ucd-snmp/mib.h> /* if_snmp.h */
#include <signal.h>
#include "types.h"
#include "logger.h"
......@@ -45,47 +46,70 @@
#include "interface/interface.h" /* IF_start */
#include "vlanserver.h" /* vs */
static void VS_finish(int);
unsigned int VS_init(int argc,char *argv[])
{
ERR_CODE grumpf;
signal(SIGINT, VS_finish); /* arrange interrupts to terminate */
grumpf=pthread_mutex_init(&(vs->cnx_lock),NULL);
// Initializing the log process
// with screen only because we don't know yet the logfile
LOG_init(NULL,LOG_SCREEN_ONLY);
/* Initializing the log process */
/* with screen only because we don't know yet the logfile */
LOG_init();
LOG_create(stderr, LOGTYPE_SCREEN);
// Initializing the DataBase
/* Initializing the DataBase */
grumpf=DB_start(vs->db);
if (grumpf)
return grumpf;
// Initializing the interface
/* Initializing the interface */
grumpf=IF_start();
if(grumpf)
return grumpf;
// Initializing the SNMP
/* Initializing the SNMP */
vs->snmp->sem=malloc(sizeof(sem_t));
sem_init(vs->snmp->sem,0,0);
grumpf=SNMP_start(vs->snmp);
if (grumpf)
return grumpf;
// Reading configuration file
/* Reading configuration file */
grumpf=CFG_init(vs->cfg,argc,argv);
if (grumpf)
return grumpf;
// Change the logprocess
// with method and logFile we asked for
LOG_change(vs->cfg->logfile, vs->cfg->logmethod);
/* creating logging output */
/* XXX : the fd returned is still ignored, please fix it */
if (vs->cfg->logscreen==0)
{
LOG_delete(stderr);
}
if (vs->cfg->logfile!=NULL)
{
LOG_file(vs->cfg->logfile);
}
// Starting the server
/* Starting the server */
grumpf=VS_start();
if (grumpf)
return grumpf;
LOG_close();
return 0;
}
/* it is the callback called when ctrl-C is pressed *
* it is a big kludge because I don't know how to *
* do it : someone should correct this */
static void VS_finish(int sig)
{
VS_stop(vs->info_poller);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment