aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xtl_logger_stdio.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-05-28 09:29:15 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-05-28 09:29:15 +0100
commit7f9a888af4b65cb8c22cea3c8295d30d0fedd623 (patch)
tree84001e50ab1b7f9fa6bb45494dab0d241cc72253 /tools/libxc/xtl_logger_stdio.c
parent36cfb6aa84c1b5a5b5ac15883e34b10f32ab0ab8 (diff)
downloadxen-7f9a888af4b65cb8c22cea3c8295d30d0fedd623.tar.gz
xen-7f9a888af4b65cb8c22cea3c8295d30d0fedd623.tar.bz2
xen-7f9a888af4b65cb8c22cea3c8295d30d0fedd623.zip
xtl: New xentoollog mini-library.
We provide a new header file "xentoollog.h" which defines an interface that libraries and applications can use for logging. This avoids having to wrap each library's log callbacks up, massage arguments to log callbacks, and so on. The library's .o files are within libxc to avoid having to create a separate lib*.a, but callers do not need to #include xenctrl.h and it should be regarded as a separate API. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxc/xtl_logger_stdio.c')
-rw-r--r--tools/libxc/xtl_logger_stdio.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/tools/libxc/xtl_logger_stdio.c b/tools/libxc/xtl_logger_stdio.c
new file mode 100644
index 0000000000..587c67da6a
--- /dev/null
+++ b/tools/libxc/xtl_logger_stdio.c
@@ -0,0 +1,122 @@
+/*
+ * xtl_logger_stdio.c
+ *
+ * log message consumer that writes to stdio
+ *
+ * Copyright (c) 2010 Citrix
+ * Part of a generic logging interface used by various dom0 userland libraries.
+ */
+
+#include "xentoollog.h"
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+struct xentoollog_logger_stdiostream {
+ xentoollog_logger vtable;
+ FILE *f;
+ xentoollog_level min_level;
+ unsigned flags;
+ int progress_erase_len, progress_last_percent;
+};
+
+static void progress_erase(xentoollog_logger_stdiostream *lg) {
+ if (lg->progress_erase_len)
+ fprintf(lg->f, "\r%*s\r", lg->progress_erase_len, "");
+}
+
+static void stdiostream_vmessage(xentoollog_logger *logger_in,
+ xentoollog_level level,
+ int errnoval,
+ const char *context,
+ const char *format,
+ va_list al) {
+ xentoollog_logger_stdiostream *lg = (void*)logger_in;
+
+ progress_erase(lg);
+
+ if (lg->flags & XTL_STDIOSTREAM_SHOW_DATE) {
+ struct tm lt_buf;
+ time_t now = time(0);
+ struct tm *lt= localtime_r(&now, &lt_buf);
+ fprintf(lg->f, "%04d-%02d-%02d %02d:%02d:%02d %s ",
+ lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday,
+ lt->tm_hour, lt->tm_min, lt->tm_sec,
+ tzname[daylight ? !!lt->tm_isdst : 0]);
+ }
+ if (lg->flags & XTL_STDIOSTREAM_SHOW_PID)
+ fprintf(lg->f, "[%lu] ", (unsigned long)getpid());
+
+ if (context)
+ fprintf(lg->f, "%s: ", context);
+
+ fprintf(lg->f, "%s: ", xtl_level_to_string(level));
+
+ vfprintf(lg->f, format, al);
+
+ if (errnoval >= 0)
+ vfprintf(lg->f, ": %s", strerror(errnoval));
+
+ putc('\n', lg->f);
+ fflush(lg->f);
+}
+
+static void stdiostream_progress(struct xentoollog_logger *logger_in,
+ const char *context,
+ const char *doing_what, int percent,
+ unsigned long done, unsigned long total) {
+ xentoollog_logger_stdiostream *lg = (void*)logger_in;
+ int newpel, extra_erase;
+ xentoollog_level this_level;
+
+ if (percent < lg->progress_last_percent) {
+ this_level = XTL_PROGRESS;
+ } else if (percent == lg->progress_last_percent) {
+ return;
+ } else if (percent < lg->progress_last_percent + 5) {
+ this_level = XTL_DETAIL;
+ } else {
+ this_level = XTL_PROGRESS;
+ }
+
+ if (lg->min_level < this_level)
+ return;
+
+ if (lg->progress_erase_len)
+ putc('\r', lg->f);
+
+ newpel = fprintf(lg->f, "%s%s" "%s: %lu/%lu %3d%%",
+ context?context:"", context?": ":"",
+ doing_what, done, total, percent);
+
+ extra_erase = lg->progress_erase_len - newpel;
+ if (extra_erase > 0)
+ fprintf(lg->f, "%*s\r", extra_erase, "");
+
+ lg->progress_erase_len = newpel;
+}
+
+static void stdiostream_destroy(struct xentoollog_logger *logger_in) {
+ xentoollog_logger_stdiostream *lg = (void*)logger_in;
+ progress_erase(lg);
+ free(lg);
+}
+
+
+xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
+ (FILE *f, xentoollog_level min_level, unsigned flags) {
+ xentoollog_logger_stdiostream newlogger;
+
+ newlogger.f = f;
+ newlogger.min_level = min_level;
+ newlogger.flags = flags;
+
+ if (newlogger.flags & XTL_STDIOSTREAM_SHOW_DATE) tzset();
+
+ newlogger.progress_erase_len = 0;
+
+ return XTL_NEW_LOGGER(stdiostream, newlogger);
+}