[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] Imprint all logs with version + package build information



The logging functions are enhanced so that immediately prior to
the first log message being printed to any output channel, the
libvirt package version will be printed.

eg

 $ LIBVIRT_DEBUG=1 virsh
 18:13:28.013: 17536: info : libvirt version: 0.8.7
 18:13:28.013: 17536: debug : virInitialize:361 : register drivers
 ...

The 'configure' script gains a '--with-package-string' argument
to allow distros to append a custom string with package specific
data.

The RPM specfile is modified so that it appends the RPM version,
the build host, the build date and the packager name.

eg

 $ LIBVIRT_DEBUG=1 virsh
 18:14:52.086: 17551: info : libvirt version: 0.8.7, package: 1.fc13 (Fedora Project, x86-01.phx2.fedoraproject.org, 01-27-2011-18:00:10)
 18:14:52.086: 17551: debug : virInitialize:361 : register drivers

Thus when distro packagers receive bug reports they can clearly
see what version was in use, even if the bug reporter mistakenly
or intentionally lies about version/builds

* src/util/logging.c: Output version data prior to first log message
* libvirt.spec.in: Include RPM release, date, hostname & packager
* configure.ac: Add --with-package-string arg
---
 configure.ac       |   10 ++++++
 libvirt.spec.in    |    7 ++++
 src/util/logging.c |   86 +++++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/configure.ac b/configure.ac
index f310a5e..92d77e4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,16 @@ AC_SUBST([LIBVIRT_VERSION])
 AC_SUBST([LIBVIRT_VERSION_INFO])
 AC_SUBST([LIBVIRT_VERSION_NUMBER])
 
+AC_ARG_WITH([package-string],
+            [AS_HELP_STRING([--with-package-string],
+                            [Extra package name/version string])],
+            [],[])
+if test "x$with_package_string" != "xno"
+then
+  AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$with_package_string"],
+                     [Extra package name/version string])
+fi
+
 dnl Required minimum versions of all libs we depend on
 LIBXML_REQUIRED="2.6.0"
 GNUTLS_REQUIRED="1.0.25"
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 0a2d10e..43c9067 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -592,6 +592,12 @@ of recent versions of Linux (and other OSes).
 %define _without_dtrace --without-dtrace
 %endif
 
+%define when  %(date +"%%m-%%d-%%Y-%%H:%%M:%%S")
+%define where %(hostname)
+%define who   %{?packager}%{!?packager:Unknown}
+%define with_package_string --with-package-string="%{release} (%{who}, %{when}, %{where})"
+
+
 %configure %{?_without_xen} \
            %{?_without_qemu} \
            %{?_without_openvz} \
@@ -626,6 +632,7 @@ of recent versions of Linux (and other OSes).
            %{?_without_macvtap} \
            %{?_without_audit} \
            %{?_without_dtrace} \
+           %{with_package_string} \
            --with-qemu-user=%{qemu_user} \
            --with-qemu-group=%{qemu_group} \
            --with-init-script=redhat \
diff --git a/src/util/logging.c b/src/util/logging.c
index a80c3e3..5102e06 100644
--- a/src/util/logging.c
+++ b/src/util/logging.c
@@ -108,6 +108,7 @@ static int virLogNbFilters = 0;
  * after filtering, multiple output can be used simultaneously
  */
 struct _virLogOutput {
+    bool logVersion;
     void *data;
     virLogOutputFunc f;
     virLogCloseFunc c;
@@ -490,6 +491,7 @@ int virLogDefineOutput(virLogOutputFunc f, virLogCloseFunc c, void *data,
         goto cleanup;
     }
     ret = virLogNbOutputs++;
+    virLogOutputs[ret].logVersion = true;
     virLogOutputs[ret].f = f;
     virLogOutputs[ret].c = c;
     virLogOutputs[ret].data = data;
@@ -501,6 +503,50 @@ cleanup:
     return ret;
 }
 
