logging.h 4.68 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright 2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
 *
 * This file is part of the turris updater.
 *
 * Updater is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * Updater is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Updater.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef UPDATER_LOGGING_H
#define UPDATER_LOGGING_H

Karel Koci's avatar
Karel Koci committed
22
#ifndef _GNU_SOURCE
23
#define _GNU_SOURCE
Karel Koci's avatar
Karel Koci committed
24
#endif
25 26 27 28 29
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "util.h"

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
enum log_state {
	LS_INIT, // Initial state
	LS_CONF, // Running configuration scripts
	LS_PLAN, // Generating plan
	LS_DOWN, // Downloading needed packages
	LS_PREUPD, // Running updater's preupdate hooks
	// These are states in critical section
	LS_UNPACK, // Unpacking downloaded packages
	LS_CHECK, // Checking for files collisions and more
	LS_INST, // Running preinst scripts and merging files to filesystem
	LS_POST, // Running postinst scripts
	LS_REM, // Removing leftover files
	LS_CLEANUP, // Cleaning up control files
	// End of critical section
	LS_POSTUPD, // Running updater's postupdate hooks
	LS_EXIT, // Updater exit
	LS_FAIL, // Detected failure, exiting.
};

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
enum log_level {
	LL_DISABLE,
	LL_DIE,
	LL_ERROR,
	LL_WARN,
	LL_INFO,
	LL_DBG,
	LL_TRACE,
	LL_UNKNOWN
};

void log_internal(enum log_level level, const char *file, size_t line, const char
		*func, const char *format, ...) __attribute__((format(printf, 5, 6)));

// Picosat is compiled with TRACE defined. We really want to use that name for our
// log output so let's redefine it here. Picosat expect it being defined so result
// is the same.
#undef TRACE

#define LOG(level, ...) log_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define ERROR(...) LOG(LL_ERROR, __VA_ARGS__)
#define WARN(...) LOG(LL_WARN, __VA_ARGS__)
#define INFO(...) LOG(LL_INFO, __VA_ARGS__)
#define DBG(...) LOG(LL_DBG, __VA_ARGS__)
#define TRACE(...) LOG(LL_TRACE, __VA_ARGS__)
#define DIE(...) do { LOG(LL_DIE, __VA_ARGS__); cleanup_run_all(); abort(); } while (0)
#define ASSERT_MSG(COND, ...) do { if (!(COND)) DIE(__VA_ARGS__); } while (0)
#define ASSERT(COND) do { if (!(COND)) DIE("Failed assert: " #COND); } while (0)

// If prepare of log would be long, check if it would be printed first.
bool would_log(enum log_level level);

enum log_level log_level_get(const char *str) __attribute__((nonnull));

// FILE log buffer. Initialize it and then you can build message using FILE. To print it use char_buffer.
struct log_buffer {
	FILE *f; // Use this as output and before printing it close this with fclose(f).
	char *char_buffer; // This contains resulting text. Don't forget to free this buffer.
	size_t buffer_len;
};
// Initialize log buffer (if would_log(level)
void log_buffer_init(struct log_buffer *buf, enum log_level level) __attribute__((nonnull));

// Sets if state and error should be dumped into files in /tmp/updater-state directory
void set_state_log(bool state_log);
94 95
// Log state change of updater
void update_state(enum log_state);
96 97 98 99 100 101 102 103
// In the full updater mode, dump the error into /tmp/update-state/error
void err_dump(const char *msg) __attribute__((nonnull));

void log_syslog_level(enum log_level level);
void log_syslog_name(const char *name);
void log_stderr_level(enum log_level level);
void setup_logging(enum log_level tty, enum log_level syslog);

104 105 106 107 108 109 110 111
// Following functions are intended to be used with subprocess functions to log
// out of subprocess in consistent way.
// You can pass pointer to char* variable to receive complete output from
// subprocess when log_subproc_close is called. Passing NULL results to buffer to
// be dropped. Note that it's your responsibility to free used memory by output
// afterward.
enum log_subproc_type {
	LST_PKG_SCRIPT, // This is post/pre install/rm script
112 113
	LST_HOOK, // This is updater's hook
	LST_USIGN // This is usign executable (this has explicitly lower logging level set to DBG)
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
};

struct log_subproc {
	// Use following streams
	FILE *out, *err;
	// Don't edit following fields
	enum log_subproc_type type;
	struct {
		FILE *f;
		char *buf;
		size_t size;
	} buffer; // Buffer for all output/input
};

void log_subproc_open(struct log_subproc *ls, enum log_subproc_type type, const char *message) __attribute__((nonnull));
129
void log_subproc_close(struct log_subproc *ls, char **output) __attribute__((nonnull(1)));
130

131
#endif