1 #ifndef FAILURES_H 2 #define FAILURES_H 3 4 struct ip_addr; 5 6 /* Default exit status codes that we could use. */ 7 enum fatal_exit_status { 8 FATAL_LOGOPEN = 80, /* Can't open log file */ 9 FATAL_LOGWRITE = 81, /* Can't write to log file */ 10 FATAL_LOGERROR = 82, /* Internal logging error */ 11 FATAL_OUTOFMEM = 83, /* Out of memory */ 12 FATAL_EXEC = 84, /* exec() failed */ 13 14 FATAL_DEFAULT = 89 15 }; 16 17 enum log_type { 18 LOG_TYPE_DEBUG, 19 LOG_TYPE_INFO, 20 LOG_TYPE_WARNING, 21 LOG_TYPE_ERROR, 22 LOG_TYPE_FATAL, 23 LOG_TYPE_PANIC, 24 25 LOG_TYPE_COUNT, 26 /* special case */ 27 LOG_TYPE_OPTION 28 }; 29 30 struct failure_line { 31 pid_t pid; 32 enum log_type log_type; 33 /* If non-zero, the first log_prefix_len bytes in text indicate 34 the log prefix. This implies disable_log_prefix=TRUE. */ 35 unsigned int log_prefix_len; 36 /* Disable the global log prefix. */ 37 bool disable_log_prefix; 38 const char *text; 39 }; 40 41 struct failure_context { 42 enum log_type type; 43 int exit_status; /* for LOG_TYPE_FATAL */ 44 const struct tm *timestamp; /* NULL = use time() + localtime() */ 45 unsigned int timestamp_usecs; 46 const char *log_prefix; /* override the default log prefix */ 47 /* If non-0, insert the log type text (e.g. "Info: ") at this position 48 in the log_prefix instead of appending it. */ 49 unsigned int log_prefix_type_pos; 50 }; 51 52 #define DEFAULT_FAILURE_STAMP_FORMAT "%b %d %H:%M:%S " 53 54 typedef void failure_callback_t(const struct failure_context *ctx, 55 const char *format, va_list args); 56 57 extern const char *failure_log_type_prefixes[]; 58 extern const char *failure_log_type_names[]; 59 60 void i_log_type(const struct failure_context *ctx, const char *format, ...) 61 ATTR_FORMAT(2, 3); 62 void i_log_typev(const struct failure_context *ctx, const char *format, 63 va_list args) ATTR_FORMAT(2, 0); 64 65 void i_panic(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD; 66 void i_fatal(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD; 67 void i_error(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_COLD; 68 void i_warning(const char *format, ...) ATTR_FORMAT(1, 2); 69 void i_info(const char *format, ...) ATTR_FORMAT(1, 2); 70 void i_debug(const char *format, ...) ATTR_FORMAT(1, 2); 71 72 void i_fatal_status(int status, const char *format, ...) 73 ATTR_FORMAT(2, 3) ATTR_NORETURN ATTR_COLD; 74 75 /* Change failure handlers. */ 76 #ifndef __cplusplus 77 void i_set_fatal_handler(failure_callback_t *callback ATTR_NORETURN); 78 #else 79 /* Older g++ doesn't like attributes in parameters */ 80 void i_set_fatal_handler(failure_callback_t *callback); 81 #endif 82 void i_set_error_handler(failure_callback_t *callback); 83 void i_set_info_handler(failure_callback_t *callback); 84 void i_set_debug_handler(failure_callback_t *callback); 85 void i_get_failure_handlers(failure_callback_t **fatal_callback_r, 86 failure_callback_t **error_callback_r, 87 failure_callback_t **info_callback_r, 88 failure_callback_t **debug_callback_r); 89 90 /* Send failures to file. */ 91 void default_fatal_handler(const struct failure_context *ctx, 92 const char *format, va_list args) 93 ATTR_NORETURN ATTR_FORMAT(2, 0); 94 void default_error_handler(const struct failure_context *ctx, 95 const char *format, va_list args) 96 ATTR_FORMAT(2, 0); 97 98 /* Send failures to syslog() */ 99 void i_syslog_fatal_handler(const struct failure_context *ctx, 100 const char *format, va_list args) 101 ATTR_NORETURN ATTR_FORMAT(2, 0); 102 void i_syslog_error_handler(const struct failure_context *ctx, 103 const char *format, va_list args) 104 ATTR_FORMAT(2, 0); 105 106 /* Open syslog and set failure/info/debug handlers to use it. */ 107 void i_set_failure_syslog(const char *ident, int options, int facility); 108 109 /* Send failures to specified log file instead of stderr. */ 110 void i_set_failure_file(const char *path, const char *prefix); 111 112 /* Send errors to stderr using internal error protocol. */ 113 void i_set_failure_internal(void); 114 /* Returns TRUE if the given callback handler was set via 115 i_set_failure_internal(). */ 116 bool i_failure_handler_is_internal(failure_callback_t *const callback); 117 /* If writing to log fails, ignore it instead of existing with 118 FATAL_LOGWRITE or FATAL_LOGERROR. */ 119 void i_set_failure_ignore_errors(bool ignore); 120 121 /* Send informational messages to specified log file. i_set_failure_*() 122 functions modify the info file too, so call this function after them. */ 123 void i_set_info_file(const char *path); 124 125 /* Send debug-level message to the given log file. The i_set_info_file() 126 function modifies also the debug log file, so call this function after it. */ 127 void i_set_debug_file(const char *path); 128 129 /* Set the failure prefix. */ 130 void i_set_failure_prefix(const char *prefix_fmt, ...) ATTR_FORMAT(1, 2); 131 /* Set prefix to "". */ 132 void i_unset_failure_prefix(void); 133 /* Returns the current failure prefix (never NULL). */ 134 const char *i_get_failure_prefix(void); 135 /* Prefix failures with a timestamp. fmt is in strftime() format. */ 136 void i_set_failure_timestamp_format(const char *fmt); 137 /* When logging with internal error protocol, update the process's current 138 IP address / log prefix by sending it to log process. This is mainly used to 139 improve the error message if the process crashes. */ 140 void i_set_failure_send_ip(const struct ip_addr *ip); 141 void i_set_failure_send_prefix(const char *prefix); 142 143 /* Call the callback before exit()ing. The callback may update the status. */ 144 void i_set_failure_exit_callback(void (*callback)(int *status)); 145 /* Call the exit callback and exit() */ 146 void failure_exit(int status) ATTR_NORETURN ATTR_COLD; 147 148 /* Parse a line logged using internal failure handler */ 149 void i_failure_parse_line(const char *line, struct failure_line *failure); 150 151 void failures_deinit(void); 152 153 #endif 154