+static int
+virLogFormatString(char **msg,
+                   const char *funcname,
+                   long long linenr,
+                   struct tm *time_info,
+                   struct timeval *cur_time,
+                   int priority,
+                   const char *str)
+{
+    int ret;
+    if ((funcname != NULL)) {
+        ret = virAsprintf(msg, "%02d:%02d:%02d.%03d: %d: %s : %s:%lld : %s\n",
+                          time_info->tm_hour, time_info->tm_min,
+                          time_info->tm_sec, (int) cur_time->tv_usec / 1000,
+                          virThreadSelfID(),
+                          virLogPriorityString(priority), funcname, linenr, str);
+    } else {
+        ret = virAsprintf(msg, "%02d:%02d:%02d.%03d: %d: %s : %s\n",
+                          time_info->tm_hour, time_info->tm_min,
+                          time_info->tm_sec, (int) cur_time->tv_usec / 1000,
+                          virThreadSelfID(),
+                          virLogPriorityString(priority), str);
+    }
+    return ret;
+}
+
+static int
+virLogVersionString(char **msg,
+                    struct tm *time_info,
+                    struct timeval *cur_time)
+{
+#ifdef PACKAGE_STRING
+# define LOG_VERSION_STRING                     \
+    "libvirt version: " VERSION ", package: " PACKAGE_STRING
+#else
+# define LOG_VERSION_STRING                             \
+    "libvirt version: " VERSION
+#endif
+
+    return virLogFormatString(msg, NULL, 0,
+                              time_info, cur_time,
+                              VIR_LOG_INFO, LOG_VERSION_STRING);
+}
+
 /**
  * virLogMessage:
  * @category: where is that message coming from
@@ -516,6 +562,7 @@ cleanup:
  */
 void virLogMessage(const char *category, int priority, const char *funcname,
                    long long linenr, int flags, const char *fmt, ...) {
+    static bool logVersionStderr = true;
     char *str = NULL;
     char *msg;
     struct timeval cur_time;
@@ -547,19 +594,9 @@ void virLogMessage(const char *category, int priority, const char *funcname,
     gettimeofday(&cur_time, NULL);
     localtime_r(&cur_time.tv_sec, &time_info);
 
-    if ((funcname != NULL)) {
-        ret = virAsprintf(&msg, "%02d:%02d:%02d.%03d: %d: %s : %s:%lld : %s\n",
-                          time_info.tm_hour, time_info.tm_min,
-                          time_info.tm_sec, (int) cur_time.tv_usec / 1000,
-                          virThreadSelfID(),
-                          virLogPriorityString(priority), funcname, linenr, str);
-    } else {
-        ret = virAsprintf(&msg, "%02d:%02d:%02d.%03d: %d: %s : %s\n",
-                          time_info.tm_hour, time_info.tm_min,
-                          time_info.tm_sec, (int) cur_time.tv_usec / 1000,
-                          virThreadSelfID(),
-                          virLogPriorityString(priority), str);
-    }
+    ret = virLogFormatString(&msg, funcname, linenr,
+                             &time_info, &cur_time,
+                             priority, str);
     VIR_FREE(str);
     if (ret < 0) {
         /* apparently we're running out of memory */
@@ -578,12 +615,31 @@ void virLogMessage(const char *category, int priority, const char *funcname,
     virLogStr(msg, len);
     virLogLock();
     for (i = 0; i < virLogNbOutputs;i++) {
-        if (priority >= virLogOutputs[i].priority)
+        if (priority >= virLogOutputs[i].priority) {
+            if (virLogOutputs[i].logVersion) {
+                char *ver = NULL;
+                if (virLogVersionString(&ver, &time_info, &cur_time) >= 0)
+                    virLogOutputs[i].f(category, priority, __func__, __LINE__,
+                                       ver, strlen(ver),
+                                       virLogOutputs[i].data);
+                VIR_FREE(ver);
+                virLogOutputs[i].logVersion = false;
+            }
             virLogOutputs[i].f(category, priority, funcname, linenr,
                                msg, len, virLogOutputs[i].data);
+        }
     }
-    if ((virLogNbOutputs == 0) && (flags != 1))
+    if ((virLogNbOutputs == 0) && (flags != 1)) {
+        if (logVersionStderr) {
+            char *ver = NULL;
+            if (virLogVersionString(&ver, &time_info, &cur_time) >= 0)
+                ignore_value (safewrite(STDERR_FILENO,
+                                        ver, strlen(ver)));
+            VIR_FREE(ver);
+            logVersionStderr = false;
+        }
         ignore_value (safewrite(STDERR_FILENO, msg, len));
+    }
     virLogUnlock();
 
     VIR_FREE(msg);
-- 
1.7.3.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]