static const char version[] = "1.2.1"; /* * appender.c * * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. * * See the COPYING file for the terms of usage and distribution. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include struct __log4c_appender { char* app_name; const log4c_layout_t* app_layout; const log4c_appender_type_t* app_type; int app_isopen; void* app_udata; }; sd_factory_t* log4c_appender_factory = NULL; ////////////////////////////////////////////////////////////////////////// ///以下为jesse修改的代码,将原有代码用#if 0...#endif注释掉 // 为解决log4c_layout_types中内存泄漏而将静态局部变量提升为全局局部变量 [9/8/2008 jesse] static sd_hash_t* gs_types = NULL; static sd_hash_t* log4c_appender_types(void) { ///static sd_hash_t* types = NULL; if (!gs_types) gs_types = sd_hash_new(20, NULL); return gs_types; } /** 删除本appender.c文件中定义的全局和静态的指针指向的内存,防止内存泄漏 如: 1.gs_types. 2. @return void. 作者:jesse 日期:2008.09.08 */ extern void log4c_appender_delete_global() { if (NULL != gs_types) { sd_hash_delete(gs_types); gs_types = NULL; } } ////////////////////////////////////////////////////////////////////////// #if 0 /** * @bug log4c_appender_type hash is not freed in destructor */ /*******************************************************************************/ static sd_hash_t* log4c_appender_types(void) { static sd_hash_t* types = NULL; if (!types) types = sd_hash_new(20, NULL); return types; } #endif extern void log4c_appender_types_print(FILE *fp) { sd_hash_iter_t* i; fprintf(fp, "appender types:"); for (i = sd_hash_begin(log4c_appender_types()); i != sd_hash_end(log4c_appender_types()); i = sd_hash_iter_next(i) ) { fprintf(fp, "'%s' ",((log4c_appender_type_t *)(i->data))->name ); } fprintf(fp, "\n"); } /*******************************************************************************/ extern const log4c_appender_type_t* log4c_appender_type_get(const char* a_name) { sd_hash_iter_t* i; if (!a_name) return NULL; if ( (i = sd_hash_lookup(log4c_appender_types(), a_name)) != NULL) return (log4c_appender_type_t*)i->data; return NULL; } /*******************************************************************************/ extern const log4c_appender_type_t* log4c_appender_type_set( const log4c_appender_type_t* a_type) { sd_hash_iter_t* i = NULL; void* previous = NULL; if (!a_type) return NULL; if ( (i = sd_hash_lookadd(log4c_appender_types(), a_type->name)) == NULL) return NULL; previous = i->data; i->data = (void*) a_type; return (log4c_appender_type_t*)previous; } /*******************************************************************************/ extern log4c_appender_t* log4c_appender_get(const char* a_name) { static const sd_factory_ops_t log4c_appender_factory_ops = { /*(void*) log4c_appender_new, (void*) log4c_appender_delete, (void*) log4c_appender_print,*/ (void *( *)(const char *))log4c_appender_new, (void ( *)(void *))log4c_appender_delete, (void ( *)(void *,FILE *))log4c_appender_print }; if (!log4c_appender_factory) { log4c_appender_factory = sd_factory_new("log4c_appender_factory", &log4c_appender_factory_ops); /* build default appenders */ log4c_appender_set_udata(log4c_appender_get("stderr"), stderr); log4c_appender_set_udata(log4c_appender_get("stdout"), stdout); } return (log4c_appender_t *)sd_factory_get(log4c_appender_factory, a_name); } /*******************************************************************************/ extern log4c_appender_t* log4c_appender_new(const char* a_name) { log4c_appender_t* ptrThis; if (!a_name) return NULL; ptrThis = (log4c_appender_t*)sd_calloc(1, sizeof(log4c_appender_t)); ptrThis->app_name = sd_strdup(a_name); ptrThis->app_type = &log4c_appender_type_stream; ptrThis->app_layout = log4c_layout_get("basic"); ptrThis->app_isopen = 0; ptrThis->app_udata = NULL; return ptrThis; } /*******************************************************************************/ extern void log4c_appender_delete(log4c_appender_t* ptrThis) { sd_debug("log4c_appender_delete['%s'", (ptrThis && ptrThis->app_name ? ptrThis->app_name: "(no name)")); if (!ptrThis){ goto log4c_appender_delete_exit; } log4c_appender_close(ptrThis); if (ptrThis->app_name){ free(ptrThis->app_name); } free(ptrThis); log4c_appender_delete_exit: sd_debug("]"); } /*******************************************************************************/ extern const char* log4c_appender_get_name(const log4c_appender_t* ptrThis) { return (ptrThis ? ptrThis->app_name : "(nil)"); } /*******************************************************************************/ extern const log4c_appender_type_t* log4c_appender_get_type( const log4c_appender_t* ptrThis) { return (ptrThis ? ptrThis->app_type : NULL); } /*******************************************************************************/ extern const log4c_layout_t* log4c_appender_get_layout(const log4c_appender_t* ptrThis) { return (ptrThis ? ptrThis->app_layout : NULL); } /*******************************************************************************/ extern void* log4c_appender_get_udata(const log4c_appender_t* ptrThis) { return (ptrThis ? ptrThis->app_udata : NULL); } /*******************************************************************************/ extern const log4c_appender_type_t* log4c_appender_set_type( log4c_appender_t* ptrThis, const log4c_appender_type_t* a_type) { const log4c_appender_type_t* previous; if (!ptrThis) return NULL; previous = ptrThis->app_type; ptrThis->app_type = a_type; return previous; } /*******************************************************************************/ extern const log4c_layout_t* log4c_appender_set_layout( log4c_appender_t* ptrThis, const log4c_layout_t* a_layout) { const log4c_layout_t* previous; if (!ptrThis) return NULL; previous = ptrThis->app_layout; ptrThis->app_layout = a_layout; return previous; } /*******************************************************************************/ extern void* log4c_appender_set_udata(log4c_appender_t* ptrThis, void* a_udata) { void* previous; if (!ptrThis) return NULL; previous = ptrThis->app_udata; ptrThis->app_udata = a_udata; return previous; } /*******************************************************************************/ extern int log4c_appender_open(log4c_appender_t* ptrThis) { int rc = 0; if (!ptrThis) return -1; if (ptrThis->app_isopen) return 0; if (!ptrThis->app_type) return 0; if (!ptrThis->app_type->open) return 0; if (ptrThis->app_type->open(ptrThis) == -1){ rc = -1; } if (!rc) { ptrThis->app_isopen++; } return rc; } /** * @bug is this the right place to open an appender ? */ /*******************************************************************************/ extern int log4c_appender_append( log4c_appender_t* ptrThis, log4c_logging_event_t* a_event) { if (!ptrThis) return -1; if (!ptrThis->app_type) return 0; if (!ptrThis->app_type->append) return 0; if (!ptrThis->app_isopen) if (log4c_appender_open(ptrThis) == -1) return -1; if ( (a_event->evt_rendered_msg = log4c_layout_format(ptrThis->app_layout, a_event)) == NULL) a_event->evt_rendered_msg = a_event->evt_msg; return ptrThis->app_type->append(ptrThis, a_event); } /*******************************************************************************/ extern int log4c_appender_append_no_file_num_no_layout( log4c_appender_t* ptrThis, log4c_logging_event_t* a_event) { if (!ptrThis) return -1; if (!ptrThis->app_type) return 0; if (!ptrThis->app_type->append) return 0; if (!ptrThis->app_isopen) if (log4c_appender_open(ptrThis) == -1) return -1; #if 0 if ( (a_event->evt_rendered_msg = log4c_layout_format(ptrThis->app_layout, a_event)) == NULL) a_event->evt_rendered_msg = a_event->evt_msg; #else a_event->evt_rendered_msg = a_event->evt_msg; #endif return ptrThis->app_type->append(ptrThis, a_event); } /*******************************************************************************/ extern int log4c_appender_close(log4c_appender_t* ptrThis) { if (!ptrThis) return -1; if (!ptrThis->app_isopen) return 0; if (!ptrThis->app_type) return 0; if (!ptrThis->app_type->close) return 0; if (ptrThis->app_type->close(ptrThis) == -1) return -1; ptrThis->app_isopen--; return 0; } /*******************************************************************************/ extern void log4c_appender_print(const log4c_appender_t* ptrThis, FILE* a_stream) { if (!ptrThis) return; fprintf(a_stream, "{ name:'%s' type:'%s' layout:'%s' isopen:%d udata:%p}", ptrThis->app_name, ptrThis->app_type ? ptrThis->app_type->name : "(not set)", log4c_layout_get_name(ptrThis->app_layout), ptrThis->app_isopen, ptrThis->app_udata); }