开源日志库log4c存在的一个bug,程序重启后,每次都重新写新的文件,不是接在在原来的文件中写;

开源日志库log4c存在的一个bug,程序重启后,每次都重新写新的文件,不是接在在原来的文件中写;这样在ARM中应用时,当应用重启了,但是log0还没有达到maxsize,就切换了一个新的文件,会造成空间浪费,网上查了好久,log4c没有提供这样的接口,维护别人的代码,用到了log4c这个库,只能修改log4c的源码了。

源码修改的地方如下:

static int get_file_size(const char *filename)
{
   FILE*fp;
   
  if((fp=fopen(filename,"rb"))==NULL)
   {
      return -1;
   }
   
   fseek(fp, 0, SEEK_END);
   int len = ftell(fp);
   fseek(fp, 0, SEEK_SET);
   
   fclose(fp);

   return len;
}

/*******************************************************************************/

static int sizewin_rollover(log4c_rollingpolicy_t *this, FILE ** current_fpp ){
  int rc = 0;
  rollingpolicy_sizewin_udata_t *swup = log4c_rollingpolicy_get_udata(this);
  int k = 0;
  int i = 0;
 
  sd_debug("sizewin_rollover[");
  /* Starting at the last_index work back renaming the files and
     leaving space for the .0 file.
     If the last index is negative then it means the file doesn't exist
     so we create the first file
  */

  if ( !swup || !swup->sw_logdir){
    sd_error("rollingpolicy '%s' not yet configured (logdir,prefix etc.)",
      log4c_rollingpolicy_get_name(this));
  } else {
  
   swup->sw_last_index = sizewin_get_last_index(swup);  
   k = swup->sw_last_index;

   if ( k < 0 ) {
     sd_debug("creating first file");
     if (sizewin_open_zero_file(swup->sw_filenames[0], current_fpp,1)){
       swup->sw_flags |= SW_LAST_FOPEN_FAILED;
       sd_error("open zero file failed");
     } else{
       swup->sw_flags &= !SW_LAST_FOPEN_FAILED;
     }
     swup->sw_last_index = 0;
   } else {
     sd_debug("rolling up existing files");

     if ( k == swup->sw_conf.swc_file_max_num_files-1) {    
       if(unlink(swup->sw_filenames[k])){
          sd_error("unlink failed");
          rc = 1;
       } else {
         k = swup->sw_conf.swc_file_max_num_files-2;
       }
     } else {
       /* not yet reached the max num of files
	      * so there's still room to rotate the list up */    
     }

     /* If there's a current open fp, close it.*/
     if ( !(swup->sw_flags & SW_LAST_FOPEN_FAILED) && *current_fpp) {
       if(fclose(*current_fpp)){
         sd_error("failed to close current log file");
         rc = 1;
       }
     } else {
       if( (swup->sw_flags & SW_LAST_FOPEN_FAILED)){
           sd_debug("Not closing log file...last open failed");
       } else if (*current_fpp == 0) {
         sd_debug("No log file currentlty open...so not closing it");
       }else {
         sd_debug("Not closing current log file...not sure why");
       }
     }
     

     /* Now, rotate the list up if all seems ok, otherwise 
     * don't mess with teh files if something seems to have gone wrong
     */
     int new_file_flag=0;
     if ( !rc){
       sd_debug("rotate up , last index is %d", k);
       int len= get_file_size(swup->sw_filenames[0]);
       int max_len=swup->sw_conf.swc_file_maxsize/100000*100000;
       if(len>max_len ||len==-1)
       {
          i = k;
          while ( i >= 0 ) {
            sd_debug("Renaming %s to %s",
            swup->sw_filenames[i], swup->sw_filenames[i+1]);
            if(rename( swup->sw_filenames[i], swup->sw_filenames[i+1])){
            sd_error("rename failed"); 
            rc = 1;
           // break;
           }
           i--;
          }

         if ( !rc){
           swup->sw_last_index = k + 1;
          }
         new_file_flag=1;
      }

     } else {
       sd_debug("not rotating up--some file access error");
     }
         
     /* Now open up the 0'th file for writing */
     
     if (sizewin_open_zero_file(swup->sw_filenames[0], current_fpp,new_file_flag)){
       swup->sw_flags |= SW_LAST_FOPEN_FAILED;
       sd_error("open zero file failed");
       rc = 1;
     } else{
       swup->sw_flags &= !SW_LAST_FOPEN_FAILED;
       rc = 0;
     }

   }
   sd_debug("current file descriptor '%d'", fileno(*current_fpp));
  }
  sd_debug("]");
  return(rc);
}


 

