2008-06-24 19:19:20 +00:00
|
|
|
#ifndef _LIGHTTPD_LOG_H_
|
|
|
|
#define _LIGHTTPD_LOG_H_
|
|
|
|
|
|
|
|
/* #include "valgrind/valgrind.h" */
|
|
|
|
#include "base.h"
|
|
|
|
|
|
|
|
#define REMOVE_PATH_FROM_FILE 1
|
|
|
|
#if REMOVE_PATH_FROM_FILE
|
|
|
|
LI_API const char *remove_path(const char *path);
|
|
|
|
#define REMOVE_PATH(file) remove_path(file)
|
|
|
|
#else
|
|
|
|
#define REMOVE_PATH(file) file
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2008-07-19 10:56:44 +00:00
|
|
|
#define ERROR(srv, fmt, ...) \
|
|
|
|
log_write(srv, NULL, "%s.%d: (error) "fmt, REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
|
2008-06-24 19:19:20 +00:00
|
|
|
|
2008-08-08 16:49:00 +00:00
|
|
|
#define INFO(srv, ...) \
|
|
|
|
log_write(srv, NULL, __VA_ARGS__)
|
|
|
|
|
2008-07-19 10:56:44 +00:00
|
|
|
#define TRACE(srv, fmt, ...) \
|
|
|
|
log_write(srv, NULL, "%s.%d: (trace) "fmt, REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
|
2008-06-24 19:19:20 +00:00
|
|
|
|
2008-07-19 10:56:44 +00:00
|
|
|
#define SEGFAULT(srv, fmt, ...) \
|
2008-06-24 19:19:20 +00:00
|
|
|
do { \
|
2008-07-19 10:56:44 +00:00
|
|
|
log_write(srv, NULL, "%s.%d: (crashing) "fmt, REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__); \
|
2008-06-24 19:19:20 +00:00
|
|
|
/* VALGRIND_PRINTF_BACKTRACE(fmt, __VA_ARGS__); */\
|
|
|
|
abort();\
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
#define CON_ERROR(srv, con, fmt, ...) \
|
|
|
|
log_write(srv, con, "%s.%d: (error) "fmt, REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define CON_TRACE(srv, con, fmt, ...) \
|
|
|
|
log_write(srv, con, "%s.%d: (trace) "fmt, REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define CON_SEGFAULT(srv, con, fmt, ...) \
|
|
|
|
do { \
|
|
|
|
log_write(srv, con, "%s.%d: (crashing) "fmt, REMOVE_PATH(__FILE__), __LINE__, __VA_ARGS__); \
|
|
|
|
/* VALGRIND_PRINTF_BACKTRACE(fmt, __VA_ARGS__); */ \
|
|
|
|
abort();\
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO: perhaps make portable (detect if cc supports) */
|
|
|
|
#define __ATTRIBUTE_PRINTF_FORMAT(fmt, arg) __attribute__ ((__format__ (__printf__, fmt, arg)))
|
|
|
|
|
|
|
|
LI_API int log_write(server *srv, connection *con, const char *fmt, ...) __ATTRIBUTE_PRINTF_FORMAT(3, 4);
|
|
|
|
|
2008-07-18 23:33:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* convenience makros */
|
|
|
|
#define log_error(srv, con, fmt, ...) \
|
|
|
|
log_write_(srv, con, LOG_LEVEL_ERROR, fmt, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define log_warning(srv, con, fmt, ...) \
|
|
|
|
log_write_(srv, con, LOG_LEVEL_WARNING, fmt, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define log_info(srv, con, fmt, ...) \
|
|
|
|
log_write_(srv, con, LOG_LEVEL_INFO, fmt, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define log_message(srv, con, fmt, ...) \
|
|
|
|
log_write_(srv, con, LOG_LEVEL_MESSAGE, fmt, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define log_debug(srv, con, fmt, ...) \
|
|
|
|
log_write_(srv, con, LOG_LEVEL_DEBUG, fmt, __VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-07-18 20:16:30 +00:00
|
|
|
struct log_t;
|
|
|
|
typedef struct log_t log_t;
|
|
|
|
|
2008-07-18 22:11:08 +00:00
|
|
|
struct log_entry_t;
|
|
|
|
typedef struct log_entry_t log_entry_t;
|
|
|
|
|
2008-07-18 22:38:33 +00:00
|
|
|
typedef enum {
|
|
|
|
LOG_LEVEL_DEBUG,
|
|
|
|
LOG_LEVEL_INFO,
|
|
|
|
LOG_LEVEL_MESSAGE,
|
|
|
|
LOG_LEVEL_WARNING,
|
|
|
|
LOG_LEVEL_ERROR
|
|
|
|
} log_level_t;
|
|
|
|
|
2008-07-19 20:13:32 +00:00
|
|
|
typedef enum {
|
|
|
|
LOG_TYPE_STDERR,
|
|
|
|
LOG_TYPE_FILE,
|
|
|
|
LOG_TYPE_PIPE,
|
|
|
|
LOG_TYPE_SYSLOG
|
|
|
|
} log_type_t;
|
|
|
|
|
2008-07-18 20:16:30 +00:00
|
|
|
struct log_t {
|
2008-07-19 20:13:32 +00:00
|
|
|
log_type_t type;
|
|
|
|
GString *path;
|
2008-07-20 16:28:58 +00:00
|
|
|
gint refcount;
|
2008-07-18 20:16:30 +00:00
|
|
|
gint fd;
|
|
|
|
GString *lastmsg;
|
|
|
|
guint lastmsg_count;
|
2008-07-20 14:35:04 +00:00
|
|
|
GMutex *mutex;
|
2008-07-18 20:16:30 +00:00
|
|
|
};
|
|
|
|
|
2008-07-18 22:11:08 +00:00
|
|
|
struct log_entry_t {
|
2008-07-19 20:13:32 +00:00
|
|
|
log_t *log;
|
2008-07-22 14:00:31 +00:00
|
|
|
log_level_t level;
|
2008-07-18 22:11:08 +00:00
|
|
|
GString *msg;
|
|
|
|
};
|
|
|
|
|
2008-08-13 17:57:19 +00:00
|
|
|
/* determines the type of a log target by the path given. /absolute/path = file; |app = pipe; stderr = stderr; syslog = syslog */
|
|
|
|
log_type_t log_type_from_path(GString *path);
|
|
|
|
|
|
|
|
log_level_t log_level_from_string(GString *str);
|
|
|
|
gchar* log_level_str(log_level_t log_level);
|
2008-07-19 20:13:32 +00:00
|
|
|
|
2008-07-22 14:00:31 +00:00
|
|
|
/* log_new is used to create a new log target, if a log with the same path already exists, it is referenced instead */
|
2008-07-19 20:13:32 +00:00
|
|
|
log_t *log_new(server *srv, log_type_t type, GString *path);
|
2008-07-22 14:00:31 +00:00
|
|
|
/* avoid calling log_free directly. instead use log_unref which calls log_free if refcount has reached zero */
|
2008-07-19 20:13:32 +00:00
|
|
|
void log_free(server *srv, log_t *log);
|
2008-08-06 21:48:39 +00:00
|
|
|
void log_free_unlocked(server *srv, log_t *log);
|
2008-07-19 20:13:32 +00:00
|
|
|
|
2008-08-06 21:48:39 +00:00
|
|
|
void log_ref(server *srv, log_t *log);
|
2008-07-19 20:13:32 +00:00
|
|
|
void log_unref(server *srv, log_t *log);
|
|
|
|
|
2008-07-22 14:00:31 +00:00
|
|
|
/* do not call directly, use log_rotate_logs instead */
|
2008-07-20 14:35:04 +00:00
|
|
|
void log_rotate(gchar *path, log_t *log, server *srv);
|
2008-08-06 21:48:39 +00:00
|
|
|
|
2008-07-22 14:00:31 +00:00
|
|
|
void log_rotate_logs(server *srv);
|
2008-07-19 20:13:32 +00:00
|
|
|
|
2008-07-18 22:11:08 +00:00
|
|
|
gpointer log_thread(server *srv);
|
2008-07-20 15:12:17 +00:00
|
|
|
void log_thread_start(server *srv);
|
|
|
|
void log_thread_wakeup(server *srv);
|
|
|
|
|
2008-07-18 22:11:08 +00:00
|
|
|
void log_init(server *srv);
|
2008-07-18 23:33:12 +00:00
|
|
|
gboolean log_write_(server *srv, connection *con, log_level_t log_level, const gchar *fmt, ...);
|
2008-07-18 20:16:30 +00:00
|
|
|
|
2008-06-24 19:19:20 +00:00
|
|
|
#endif
|