From a9a7b9123ed06f5176aa981f333b740bf882d950 Mon Sep 17 00:00:00 2001 From: qintl Date: Sun, 6 Jan 2019 10:50:09 +0800 Subject: [PATCH] add linux-os plugin file support Signed-off-by: qintl --- demo/os/linux/easylogger/inc/elog_cfg.h | 2 + .../linux/easylogger/plugins/file/elog_file.c | 34 ++++ .../linux/easylogger/plugins/file/elog_file.h | 30 ++++ .../easylogger/plugins/file/elog_file_cfg.h | 13 ++ .../easylogger/plugins/file/elog_file_port.c | 167 ++++++++++++++++++ demo/os/linux/easylogger/port/elog_port.c | 9 + 6 files changed, 255 insertions(+) create mode 100644 demo/os/linux/easylogger/plugins/file/elog_file.c create mode 100644 demo/os/linux/easylogger/plugins/file/elog_file.h create mode 100644 demo/os/linux/easylogger/plugins/file/elog_file_cfg.h create mode 100644 demo/os/linux/easylogger/plugins/file/elog_file_port.c diff --git a/demo/os/linux/easylogger/inc/elog_cfg.h b/demo/os/linux/easylogger/inc/elog_cfg.h index 52c8081..778972b 100644 --- a/demo/os/linux/easylogger/inc/elog_cfg.h +++ b/demo/os/linux/easylogger/inc/elog_cfg.h @@ -31,6 +31,8 @@ /* enable log output. default open this macro */ #define ELOG_OUTPUT_ENABLE +/* enable log write file. default open this macro */ +#define ELOG_FILE_ENABLE /* setting static output log level */ #define ELOG_OUTPUT_LVL ELOG_LVL_VERBOSE /* enable assert check */ diff --git a/demo/os/linux/easylogger/plugins/file/elog_file.c b/demo/os/linux/easylogger/plugins/file/elog_file.c new file mode 100644 index 0000000..f7f2a98 --- /dev/null +++ b/demo/os/linux/easylogger/plugins/file/elog_file.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +#include "elog_file.h" + +/* initialize OK flag */ +static bool init_ok = false; + +ElogErrCode elog_file_init(void) +{ + ElogErrCode result = ELOG_NO_ERR; + + elog_file_port_init(); + + init_ok = true; + return result; +} + +void elog_file_write(const char *log, size_t size) +{ + ELOG_ASSERT(init_ok); + ELOG_ASSERT(log); + + elog_file_port_lock(); + elog_file_port_write(log, size); + elog_file_port_unlock(); +} + +void elog_file_deinit(void) +{ + elog_file_port_deinit(); +} diff --git a/demo/os/linux/easylogger/plugins/file/elog_file.h b/demo/os/linux/easylogger/plugins/file/elog_file.h new file mode 100644 index 0000000..6cc8bf6 --- /dev/null +++ b/demo/os/linux/easylogger/plugins/file/elog_file.h @@ -0,0 +1,30 @@ +#ifndef __ELOG_FILE__H__ +#define __ELOG_FILE__H__ + +#include + +/* EasyLogger file log plugin's software version number */ +#define ELOG_FILE_SW_VERSION "V1.0.0" + +#ifdef __cplusplus +extern "C" { +#endif + /* elog_file.c */ + ElogErrCode elog_file_init(void); + void elog_file_set_name(const char *name); + void elog_file_get_name(const char *name); + void elog_file_write(const char *log, size_t size); + void elog_file_deinit(void); + + /* elog_file_port.c */ + ElogErrCode elog_file_port_init(void); + void elog_file_port_write(const char *log, size_t size); + void elog_file_port_lock(void); + void elog_file_port_unlock(void); + void elog_file_port_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/demo/os/linux/easylogger/plugins/file/elog_file_cfg.h b/demo/os/linux/easylogger/plugins/file/elog_file_cfg.h new file mode 100644 index 0000000..42a2b36 --- /dev/null +++ b/demo/os/linux/easylogger/plugins/file/elog_file_cfg.h @@ -0,0 +1,13 @@ +#ifndef _ELOG_FILE_CFG_H_ +#define _ELOG_FILE_CFG_H_ + +/* EasyLogger file log plugin's using file name */ +#define ELOG_FILE_NAME "/tmp/elog_file.log" + +/* EasyLogger file log plugin's using file max size */ +#define ELOG_FILE_MAX_SIZE (10 * 1024 * 1024) + +/* EasyLogger file log plugin's using semaphore key */ +#define ELOG_FILE_SEM_KEY ((key_t)0x19910612) + +#endif /* _ELOG_FILE_CFG_H_ */ diff --git a/demo/os/linux/easylogger/plugins/file/elog_file_port.c b/demo/os/linux/easylogger/plugins/file/elog_file_port.c new file mode 100644 index 0000000..9e3a2ae --- /dev/null +++ b/demo/os/linux/easylogger/plugins/file/elog_file_port.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "elog_file.h" +#include "elog_file_cfg.h" + +#ifdef _SEM_SEMUN_UNDEFINED +union semun { + int val; /* Value for SETVAL */ + struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ + unsigned short *array; /* Array for GETALL, SETALL */ + struct seminfo *__buf; /* Buffer for IPC_INFO + (Linux-specific) */ +}; +#endif + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +static FILE *fp; +static int fd; +static int semid = -1; +static struct sembuf const up = {0, 1, SEM_UNDO}; +static struct sembuf const down = {0, -1, SEM_UNDO}; + +static void lock_init(void); +static int lock_open(void); +static inline int file_size(void); +/** + * EasyLogger flile log pulgin port initialize + * + * @return result + */ +ElogErrCode elog_file_port_init(void) { + ElogErrCode result = ELOG_NO_ERR; + + fp = fopen(ELOG_FILE_NAME, "a+"); + if (unlikely(!fp)) + goto __exit; + + lock_init(); + + fd = fileno(fp); +__exit: + return result; +} + +/** + * output file saved log port interface + * + * @param log file saved log + * @param size log size + */ +void elog_file_port_write(const char *log, size_t size) { + if(unlikely(file_size() >= ELOG_FILE_MAX_SIZE)) + return ; + + fwrite(log, size, 1, fp); + fdatasync(fd); +} + +/** + * file log lock + */ +void elog_file_port_lock(void) { + semid == -1 ? -1 : semop(semid, (struct sembuf *)&down, 1); +} + +/** + * file log unlock + */ +void elog_file_port_unlock(void) { + semid == -1 ? -1 : semop(semid, (struct sembuf *)&up, 1); +} +/** + * file log deinit + */ +void elog_file_port_deinit(void) { + fclose(fp); +} + +/** + * initialize the lock + */ +static void lock_init(void) +{ + int id, rc; + union semun arg; + struct sembuf sembuf; + + id = semget(ELOG_FILE_SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0666); + if(likely(id == -1)) { + id = lock_open(); + if (id == -1) + goto __exit; + } else { + arg.val = 0; + rc = semctl(id, 0, SETVAL, arg); + if (rc == -1) + goto __exit; + + sembuf.sem_num = 0; + sembuf.sem_op = 1; + sembuf.sem_flg = 0; + + rc = semop(semid, &sembuf, 1); + if (rc == -1) + goto __exit; + } + + semid = id; +__exit: + return ; +} + +/** + * gets the lock + */ +static int lock_open(void) +{ + int id, rc, i; + union semun arg; + struct semid_ds ds; + + id = semget(ELOG_FILE_SEM_KEY, 1, 0666); + if(unlikely(id == -1)) + goto err; + + arg.buf = &ds; + + for (i = 0; i < 10; i++) { + rc = semctl(id, 0, IPC_STAT, arg); + if (unlikely(rc == -1)) + goto err; + + if(ds.sem_otime != 0) + break; + + usleep(10 * 1000); + } + + if (unlikely(ds.sem_otime == 0)) + goto err; + + return id; +err: + return -1; +} + +/** + * gets the file size + */ +static inline int file_size() +{ + struct stat statbuf; + + statbuf.st_size = 0; + stat(ELOG_FILE_NAME, &statbuf); + + return statbuf.st_size; +} diff --git a/demo/os/linux/easylogger/port/elog_port.c b/demo/os/linux/easylogger/port/elog_port.c index 4c8c183..456888c 100644 --- a/demo/os/linux/easylogger/port/elog_port.c +++ b/demo/os/linux/easylogger/port/elog_port.c @@ -32,6 +32,7 @@ #include #include +#include static pthread_mutex_t output_lock; /** @@ -44,6 +45,10 @@ ElogErrCode elog_port_init(void) { pthread_mutex_init(&output_lock, NULL); +#ifdef ELOG_FILE_ENABLE + elog_file_init(); +#endif + return result; } @@ -56,6 +61,10 @@ ElogErrCode elog_port_init(void) { void elog_port_output(const char *log, size_t size) { /* output to terminal */ printf("%.*s", size, log); +#ifdef ELOG_FILE_ENABLE + /* write the file */ + elog_file_write(log, size); +#endif } /**