static int sizewin_open_zero_file(char *filename, FILE **fpp,int flag ){
  int rc = 0;
  sd_debug("sizewin_open_zero_file['%s'", filename);
  if(flag)
  {
     *fpp = fopen(filename, "w+");
  }else
  {
     *fpp = fopen(filename, "a+");
  }

  if ( (*fpp) == NULL){
   sd_error("failed to open zero file '%s'--defaulting to stderr--error='%s'",
     filename, strerror(errno));   
   *fpp = stderr;
    rc = 1;
  }  
    
  /* unbuffered mode at the filesystem level
   xxx make this configurable from the outside ?
  */
  setbuf(*fpp, NULL);    

  sd_debug("]");  
  return(rc);

}


 

 

以下内容转自互联网,版权归原作者所有:

http://xueqi.iteye.com/blog/1570013

1.Log工具简单比较

Log4cpp & Log4CPlus:C++的日志库,可移植移性相对差些
Log4c:C的日志库,基本上都是一些纯c的东西,移植性较好

2.Log4c的基本概念
Log4c中有三个重要的概念, Category, Appender, Layout。
  Category用于区分不同的日志,在一个程序中我们可以通过Category来指定很多的日志。
  Appdender用于描述输出流,通过为Category来指定一个Appdender,可以决定将log信息来输出到什么地方去,比如stdout, stderr, rollingfile等等。
  Layout用于指定日志信息的格式,通过为Appender来指定一个Layout,可以决定log信息以何种格式来输出,比如是否有带有时间戳, 是否包含文件位置信息等,以及他们在一条log信息中的输出格式的等。
Category, Appender, Layout三者之间的关系,一个Category需要为其指定一个appender, 一个appender亦要为其指定一个layout。
另外,对于文件类型输出还有一个rollingpolicy。rollingpolicy用于描述文件输出的配置策略。

3.关于配置
配置文件示例如下:

<!DOCTYPE log4c SYSTEM "">
<log4c version="1.2.0">
  <config>
    <bufsize>0</bufsize>
    <debug level="0"/>
    <nocleanup>0</nocleanup>
  </config>
  
  <layout name="dated" type="dated_l"/>
  
  <!-- appenders ===================================== -->
    <appender name="LoadBusinessLog" type="rollingfile" logdir="../etc/log"
       prefix="LoadBusiness-" layout="dated_l" rollingpolicy="Policy1" />
 
    <appender name="CataRollingFileAppender" type="rollingfile" logdir="../etc/log/"
       prefix="testLog" layout="dated" rollingpolicy="RollingPolicy" />

    <!-- category ========================================= -->
    <category name="root" priority="notice"/>
    <category name="framework" priority="info" appender="FrameLog" />
    <category name="test.log" priority="trace" appender="CataRollingFileAppender" />

    <!-- policy ======================================= -->
    <rollingpolicy name="Policy1" type="timewin" timetype="1" maxnum="10" />
    <rollingpolicy name="RollingPolicy" type="sizewin" maxsize="102400" maxnum="10" />
</log4c>

3.1 category
name:日志的名称
priority:日志的优先级,共有fatal、alert、crit、error、warn、notice、info、debug、trace、notset和unknown11个级别,其级别逐步递增,记录在日志中的数据为小于等于指定级别的数据。
appender:输出流类型名称,为appender节点的name属性的值。

