failures.h revision d4f004105cd7159aa9ade6b019eaecce9e94f382
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#ifndef FAILURES_H
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#define FAILURES_H
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
019a610a5ce14a80f6b017f94829933664879021Timo Sirainenstruct ip_addr;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Default exit status codes that we could use. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenenum fatal_exit_status {
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen FATAL_LOGOPEN = 80, /* Can't open log file */
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen FATAL_LOGWRITE = 81, /* Can't write to log file */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen FATAL_LOGERROR = 82, /* Internal logging error */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen FATAL_OUTOFMEM = 83, /* Out of memory */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen FATAL_EXEC = 84, /* exec() failed */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen FATAL_DEFAULT = 89
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen};
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenenum log_type {
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_DEBUG,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_INFO,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_WARNING,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_ERROR,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_FATAL,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_PANIC,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_COUNT,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen LOG_TYPE_OPTION
078aac578d08e348836c53939782afb10479def5Timo Sirainen};
078aac578d08e348836c53939782afb10479def5Timo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenstruct failure_line {
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen pid_t pid;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen enum log_type log_type;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const char *text;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen};
4e21cef121b8ad20439ccbcb4e9072c208f08611Timo Sirainen
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainenstruct failure_context {
4e21cef121b8ad20439ccbcb4e9072c208f08611Timo Sirainen enum log_type type;
4e21cef121b8ad20439ccbcb4e9072c208f08611Timo Sirainen int exit_status; /* for LOG_TYPE_FATAL */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const struct tm *timestamp; /* NULL = use time() + localtime() */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen unsigned int timestamp_usecs;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen};
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#define DEFAULT_FAILURE_STAMP_FORMAT "%b %d %H:%M:%S "
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainen
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainentypedef void failure_callback_t(const struct failure_context *ctx,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const char *format, va_list args);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenextern const char *failure_log_type_prefixes[];
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainenextern const char *failure_log_type_names[];
4e21cef121b8ad20439ccbcb4e9072c208f08611Timo Sirainen
4e21cef121b8ad20439ccbcb4e9072c208f08611Timo Sirainenvoid i_log_type(const struct failure_context *ctx, const char *format, ...)
ee3cb11d230d549367a1213aefe4598345796256Timo Sirainen ATTR_FORMAT(2, 3);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_panic(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_fatal(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD;
ef95f34bc41287eb9fd2cea42ddce648d02d5a39Timo Sirainenvoid i_error(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_COLD;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_warning(const char *format, ...) ATTR_FORMAT(1, 2);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_info(const char *format, ...) ATTR_FORMAT(1, 2);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_debug(const char *format, ...) ATTR_FORMAT(1, 2);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_fatal_status(int status, const char *format, ...)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen ATTR_FORMAT(2, 3) ATTR_NORETURN ATTR_COLD;
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Change failure handlers. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#ifndef __cplusplus
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_fatal_handler(failure_callback_t *callback ATTR_NORETURN);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#else
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Older g++ doesn't like attributes in parameters */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_fatal_handler(failure_callback_t *callback);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#endif
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_error_handler(failure_callback_t *callback);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_info_handler(failure_callback_t *callback);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_debug_handler(failure_callback_t *callback);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_get_failure_handlers(failure_callback_t **fatal_callback_r,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen failure_callback_t **error_callback_r,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen failure_callback_t **info_callback_r,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen failure_callback_t **debug_callback_r);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Send failures to file. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid default_fatal_handler(const struct failure_context *ctx,
5d2e422f9971ca9f0ad77508c1e7c315546e2765Timo Sirainen const char *format, va_list args)
5d2e422f9971ca9f0ad77508c1e7c315546e2765Timo Sirainen ATTR_NORETURN ATTR_FORMAT(2, 0);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid default_error_handler(const struct failure_context *ctx,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const char *format, va_list args)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen ATTR_FORMAT(2, 0);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Send failures to syslog() */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_syslog_fatal_handler(const struct failure_context *ctx,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const char *format, va_list args)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen ATTR_NORETURN ATTR_FORMAT(2, 0);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_syslog_error_handler(const struct failure_context *ctx,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const char *format, va_list args)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen ATTR_FORMAT(2, 0);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Open syslog and set failure/info/debug handlers to use it. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_failure_syslog(const char *ident, int options, int facility);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Send failures to specified log file instead of stderr. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_failure_file(const char *path, const char *prefix);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Send errors to stderr using internal error protocol. */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_set_failure_internal(void);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* If writing to log fails, ignore it instead of existing with
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen FATAL_LOGWRITE or FATAL_LOGERROR. */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_set_failure_ignore_errors(bool ignore);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Send informational messages to specified log file. i_set_failure_*()
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen functions modify the info file too, so call this function after them. */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_set_info_file(const char *path);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Send debug-level message to the given log file. The i_set_info_file()
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen function modifies also the debug log file, so call this function after it. */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_set_debug_file(const char *path);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Set the failure prefix. */
cdc7e0c3492f8b68699e4d19f0c96ba67f880e48Timo Sirainenvoid i_set_failure_prefix(const char *prefix_fmt, ...) ATTR_FORMAT(1, 2);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Set prefix to "". */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_unset_failure_prefix(void);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Prefix failures with a timestamp. fmt is in strftime() format. */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_set_failure_timestamp_format(const char *fmt);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* When logging with internal error protocol, update the process's current
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen IP address / log prefix by sending it to log process. This is mainly used to
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen improve the error message if the process crashes. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_failure_send_ip(const struct ip_addr *ip);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_failure_send_prefix(const char *prefix);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Call the callback before exit()ing. The callback may update the status. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid i_set_failure_exit_callback(void (*callback)(int *status));
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen/* Call the exit callback and exit() */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid failure_exit(int status) ATTR_NORETURN ATTR_COLD;
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen/* Parse a line logged using internal failure handler */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenvoid i_failure_parse_line(const char *line, struct failure_line *failure);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenvoid failures_deinit(void);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen#endif
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen