aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xentoollog.h
blob: 40ac3c418fde07fdcc08b8a0cb8e6a971fc8216b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * xentoollog.h
 *
 * Copyright (c) 2010 Citrix
 * Part of a generic logging interface used by various dom0 userland libraries.
 */

#ifndef XENTOOLLOG_H
#define XENTOOLLOG_H

#include <stdio.h>
#include <stdarg.h>


/*---------- common declarations and types ----------*/

typedef enum xentoollog_level {
    XTL_NONE, /* sentinel etc, never used for logging */
    XTL_DEBUG,
    XTL_VERBOSE,
    XTL_DETAIL,
    XTL_PROGRESS, /* also used for "progress" messages */
    XTL_INFO,
    XTL_NOTICE,
    XTL_WARN,
    XTL_ERROR,
    XTL_CRITICAL,
    XTL_NUM_LEVELS
} xentoollog_level;

typedef struct xentoollog_logger xentoollog_logger;
struct xentoollog_logger {
    void (*vmessage)(struct xentoollog_logger *logger,
                     xentoollog_level level,
                     int errnoval /* or -1 */,
                     const char *context /* eg "xc", "xl", may be 0 */,
                     const char *format /* without level, context, \n */,
                     va_list al)
         __attribute__((format(printf,5,0)));
    void (*progress)(struct xentoollog_logger *logger,
                     const char *context /* see above */,
                     const char *doing_what /* no \r,\n */,
                     int percent, unsigned long done, unsigned long total)
         /* null function pointer is ok.
          * will always be called with done==0 for each new
          * context/doing_what */;
    void (*destroy)(struct xentoollog_logger *logger);
    /* each logger can put its necessary data here */
};


/*---------- facilities for consuming log messages ----------*/

#define XTL_STDIOSTREAM_SHOW_PID      01u
#define XTL_STDIOSTREAM_SHOW_DATE     02u
#define XTL_STDIOSTREAM_HIDE_PROGRESS 04u

typedef struct xentoollog_logger_stdiostream  xentoollog_logger_stdiostream;

xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
        (FILE *f, xentoollog_level min_level, unsigned flags);
    /* may return 0 if malloc fails, in which case error was logged */
    /* destroy on this logger does not close the file */

void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream*,
                                  xentoollog_level min_level);
void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream*,
                                  unsigned set_flags, unsigned clear_flags);
  /* if set_flags and clear_flags overlap, set_flags takes precedence */

void xtl_logger_destroy(struct xentoollog_logger *logger /* 0 is ok */);


/*---------- facilities for generating log messages ----------*/

void xtl_logv(struct xentoollog_logger *logger,
              xentoollog_level level,
              int errnoval /* or -1 */,
              const char *context /* eg "xc", "xenstore", "xl", may be 0 */,
              const char *format /* does not contain \n */,
              va_list) __attribute__((format(printf,5,0)));

void xtl_log(struct xentoollog_logger *logger,
             xentoollog_level level,
             int errnoval /* or -1 */,
             const char *context /* eg "xc", "xenstore", "xl" */,
             const char *format /* does not contain \n */,
             ...) __attribute__((format(printf,5,6)));

void xtl_progress(struct xentoollog_logger *logger,
                  const char *context /* see above, may be 0 */,
                  const char *doing_what,
                  unsigned long done, unsigned long total);


/*---------- facilities for defining log message consumers ----------*/

const char *xtl_level_to_string(xentoollog_level); /* never fails */


#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
    xentoollog_logger_##LOGGER *new_consumer;                           \
                                                                        \
    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
    (buffer).vtable.progress = LOGGER##_progress;                       \
    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
                                                                        \
    new_consumer = malloc(sizeof(*new_consumer));                       \
    if (!new_consumer) {                                                \
        xtl_log((xentoollog_logger*)&buffer,                            \
                XTL_CRITICAL, errno, "xtl",                             \
                "failed to allocate memory for new message logger");    \
    } else {                                                            \
        *new_consumer = buffer;                                         \
    }                                                                   \
                                                                        \
    new_consumer;                                                       \
});


#endif /* XENTOOLLOG_H */