3.2 appender
name:输出流名称
type:输出流类型,共有stream、syslog、rollingfile三大类
layout:输出日志的格式的名称,为layout节点的name属性的值。
rollingpolicy:输出日志文件配置策略名称,为rollingpolicy节点的name属性的值。
rollingpolicy的timewin类型的日志输出为自定义类型

3.3 layout
name:输出日志的格式名称
type:输出日志格式的类型,共有base 、dated、dated_l等格式类型,对于自定义类型也有配置在这里,否则不能够加载。
base:%P %c - %m/n
     "%P" 日志信息的优先级
     "%c" 日志的名称
     "%m" 日志信息内容
dated:%d %P %c - %m/n
     "%d" 日志信息产生的时间,UTC格式yyyymmdd hh:mm:ss.mis
     "%P" 日志信息的优先级
     "%c" 日志的名称
     "%m" 日志信息内容
dated_l:%d %P %c - %m/n (源代码里面没有,自己增加的)
     "%d" 日志信息产生的时间,本地时间格式yyyymmdd hh:mm:ss
     "%P" 日志信息的优先级
     "%c" 日志的名称
     "%m"日志信息内容

3.4 rollingpolicy
name:日志文件输出的配置策略名称。
type:日志文件输出的配置策略的类型,有sizewin一种类型。
maxsize:输出日志文件的最大值。默认值为20KB
maxnum:保存的历史日志文件总数。默认值为5

3.5 配置文件的路径
${ LOG4C_RCPATH }/log4crc  //环境变量中设置的配置文件夹下log4crc
${HOME}/.log4crc       //HOME文件夹下log4crc
./log4crc          //当前可执行文件夹下log4crc

4、Log4c的基本使用

头文件 (直接引用log4c.h程序编译出错,因此只引用需要的头文件)
extern "C" {
#include <log4c/init.h>
#include <log4c/category.h>
}

cpp文件
//初始化
log4c_init();
//获取一个已有的category
log4c_category_t* mycat = log4c_category_get("cata.log ");
//用该category进行日志输出,优先级为DEBUG,输出信息为 "Hello World!"
log4c_category_log(mycat, LOG4C_PRIORITY_DEBUG, "Hello World!");
//析构
log4c_fini();

//在日志输出过程中可以进行格式化输出:
log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, "Error code = %d", 12345);
//对于格式化输出也可以有如下写法:
void CLog::Trace(const char * format, ... )
{
   if (log4c_category_is_priority_enabled(mycat, LOG4C_PRIORITY_TRACE))
   {
    a_list argptr;
    va_start(argptr, format);

    log4c_category_vlog(mycat, LOG4C_PRIORITY_TRACE, format, argptr);

    va_end(argptr);
   }
}

5.自定义Logout

5.1 添加在Log4c源代码中的流程


在log4c-1.2.0/src/文件夹添加相应的头文件和实现文件,如examplelayout.h和examplelayout.c文件
编辑log4c-1.2.0/src/log4c/Makefile.in
在am__liblog4c_la_SOURCES_DIST中添加examplelayout.c
在am_liblog4c_la_OBJECTS中添加examplelayout. lo
在liblog4c_la_SOURCES 中添加examplelayout.c
在pkginclude_HEADERS中添加 examplelayout.h
添加@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ examplelayout.Plo@am__quote@
编辑log4c-1.2.0/src/log4c/Makefile.am
在liblog4c_la_SOURCES中添加examplelayout.c
在pkginclude_HEADERS中添加examplelayout.h
编辑log4c-1.2.0/src/init.c
添加#include <examplelayout.h>
在static const log4c_layout_type_t * const layout_types[]数组中添加新添加的layout_type函数指针
5.2在工程中添加自定义日志格式
实现自定义格式的主要函数:

