⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
        logfiles[num_logfiles].file = f;    logfiles[num_logfiles].minimum_output_level = level;    logfiles[num_logfiles].exclusive = excl;    strcpy(logfiles[num_logfiles].filename, filename);    ++num_logfiles;    info(0, "Added logfile `%s' with level `%d'.", filename, level);    return (num_logfiles - 1);}#define FORMAT_SIZE (1024)static void format(char *buf, int level, const char *place, int e,		   const char *fmt, int with_timestamp){    static char *tab[] = {	"DEBUG: ",	"INFO: ",	"WARNING: ",	"ERROR: ",	"PANIC: ",	"LOG: "    };    static int tab_size = sizeof(tab) / sizeof(tab[0]);    time_t t;    struct tm tm;    char *p, prefix[1024];    long tid, pid;        p = prefix;    if (with_timestamp) {        time(&t);#if LOG_TIMESTAMP_LOCALTIME        tm = gw_localtime(t);#else        tm = gw_gmtime(t);#endif        sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d ",        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,        tm.tm_hour, tm.tm_min, tm.tm_sec);            p = strchr(p, '\0');    }    gwthread_self_ids(&tid, &pid);    sprintf(p, "[%ld] [%ld] ", pid, tid);        p = strchr(p, '\0');    if (level < 0 || level >= tab_size)	sprintf(p, "UNKNOWN: ");    else	sprintf(p, "%s", tab[level]);    p = strchr(p, '\0');    if (place != NULL && *place != '\0')	sprintf(p, "%s: ", place);        if (strlen(prefix) + strlen(fmt) > FORMAT_SIZE / 2) {	sprintf(buf, "%s <OUTPUT message too long>\n", prefix);	return;    }        if (e == 0)	sprintf(buf, "%s%s\n", prefix, fmt);    else	sprintf(buf, "%s%s\n%sSystem error %d: %s\n",		prefix, fmt, prefix, e, strerror(e));}static void PRINTFLIKE(2,0) output(FILE *f, char *buf, va_list args) {    vfprintf(f, buf, args);    fflush(f);}static void PRINTFLIKE(1,0) kannel_syslog(char *format, va_list args, int level){    char buf[4096]; /* Trying to syslog more than 4K could be bad */    int translog;        if (level >= sysloglevel && dosyslog) {	if (args == NULL) {	    strncpy(buf, format, sizeof(buf));	    buf[sizeof(buf) - 1] = '\0';	} else {	    vsnprintf(buf, sizeof(buf), format, args);	    /* XXX vsnprint not 100% portable */	}	switch(level) {	case GW_DEBUG:	    translog = LOG_DEBUG;	    break;	case GW_INFO:	    translog = LOG_INFO;	    break;	case GW_WARNING:	    translog = LOG_WARNING;	    break;	case GW_ERROR:	    translog = LOG_ERR;	    break;	case GW_PANIC:	    translog = LOG_ALERT;	    break;	default:	    translog = LOG_INFO;	    break;	}	syslog(translog, "%s", buf);    }}/* * Almost all of the message printing functions are identical, except for * the output level they use. This macro contains the identical parts of * the functions so that the code needs to exist only once. It's a bit * more awkward to edit, but that can't be helped. The "do {} while (0)" * construct is a gimmick to be more like a function call in all syntactic * situation. */#define FUNCTION_GUTS(level, place) \	do { \	    int i; \	    char buf[FORMAT_SIZE]; \	    va_list args; \	    \	    format(buf, level, place, err, fmt, 1); \            if (writers != NULL) { \                list_lock(writers); \                list_add_producer(writers); \                list_unlock(writers); \            } \	    for (i = 0; i < num_logfiles; ++i) { \		if (logfiles[i].exclusive == GW_NON_EXCL && \                    level >= logfiles[i].minimum_output_level && \                    logfiles[i].file != NULL) { \		        va_start(args, fmt); \		        output(logfiles[i].file, buf, args); \		        va_end(args); \		} \	    } \            if (writers != NULL) \                list_remove_producer(writers); \	    if (dosyslog) { \	        format(buf, level, place, err, fmt, 0); \		va_start(args, fmt); \		kannel_syslog(buf,args,level); \		va_end(args); \	    } \	} while (0)#define FUNCTION_GUTS_EXCL(level, place) \	do { \	    char buf[FORMAT_SIZE]; \	    va_list args; \	    \	    format(buf, level, place, err, fmt, 1); \            if (writers != NULL) { \                list_lock(writers); \                list_add_producer(writers); \                list_unlock(writers); \            } \            if (logfiles[e].exclusive == GW_EXCL && \                level >= logfiles[e].minimum_output_level && \                logfiles[e].file != NULL) { \                va_start(args, fmt); \                output(logfiles[e].file, buf, args); \                va_end(args); \            } \            if (writers != NULL) \              list_remove_producer(writers); \	} while (0)static void PRINTFLIKE(2,3) gw_panic_output(int err, const char *fmt, ...){    FUNCTION_GUTS(GW_PANIC, "");}void gw_panic(int err, const char *fmt, ...){    /*     * we don't want PANICs to spread accross smsc logs, so     * this will be always within the main core log.     */    FUNCTION_GUTS(GW_PANIC, "");#ifdef HAVE_BACKTRACE    {        void *stack_frames[50];        size_t size, i;        char **strings;        size = backtrace(stack_frames, sizeof(stack_frames) / sizeof(void*));        strings = backtrace_symbols(stack_frames, size);        if (strings) {            for (i = 0; i < size; i++)                gw_panic_output(0, "%s", strings[i]);        }        else { /* hmm, no memory available */            for (i = 0; i < size; i++)                gw_panic_output(0, "%p", stack_frames[i]);        }        /*         * Note: we don't free 'strings' array because gw_free could panic's and we         *       have endless loop with SEGFAULT at the end. And this doesn't care         *       us in any case, because we are panic's and exiting immediately. (alex)         */    }#endif#ifdef SEGFAULT_PANIC    *((char*)0) = 0;#endif    exit(EXIT_FAILURE);}void error(int err, const char *fmt, ...) {    int e;        if ((e = thread_to[thread_slot()])) {        FUNCTION_GUTS_EXCL(GW_ERROR, "");    } else {        FUNCTION_GUTS(GW_ERROR, "");    }}void warning(int err, const char *fmt, ...) {    int e;        if ((e = thread_to[thread_slot()])) {        FUNCTION_GUTS_EXCL(GW_WARNING, "");    } else {        FUNCTION_GUTS(GW_WARNING, "");    }}void info(int err, const char *fmt, ...) {    int e;        if ((e = thread_to[thread_slot()])) {        FUNCTION_GUTS_EXCL(GW_INFO, "");    } else {        FUNCTION_GUTS(GW_INFO, "");    }}static int place_matches(const char *place, const char *pat) {    size_t len;        len = strlen(pat);    if (pat[len-1] == '*')	return (strncasecmp(place, pat, len - 1) == 0);    return (strcasecmp(place, pat) == 0);}static int place_should_be_logged(const char *place) {    int i;        if (num_places == 0)	return 1;    for (i = 0; i < num_places; ++i) {	if (*loggable_places[i] != '-' && 	    place_matches(place, loggable_places[i]))		return 1;    }    return 0;}static int place_is_not_logged(const char *place) {    int i;        if (num_places == 0)	return 0;    for (i = 0; i < num_places; ++i) {	if (*loggable_places[i] == '-' &&	    place_matches(place, loggable_places[i]+1))		return 1;    }    return 0;}void debug(const char *place, int err, const char *fmt, ...) {    int e;        if (place_should_be_logged(place) && place_is_not_logged(place) == 0) {	/*	 * Note: giving `place' to FUNCTION_GUTS makes log lines    	 * too long and hard to follow. We'll rely on an external    	 * list of what places are used instead of reading them    	 * from the log file.	 */        if ((e = thread_to[thread_slot()])) {            FUNCTION_GUTS_EXCL(GW_DEBUG, "");        } else {            FUNCTION_GUTS(GW_DEBUG, "");        }    }}void log_set_debug_places(const char *places) {    char *p;        p = strtok(gw_strdup(places), " ,");    num_places = 0;    while (p != NULL && num_places < MAX_LOGGABLE_PLACES) {	loggable_places[num_places++] = p;	p = strtok(NULL, " ,");    }}void log_thread_to(unsigned int idx){    long thread_id = thread_slot();    if (idx > 0)         info(0, "Logging thread `%ld' to logfile `%s' with level `%d'.",              thread_id, logfiles[idx].filename, logfiles[idx].minimum_output_level);    thread_to[thread_id] = idx;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -