/*
* @file swlog.c
* @brief The file defines the interfaces to manipulate logging information.
*/
#include "swapi.h"
#include "swudp.h"
#include "swsignal.h"
#include "swlog.h"
#include "swthrd.h"
#ifndef WIN32
#include <sys/un.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#endif
#define LOG_TARGETS_MAX 6 //目标数组最大容量
#define LOG_MODS_MAX 128 //最多允许输出日志的模块数目128
#define LOG_BUF_SIZE 16384 //每条日志最大的大小,需要确保本buf大小小于ftp日志申请的空间大小
#define LOG_MODSINFO_LENGTH 1024 //mods 列表信息长度
#define LOG_TARGETSINFO_LENGTH 1024 //tagets 列表信息长度
#define LOG_LOCAL_SOCKET_FILE "/tmp/.logsocket"
#define LOG_FTP_BUF_SIZE 131072
//把四个字符转化成一个uin32_t型数据
#ifdef WORDS_BIGENDIAN
#define SW_FOURCC( a, b, c, d ) \
( ((uint32_t)d) | ( ((uint32_t)c) << 8 ) \
| ( ((uint32_t)b) << 16 ) | ( ((uint32_t)a) << 24 ) )
#else
#define SW_FOURCC( a, b, c, d ) (((uint32_t)a) | ( ((uint32_t)b) << 8 ) | ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) )
#endif
//日志输出目标的类型
typedef enum
{
LOG_TARGET_NULL = 0x00,
LOG_TARGET_CONSOLE,
LOG_TARGET_FILE,
LOG_TARGET_UDP,
LOG_TARGET_LOCALSOCK,
LOG_TARGET_SYSLOG,
LOG_TARGET_FTP,
LOG_TARGET_MAX
}target_type_t;
//日志文件的状态
typedef enum
{
LOG_FP_OFF =0x00,
LOG_FP_OPEN,
LOG_FP_ON,
LOG_FP_FULL,
LOG_FP_CLOSE,
LOG_FP_MAX
}log_fp_state_t;
//日志输出目标
typedef struct
{
target_type_t type;
char target_org[256]; //目标路径
union
{
struct log_file_t
{
FILE* fp1; //日志文件句柄
uint32_t fp1_size; //日志文件当前数据大小
log_fp_state_t fp1_state; //日志文件状态
int fp1_fullcount; //日志文件处于文件满时的计数
FILE* fp2; //日志文件句柄
uint32_t fp2_size; //日志文件当前数据大小
log_fp_state_t fp2_state; //日志文件状态
int fp2_fullcount; //日志文件处于文件满时的计数
uint32_t maxsize; //日志文件最大大小
int count; //日志文件的计数,用于生成日志文件名
char path[256]; //日志文件的路径
}logfile;
struct log_udp_t
{
uint32_t ip;
uint16_t port;
}logudp;
#ifndef WIN32
struct log_localsock_t
{
int sock;
struct sockaddr_un sock_un;
}loglocalsock;
#endif
struct log_ftp_t
{
char *logbuf1; //申请128K+2K的buf作为ftp传输的日志
int logbufpos1; //记录logbuf1日志的长度
char *logbuf2; //申请128K+2K的buf作为ftp传输的日志,2个日志轮流切换,使用线程处理ftp的日志输出
int logbufpos2; //记录logbuf2日志的长度
char *buf; //记录当前日志buf(重logbuf1,2中获取,如果当前部分)
int bufsize; //记录当前使用的buf的日志长度,当bufsize快达到128K时,如果下一buf不可用(传输中)清空buf,从头开始输出
}logftp;
}log_union;
}target_t;
//打印等级,默认OFF
static int m_level = LOG_LEVEL_OFF;
//日志输出目标数组
static target_t m_targets_list[LOG_TARGETS_MAX];
//日志输出目标信息
static char m_targets_info[LOG_TARGETSINFO_LENGTH];
//日志输出目标数目
static int m_targets_num = 0;
//模块开关标志
static bool m_allmods_is_allowed = false;
//允许输出日志的模块信息
static char m_mods_info[LOG_MODSINFO_LENGTH];
//允许输出日志的模块列表
static uint32_t m_mods_list[LOG_MODS_MAX];
//不允许输出日志的模块列表
static uint32_t m_disable_mods_list[LOG_MODS_MAX];
//允许输出日志的模块书目
static int m_mods_num = 0;
//日志输出等级信息
static const char* m_level_info[] = { "A", "D", "I", "W", "E", "F" };
//日志buf
static char m_logbuf[4][LOG_BUF_SIZE];
//日志buf索引
static int m_logbuf_index=0;
//udp日志输出socket
static int m_udp_skt = -1;
/* ftp日志输出线程 */
static HANDLE m_thrd = NULL;
/* ftp日志输出的信号量 */
static HANDLE m_signal = NULL;
/* 是否退出ftp日志传输 */
static bool m_b_exit_ftplog = false;
/**
*@brief 把日志模块的名字转成数值
*/
static uint32_t calc_imod(const char* mod);
/**
*@brief 查找mod是否存在
*/
static int find_imod(uint32_t imod);
/**
*@brief 判断模块是否允许输出日志
*/
static bool log_mod_is_allowed(const char* mod);
/**
*@brief 输出日志
*/
static int log_output(char* logbuf,int size);
/**
*@brief 打开文件
*/
static FILE* log_open_file(char* path,int count);
/**
*@brief 查找日志输出目标
*/
static int log_find_target(char* target);
/**
*@brief 找一个空的日志输出目标,以便存储新的日志输出目标
*/
static int log_find_empty_target( );
/* ftp日志输出线程 */
static bool ftplog_proc(unsigned long wParam, unsigned long lParam);
static ftp_output_callback m_ftpcallback = NULL;
/**
* @brief Initialize the logging API, prepare for logging.
*
* @param level int, The original level to record the logging infomation. You can use sw_log_set_level() to change it.
* @param target char*, The target of all logging infomation.
* @param mods char*,The modules which allow to ouput log.
*
* @return int , The status of this operation. 0 on success, else on failure.
*/
int sw_log_init( int level, char* targets, char* mods )
{
int i = 0;
if( level < LOG_LEVEL_ALL || level > LOG_LEVEL_OFF )
{
printf("level error:0-6\n ");
return -1;
}
#ifndef WIN32
for( i = 0; i < LOG_TARGETS_MAX; i++ )
{
m_targets_list[i].log_union.loglocalsock.sock = -1;
}
#endif
m_level = level;
sw_log_set_targets( targets);
sw_log_set_mods( mods);
return 0;
}
/**
* @brief Release some resources allocated by sw_log_init().
*/
void sw_log_exit()
{
int i = 0;
m_level = LOG_LEVEL_OFF ;
sw_log_clear_alltarget();
sw_log_clear_allmods();
while ( i++ < 5 && m_thrd)
{
m_b_exit_ftplog = true;
if ( m_signal )
sw_signal_give( m_signal );
sw_thrd_delay(10);
}
if ( m_thrd )
sw_thrd_close( m_thrd, 100 );
if ( m_signal )
sw_signal_destroy( m_signal );
return ;
}
/**
* @brief set the logging level
*
* @param level int, the logging level to set.
*/
int sw_log_set_level( int level )
{
if( level < LOG_LEVEL_ALL )
m_level = LOG_LEVEL_ALL;
else if( level > LOG_LEVEL_OFF )
m_level = LOG_LEVEL_OFF;
else
m_level = level;
return 0;
}
/**
* @brief To get the logging level.
*
* @return int , the logging level has been set previously.
*/
int sw_log_get_level()
{
return m_level;
}
/**
* @brief set the target of the logging info. It will override the original target list.
* The new target list has only one target.
* @param target,char*,the target to set,for example console,file:///tmp/disk1/log.log&max_size=5M
*/
int sw_log_set_targets( char* targets )
{
char* p =NULL;
char* q =NULL;
char target[256];
if(targets == NULL)
return -1;
sw_log_clear_alltarget();
p = targets;
while( *p != '\0' )
{
q = p;
while( *q !=',' && *q !='\0')
q++;
if( (q-p) <= (int)(sizeof(target)-1))
{
strncpy(target,p,q-p);
target[q-p]='\0';
}
else
{
strncpy(target,p,sizeof(target)-1);
target[sizeof(target)-1] = '\0';
}
sw_log_add_target(target);
if( *q == '\0')
break;
else
p = q+1;
}
return m_targets_num;
}
/**
* @brief Add a target to the target list.
*
* @param target,char*,the target to add.for example console,file:///tmp/disk1/log.log&max_size=5M
* for:ftp://ftpuser:111111@192.168.0.8/00-11-09-EF-B5-AF when update log swlog modules will pack as
* ftp://ftpuser:111111@192.168.0.8/00-11-09-EF-B5-AF_20110517142934.log
*/
int sw_log_add_target( char* target )
{
int i =0;
char* p = NULL;
char* q = NULL;
if( target == NULL )
return -1;
if( log_find_target(target)>=0 )
return 0;
i = log_find_empty_target();
if( i < 0 )
{
prin
linux下的ftp服务器客户端
需积分: 10 151 浏览量
2012-08-10
17:57:31
上传
评论
收藏 59KB GZ 举报
dolphin0727
- 粉丝: 0
- 资源: 2