static const char* cat_format(
  const log4c_layout_t* a_layout,
  const log4c_logging_event_t*a_event)
{
  static char buffer[4096];

  /*
   * For this formatter we put the category up front in the log message
   */
  sprintf(buffer, "[%s][LINE:%d][FILE:%s] %s", a_event->evt_category,
    a_event->evt_loc->loc_line, a_event->evt_loc->loc_file, a_event->evt_msg);

  return buffer;
}

const log4c_layout_type_t log4c_layout_type_cat = {
  "test_cat",  //格式名称,用于配置文件的设置
  cat_format,  //格式定义函数
    

5.3将自定义格式添加到Log4c的配置中

int init_example_formatters()
{
  log4c_layout_type_set(&log4c_layout_type_cat);//自定义格式类型函数指针
}

  

5.4自定义格式的使用
//执行自定义格式初始化

init_example_formatters();
//执行Log4c的初始化
log4c_init();
……
  
  

#ff00806.自定义Appender

6.1实现自定义输出流的主要函数:

static int test_file_append(log4c_appender_t* a_appender,
        const log4c_logging_event_t* a_event)
{
  FILE* fp = log4c_appender_get_udata(a_appender);
  /*
   return fprintf(fp, "[%s] [%s] [%d] [%d] [%s] [%s] [%d]/n%s",
   log4c_appender_get_name(this),
   a_event->evt_category,
   a_event->evt_priority,
   a_event->evt_timestamp.tv_sec*1000000 + a_event->evt_timestamp.tv_usec,
   a_event->evt_msg,
   a_event->evt_loc->loc_file,
   a_event->evt_loc->loc_line,
   a_event->evt_rendered_msg);
  */
  return fprintf(fp, "%s/n", a_event->evt_rendered_msg);
}

static int test_open(log4c_appender_t* a_appender)
{
  FILE* fp = log4c_appender_get_udata(a_appender);
  
  if (fp)
   return 0;
  if ( (fp = fopen(log4c_appender_get_name(a_appender), "a+")) == NULL)
   fp = stderr;
  /* unbuffered mode */
  setbuf(fp, NULL);
  log4c_appender_set_udata(a_appender, fp);
  return 0;
}

static int test_close(log4c_appender_t* a_appender)
{
  FILE* fp = log4c_appender_get_udata(a_appender);
    return (fp ? fclose(fp) : 0);
}
const log4c_appender_type_t log4c_appender_type_test_file = {
  "test_file",    //输出流的名称,用于配置文件设置
   test_open,     //打开输出流的函数
   test_file_append, //给输出流追加日志信息的函数
   test_close,    //关闭输出流的函数
};
  

6.2将自定义输出流添加到Log4c的配置中

int init_example_appenders()
{
  log4c_appender_type_set (&log4c_appender_type_test_file);//自定义输出流类型的函数指针
}
  

6.3自定义输出流的使用

//执行自定义格式初始化
init_example_appenders();
//执行Log4c的初始化
log4c_init();
……

  

7.自定义rollingpolicy
源代码中有一个sizewin的rollingpolicy,是根据文件大小进行生成日志控制的。
在这里添加一个根据时间的控制日志输出的策略,实现代码如下:

7.1 rollingpolicy_type_timewin.h

#ifndef log4c_policy_type_timewin_h
#define log4c_policy_type_timewin_h


#include <log4c/defs.h>
#include <log4c/rollingpolicy.h>

__LOG4C_BEGIN_DECLS

LOG4C_API const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_timewin;

typedef struct __timewin_udata rollingpolicy_timewin_udata_t;

#define TIME_TYPE_HOUR 0
#define TIME_TYPE_DAY  1
#define TIME_TYPE_MONTH 2
#define TIME_TYPE_YEAR 3

#define ROLLINGPOLICY_TIME_DEFAULT_MAX_NUM_FILES   100
#define ROLLINGPOLICY_TIME_DEFAULT_FILE_TYPE     TIME_TYPE_DAY

LOG4C_API rollingpolicy_timewin_udata_t *timewin_make_udata(void);

LOG4C_API int timewin_udata_set_file_time_type(
               rollingpolicy_timewin_udata_t * swup,
         long time_type);
                                                        
LOG4C_API int timewin_udata_set_max_num_files(
               rollingpolicy_timewin_udata_t * swup,
             long max_num);
                             
LOG4C_API int timewin_udata_set_appender(
               rollingpolicy_timewin_udata_t * swup,
         log4c_appender_t* app);

__LOG4C_END_DECLS


#endif
  


7.2 rollingpolicy_type_timewin.c

  
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include <log4c/appender.h>
#include <log4c/rollingpolicy.h>
#include <log4c/rollingpolicy_type_timewin.h>

#include "appender_type_rollingfile.h"
#include <sd/malloc.h>
#include <sd/error.h>
#include <sd/sd_xplatform.h>
#include <sd/sprintf.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* Internal structs that defines the conf and the state info
* for an instance of the appender_type_rollingfile type.
*/  
struct __timewin_conf { 
 long swc_file_time_type;
 long swc_file_max_num_files;
};

struct __timewin_udata {
 struct __timewin_conf sw_conf;
 rollingfile_udata_t *sw_rfudata;
 const char *sw_logdir;
 const char *sw_files_prefix;
 char *sw_curfileflag;
 char *sw_prefileflag;
 int sw_flags;
};

/***************************************************************************/

static int timewin_init(log4c_rollingpolicy_t *this, rollingfile_udata_t* rfup);
static int timewin_rollover(log4c_rollingpolicy_t *this, FILE **current_fpp );
static int timewin_is_triggering_event(
          log4c_rollingpolicy_t *this,
          const log4c_logging_event_t* a_event,
          long current_file_size);
static int timewin_fini(log4c_rollingpolicy_t *this);

static char* timewin_get_filename(rollingpolicy_timewin_udata_t * swup);
static int timewin_check_update_fileflag(rollingpolicy_timewin_udata_t * swup);
static int timewin_open_file(char *filename, FILE **fpp );
static int timewin_copy_string(char** szDest, const char* src);

/*******************************************************************************
       Policy interface: init, is_triggering_event, rollover
*******************************************************************************/

static int timewin_is_triggering_event(
          log4c_rollingpolicy_t *this,
          const log4c_logging_event_t* a_event,
          long current_file_size){
 int decision = 0;
 rollingpolicy_timewin_udata_t *swup = log4c_rollingpolicy_get_udata(this);

 sd_debug("timewin_is_triggering_event[");

 decision = timewin_check_update_fileflag(swup);
  
 if (decision)
 {
  sd_debug("triggering event"); 
 }
 else
 {
  sd_debug("not triggering event");
 }

 sd_debug("]"); 

 return(decision);
}

/*******************************************************************************/

static int timewin_rollover(log4c_rollingpolicy_t *this, FILE ** current_fpp ){
  int rc = 0;
  rollingpolicy_timewin_udata_t *swup = log4c_rollingpolicy_get_udata(this);
  int k = 0;
  char * szFileName = NULL;

  sd_debug("timewin_rollover[");

  if ( !swup || !swup->sw_logdir){
    sd_error("rollingpolicy '%s' not yet configured (logdir,prefix etc.)",
    log4c_rollingpolicy_get_name(this));
  }
  else
  {
    k = swup->sw_flags;
 
    if (k > 0 || *current_fpp == NULL)
    {
      szFileName = timewin_get_filename(swup);
      if (*current_fpp)
      {
        if(fclose(*current_fpp)){
          sd_error("failed to close current log file");
          rc = 1;
        }
      }
      if (!rc && timewin_open_file(szFileName, current_fpp)){
        sd_error("open zero file failed");
      }
      free(szFileName);
    }
  }
  sd_debug("]");
  return(rc);
}

/*******************************************************************************/

static int timewin_init(log4c_rollingpolicy_t *this, rollingfile_udata_t *rfup){
 rollingpolicy_timewin_udata_t *swup = NULL;

 sd_debug("timewin_init[");
 if (!this){
  goto timewin_init_exit;
 }
 
 swup = log4c_rollingpolicy_get_udata(this);
 if ( swup == NULL ){
  swup = timewin_make_udata();
  log4c_rollingpolicy_set_udata(this, swup);
 }
 
 swup->sw_logdir = rollingfile_udata_get_logdir(rfup);
 swup->sw_files_prefix = rollingfile_udata_get_files_prefix(rfup);
 timewin_check_update_fileflag(swup);

timewin_init_exit:
 sd_debug("]");

 return(0);
}

/*******************************************************************************/

static int timewin_fini(log4c_rollingpolicy_t *this){
 rollingpolicy_timewin_udata_t *swup = NULL;
 int rc = 0;

 sd_debug("timewin_fini[ ");
 if (!this){
  goto timewin_fini_exit;
 }
 
 swup = log4c_rollingpolicy_get_udata(this);
 if (!swup){
  goto timewin_fini_exit;
 }

 if (swup->sw_curfileflag)
 {
    free(swup->sw_curfileflag);
 }
  
 if (swup->sw_prefileflag)
 {
    free(swup->sw_prefileflag);
 }
 
 swup->sw_flags = 0;

 /* logdir and files_prefix are just pointers into the rollingfile udata
 * so they are not ours to free--that will be done by the free call to
 * the rollingfile appender
 */
 sd_debug("freeing timewin udata from rollingpolicy instance");
 free(swup);
 log4c_rollingpolicy_set_udata(this,NULL);
 
timewin_fini_exit:
 sd_debug("]");
 
 return(rc);
}

/*******************************************************************************
              timewin specific conf functions
*******************************************************************************/

LOG4C_API rollingpolicy_timewin_udata_t *timewin_make_udata(void)
{
 rollingpolicy_timewin_udata_t *swup = NULL;
 swup = (rollingpolicy_timewin_udata_t *)sd_calloc(1,
               sizeof(rollingpolicy_timewin_udata_t));
 timewin_udata_set_file_time_type(swup,
         ROLLINGPOLICY_TIME_DEFAULT_FILE_TYPE);
  
 timewin_udata_set_max_num_files(swup,
                 ROLLINGPOLICY_TIME_DEFAULT_MAX_NUM_FILES);

 swup->sw_curfileflag = 0;
 swup->sw_prefileflag = 0;
 swup->sw_flags = 0;
 return(swup);

}

/*******************************************************************************/

LOG4C_API int timewin_udata_set_file_time_type(rollingpolicy_timewin_udata_t * swup,
           long time_type){

 swup->sw_conf.swc_file_time_type = time_type;

 return(0);
 
}

/****************************************************************************/

LOG4C_API int timewin_udata_set_max_num_files(rollingpolicy_timewin_udata_t *swup,
           long max_num){

 swup->sw_conf.swc_file_max_num_files = max_num;

 return(0);
}

/****************************************************************************/

LOG4C_API int timewin_udata_set_rfudata(rollingpolicy_timewin_udata_t *swup,
           rollingfile_udata_t *rfup ){

 swup->sw_rfudata = rfup;

 return(0);
}

/*****************************************************************************
            private functions
*****************************************************************************/

/****************************************************************************/
static char* timewin_get_filename(rollingpolicy_timewin_udata_t* swup){
 long filename_len = 0;
 char *s = NULL;
 filename_len = strlen(swup->sw_logdir) + 1 +
         strlen(swup->sw_files_prefix) + 1 + 15; // a margin /
 s = (char *)malloc(filename_len);   
 sprintf( s, "%s%s%s%s%s", swup->sw_logdir,
    FILE_SEP, swup->sw_files_prefix, swup->sw_curfileflag, ".log");     
 return(s);
}

/********************************************************************************/
static int timewin_check_update_fileflag(rollingpolicy_timewin_udata_t * swup)
{
  struct tm  tm;
  time_t timep;
  time(&timep);
  char buf[11];
  memset(buf, 0, 11);

#ifndef _WIN32
#ifndef __HP_cc
#warning gmtime() routine should be defined in sd_xplatform
#endif
  localtime_r(&timep, &tm);
#else
  /* xxx Need a CreateMutex/ReleaseMutex or something here
   */
  {
  struct tm *tmp = NULL;
  tmp = localtime(&timep);
  tm = *tmp; /* struct copy */
  }
#endif
  swup->sw_flags = 0;
  switch (swup->sw_conf.swc_file_time_type)
  {
  case TIME_TYPE_YEAR:
    sprintf(buf, "%04d", tm.tm_year + 1900);
    break;
  case TIME_TYPE_MONTH:
    sprintf(buf, "%04d%02d", tm.tm_year + 1900, tm.tm_mon + 1);
    break;
  case TIME_TYPE_DAY:
    sprintf(buf, "%04d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
    break;
  case TIME_TYPE_HOUR:
    sprintf(buf, "%04d%02d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour);
    break;
  default:
    sprintf(buf, "%04d%02d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour);
    break;
  }
  
  if (swup->sw_curfileflag == NULL)
  {
    timewin_copy_string(&swup->sw_curfileflag, buf);
    swup->sw_flags = 1;
  }
  else if (strcmp(swup->sw_curfileflag, buf) != 0)
  {
    timewin_copy_string(&swup->sw_prefileflag, swup->sw_curfileflag);
    timewin_copy_string(&swup->sw_curfileflag, buf);
    swup->sw_flags = 1;
  }
  
  return swup->sw_flags;
}

/******************************************************************************/
static int timewin_copy_string(char** szDest, const char* src)
{
  int len = 0;
  if (src == 0)
  {
    return -1;
  }
  len = strlen(src) + 1;

  if (*szDest == NULL)
  {
    * szDest = (char *)malloc(len);
  }
  else if (strlen(*szDest) < len)
  {
    free(*szDest);
    * szDest = (char *)malloc(len);
    memset(*szDest, 0, len);
  }
  memcpy(* szDest, src, len);
  return 0;
}

/*******************************************************************************/

static int timewin_open_file(char *filename, FILE **fpp ){
 int rc = 0;
 sd_debug("timewin_open_file['%s'", filename);

 if ( (*fpp = fopen(filename, "a+")) == NULL){
  sd_error("failed to open file '%s'--defaulting to stderr--error='%s'",
      filename, strerror(errno));  
  *fpp = stderr;
  rc = 1;
 } 
  
 /* unbuffered mode at the filesystem level
  xxx make this configurable from the outside ?
 */
 setbuf(*fpp, NULL);  

 sd_debug("]"); 

 return(rc);

}

/****************************************************************************/

const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_timewin = {
  "timewin",
  timewin_init,
  timewin_is_triggering_event,
  timewin_rollover,
  timewin_fini
};

  


7.3 init.c

#ifdef WITH_ROLLINGFILE
static const log4c_rollingpolicy_type_t * const rollingpolicy_types[] = {
  &log4c_rollingpolicy_type_sizewin,
  &log4c_rollingpolicy_type_timewin
};
static size_t nrollingpolicy_types =
  sizeof(rollingpolicy_types) / sizeof(rollingpolicy_types[0]);
#endif

rc.c

#ifdef WITH_ROLLINGFILE
/******************************************************************************/
static int rollingpolicy_load(log4c_rc_t* this, sd_domnode_t* anode)
{
  sd_domnode_t*  name  = sd_domnode_attrs_get(anode, "name");
  sd_domnode_t*  type  = sd_domnode_attrs_get(anode, "type");
  log4c_rollingpolicy_t* rpolicyp = NULL;
  
  sd_debug("rollingpolicy_load[");
  if (!name) {
  sd_error("attribute /"name/" is missing");
  return -1;
  }

  rpolicyp = log4c_rollingpolicy_get(name->value);  


  if (type){
  log4c_rollingpolicy_set_type(rpolicyp,
       log4c_rollingpolicy_type_get(type->value));
  
   if (!strcasecmp(type->value, "sizewin")){
    sd_domnode_t*  maxsize  = sd_domnode_attrs_get(anode, "maxsize");
    sd_domnode_t*  maxnum = sd_domnode_attrs_get(anode, "maxnum");
    rollingpolicy_sizewin_udata_t *sizewin_udatap = NULL;
    
    sd_debug("type='sizewin', maxsize='%s', maxnum='%s', "
         "rpolicyname='%s'",
      (maxsize && maxsize->value ? maxsize->value :"(not set)"),
      (maxnum && maxnum->value ? maxnum->value :"(not set)"),
      (name && name->value ? name->value :"(not set)"));
    /*
     * Get a new sizewin policy type and configure it.
     * Then attach it to the policy object.
     * Check to see if this policy already has a
     sw udata object. If so, leave as is except update
     the params
    */
    if ( !(sizewin_udatap = log4c_rollingpolicy_get_udata(rpolicyp))){
     sd_debug("creating new sizewin udata for this policy");
     sizewin_udatap = sizewin_make_udata();
     log4c_rollingpolicy_set_udata(rpolicyp,sizewin_udatap); 
     sizewin_udata_set_file_maxsize(sizewin_udatap, atoi(maxsize->value));
    sizewin_udata_set_max_num_files(sizewin_udatap, atoi(maxnum->value));
    }else{
     sd_debug("policy already has a sizewin udata--just updating params");
    sizewin_udata_set_file_maxsize(sizewin_udatap, atoi(maxsize->value));
    sizewin_udata_set_max_num_files(sizewin_udatap, atoi(maxnum->value));
     /* allow the policy to initialize itself */
    log4c_rollingpolicy_init(rpolicyp,
      log4c_rollingpolicy_get_rfudata(rpolicyp));
    }    
   }
   else if (!strcasecmp(type->value, "timewin")){
    sd_domnode_t*  timetype  = sd_domnode_attrs_get(anode, "timetype");
    sd_domnode_t*  maxnum = sd_domnode_attrs_get(anode, "maxnum");
    rollingpolicy_timewin_udata_t *timewin_udatap = NULL;
    
    sd_debug("type='timewin', timetype='%s', maxnum='%s', "
         "rpolicyname='%s'",
      (timetype && timetype->value ? timetype->value :"(not set)"),
      (maxnum && maxnum->value ? maxnum->value :"(not set)"),
      (name && name->value ? name->value :"(not set)"));
    /*
     * Get a new sizewin policy type and configure it.
     * Then attach it to the policy object.
     * Check to see if this policy already has a
     sw udata object. If so, leave as is except update
     the params
    */
    if ( !(timewin_udatap = log4c_rollingpolicy_get_udata(rpolicyp))){
     sd_debug("creating new sizewin udata for this policy");
     timewin_udatap = timewin_make_udata();
     log4c_rollingpolicy_set_udata(rpolicyp,timewin_udatap); 
     timewin_udata_set_file_time_type(timewin_udatap, atoi(timetype->value));
     timewin_udata_set_max_num_files(timewin_udatap, atoi(maxnum->value));
    }else{
     sd_debug("policy already has a sizewin udata--just updating params");
    timewin_udata_set_file_time_type(timewin_udatap, atoi(timetype->value));
    timewin_udata_set_max_num_files(timewin_udatap, atoi(maxnum->value));
     /* allow the policy to initialize itself */
    log4c_rollingpolicy_init(rpolicyp,
      log4c_rollingpolicy_get_rfudata(rpolicyp));
    }    
   
   }
  
  }
  sd_debug("]");

  return 0;
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值