1 /*
2  * xentoollog.h
3  *
4  * Copyright (c) 2010 Citrix
5  * Part of a generic logging interface used by various dom0 userland libraries.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation;
10  * version 2.1 of the License.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef XENTOOLLOG_H
22 #define XENTOOLLOG_H
23 
24 #include <stdio.h>
25 #include <stdarg.h>
26 
27 
28 /*---------- common declarations and types ----------*/
29 
30 typedef enum xentoollog_level {
31     XTL_NONE, /* sentinel etc, never used for logging */
32     XTL_DEBUG,
33     XTL_VERBOSE,
34     XTL_DETAIL,
35     XTL_PROGRESS, /* also used for "progress" messages */
36     XTL_INFO,
37     XTL_NOTICE,
38     XTL_WARN,
39     XTL_ERROR,
40     XTL_CRITICAL,
41     XTL_NUM_LEVELS
42 } xentoollog_level;
43 
44 typedef struct xentoollog_logger xentoollog_logger;
45 struct xentoollog_logger {
46     void (*vmessage)(struct xentoollog_logger *logger,
47                      xentoollog_level level,
48                      int errnoval /* or -1 */,
49                      const char *context /* eg "xc", "xl", may be 0 */,
50                      const char *format /* without level, context, \n */,
51                      va_list al)
52          __attribute__((format(printf,5,0)));
53     void (*progress)(struct xentoollog_logger *logger,
54                      const char *context /* see above */,
55                      const char *doing_what /* no \r,\n */,
56                      int percent, unsigned long done, unsigned long total)
57          /* null function pointer is ok.
58           * will always be called with done==0 for each new
59           * context/doing_what */;
60     void (*destroy)(struct xentoollog_logger *logger);
61     /* each logger can put its necessary data here */
62 };
63 
64 
65 /*---------- facilities for consuming log messages ----------*/
66 
67 #define XTL_STDIOSTREAM_SHOW_PID            001u
68 #define XTL_STDIOSTREAM_SHOW_DATE           002u
69 #define XTL_STDIOSTREAM_HIDE_PROGRESS       004u
70 #define XTL_STDIOSTREAM_PROGRESS_USE_CR     010u /* default is to */
71 #define XTL_STDIOSTREAM_PROGRESS_NO_CR      020u /* use \r to ttys */
72 
73 typedef struct xentoollog_logger_stdiostream  xentoollog_logger_stdiostream;
74 
75 xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
76         (FILE *f, xentoollog_level min_level, unsigned flags);
77     /* may return 0 if malloc fails, in which case error was logged */
78     /* destroy on this logger does not close the file */
79 
80 void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream*,
81                                   xentoollog_level min_level);
82 void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream*,
83                                   unsigned set_flags, unsigned clear_flags);
84   /* if set_flags and clear_flags overlap, set_flags takes precedence */
85 
86 void xtl_logger_destroy(struct xentoollog_logger *logger /* 0 is ok */);
87 
88 
89 /*---------- facilities for generating log messages ----------*/
90 
91 void xtl_logv(struct xentoollog_logger *logger,
92               xentoollog_level level,
93               int errnoval /* or -1 */,
94               const char *context /* eg "xc", "xenstore", "xl", may be 0 */,
95               const char *format /* does not contain \n */,
96               va_list) __attribute__((format(printf,5,0)));
97 
98 void xtl_log(struct xentoollog_logger *logger,
99              xentoollog_level level,
100              int errnoval /* or -1 */,
101              const char *context /* eg "xc", "xenstore", "xl" */,
102              const char *format /* does not contain \n */,
103              ...) __attribute__((format(printf,5,6)));
104 
105 void xtl_progress(struct xentoollog_logger *logger,
106                   const char *context /* see above, may be 0 */,
107                   const char *doing_what,
108                   unsigned long done, unsigned long total);
109 
110 
111 /*---------- facilities for defining log message consumers ----------*/
112 
113 const char *xtl_level_to_string(xentoollog_level); /* never fails */
114 
115 
116 #define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
117     xentoollog_logger_##LOGGER *new_consumer;                           \
118                                                                         \
119     (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
120     (buffer).vtable.progress = LOGGER##_progress;                       \
121     (buffer).vtable.destroy  = LOGGER##_destroy;                        \
122                                                                         \
123     new_consumer = malloc(sizeof(*new_consumer));                       \
124     if (!new_consumer) {                                                \
125         xtl_log((xentoollog_logger*)&buffer,                            \
126                 XTL_CRITICAL, errno, "xtl",                             \
127                 "failed to allocate memory for new message logger");    \
128     } else {                                                            \
129         *new_consumer = buffer;                                         \
130     }                                                                   \
131                                                                         \
132     new_consumer;                                                       \
133 });
134 
135 
136 #endif /* XENTOOLLOG_H */
137 
138 /*
139  * Local variables:
140  * mode: C
141  * c-file-style: "BSD"
142  * c-basic-offset: 4
143  * tab-width: 4
144  * indent-tabs-mode: nil
145  * End:
146  */
147