Created
September 21, 2012 08:01
-
-
Save c4pt0r/3760278 to your computer and use it in GitHub Desktop.
simple logger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdarg.h> | |
#include <ctype.h> | |
#include <time.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include "log.h" | |
static struct logger g_logger; | |
// logger util for vscprintf | |
int _scnprintf(char *buf, size_t size, const char *fmt, ...); | |
int _vscnprintf(char *buf, size_t size, const char *fmt, va_list args); | |
int | |
_scnprintf(char *buf, size_t size, const char *fmt, ...) | |
{ | |
va_list args; | |
int i; | |
va_start(args, fmt); | |
i = _vscnprintf(buf, size, fmt, args); | |
va_end(args); | |
return i; | |
} | |
int | |
_vscnprintf(char *buf, size_t size, const char *fmt, va_list args) | |
{ | |
int i; | |
i = vsnprintf(buf, size, fmt, args); | |
/* | |
* The return value is the number of characters which would be written | |
* into buf not including the trailing '\0'. If size is == 0 the | |
* function returns 0. | |
* | |
* On error, the function also returns 0. This is to allow idiom such | |
* as len += _vscnprintf(...) | |
* | |
* See: http://lwn.net/Articles/69419/ | |
*/ | |
if (i <= 0) { | |
return 0; | |
} | |
if (i < size) { | |
return i; | |
} | |
return size - 1; | |
} | |
int | |
logger_init(int level, char * name) | |
{ | |
struct logger * logger = &g_logger; | |
logger->level = level; | |
if (name == NULL || !strlen(name) ) { | |
logger->fd = STDERR_FILENO; | |
} | |
else{ | |
logger->fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644); | |
if (logger->fd < 0) { | |
_log_stderr("open log file '%s' error!", name); | |
return -1; | |
} | |
} | |
return 0; | |
} | |
void | |
logger_close() | |
{ | |
struct logger * logger = &g_logger; | |
if (logger->fd >= 0 && logger->fd != STDERR_FILENO) { | |
close(logger->fd); | |
} | |
} | |
int | |
logger_canlog(int level) | |
{ | |
struct logger * logger = &g_logger; | |
if (level >= logger->level) { | |
return 1; | |
} | |
return 0; | |
} | |
void | |
_log(const char * file, int line, int is_panic, const char * fmt, ...) | |
{ | |
struct logger * logger = &g_logger; | |
char buf[MAX_LOG_BUF], * time_str; | |
va_list args; | |
struct tm * local; | |
time_t t; | |
ssize_t n; | |
int len,size; | |
len = 0; | |
size = MAX_LOG_BUF; | |
if (logger->fd < 0) { | |
return; | |
} | |
t = time(NULL); | |
local = localtime(&t); | |
time_str = asctime(local); | |
len += _scnprintf(buf + len , size - len, "[%.*s] %s %d ", strlen(time_str) -1 , time_str, file, line); | |
va_start(args, fmt); | |
len += _vscnprintf(buf + len, size - len, fmt, args); | |
va_end(args); | |
buf[len++] = '\n'; | |
n = write(logger->fd, buf, len); | |
if (n < 0) { | |
return ; | |
} | |
if (is_panic) { | |
abort(); | |
} | |
} | |
void | |
_log_stderr(const char * fmt, ...) { | |
char buf[MAX_LOG_BUF], * time_str; | |
int len , size; | |
va_list args; | |
struct tm * local; | |
time_t t; | |
ssize_t n; | |
t = time(NULL); | |
local = localtime(&t); | |
time_str = asctime(local); | |
size = MAX_LOG_BUF; | |
len = 0; | |
len += _scnprintf(buf + len , size - len, "[%.*s] ", strlen(time_str) -1 , time_str); | |
va_start(args, fmt); | |
len += _vscnprintf(buf + len, size - len, fmt, args); | |
va_end(args); | |
buf[len++] = '\n'; | |
n = write(STDERR_FILENO, buf, len); | |
if (n < 0) { | |
return ; | |
} | |
} | |
int main() | |
{ | |
logger_init(LOG_INFO, "log"); | |
log_info("fuck"); | |
logger_close(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Simple logger in C | |
* inspired by memcached's logger | |
* written by c4pt0r | |
*/ | |
#ifndef _LOG_H_ | |
#define _LOG_H_ | |
struct logger { | |
char * name; | |
int fd; | |
int level; | |
}; | |
#define LOG_INFO 0 | |
#define LOG_DEBUG 1 | |
#define LOG_WARN 2 | |
#define LOG_EMERG 3 | |
#define MAX_LOG_BUF 256 | |
// log functions | |
void _log(const char * file, int line, int is_panic, const char * fmt, ...); | |
void _log_err(const char * fmt, ...); | |
int logger_init(int level, char * name); | |
void logger_close(); | |
// logger interfaces | |
#define log_info(...) do { \ | |
if (logger_canlog(LOG_INFO) != 0) { \ | |
_log(__FILE__, __LINE__, 0, __VA_ARGS__); \ | |
} \ | |
} while (0) | |
#define log_debug(...) do { \ | |
if (logger_canlog(LOG_DEBUG) != 0) { \ | |
_log(__FILE__, __LINE__, 0, __VA_ARGS__); \ | |
} \ | |
} while (0) | |
#define log_warn(...) do { \ | |
if (logger_canlog(LOG_WARN) != 0) { \ | |
_log(__FILE__, __LINE__, 0, __VA_ARGS__); \ | |
} \ | |
} while (0) | |
#define log_warn(...) do { \ | |
if (logger_canlog(LOG_EMERG) != 0) { \ | |
_log(__FILE__, __LINE__, 0, __VA_ARGS__); \ | |
} \ | |
} while (0) | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment