From: John Wolfe Date: Fri, 21 Jan 2022 00:48:45 +0000 (-0800) Subject: The header added to the vmsvc log file is repeated at log file rotation. X-Git-Tag: stable-12.0.0~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10dd041d5e5c7604fb525ec72cf314a27ea0c166;p=thirdparty%2Fopen-vm-tools.git The header added to the vmsvc log file is repeated at log file rotation. The log entry with the tools version, tools build number and guest OS details added at the start of the vmsvc log file is repeated when log file rotation occurs. --- diff --git a/open-vm-tools/lib/glibUtils/fileLogger.c b/open-vm-tools/lib/glibUtils/fileLogger.c index a9619a379..1ec6b2380 100644 --- a/open-vm-tools/lib/glibUtils/fileLogger.c +++ b/open-vm-tools/lib/glibUtils/fileLogger.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2010-2019, 2021 VMware, Inc. All rights reserved. + * Copyright (C) 2010-2019, 2021-2022 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -392,6 +392,7 @@ FileLoggerLog(const gchar *domain, g_io_channel_unref(logger->file); logger->append = FALSE; logger->file = FileLoggerOpen(logger); + logger->handler.logHeader = TRUE; } else { g_io_channel_flush(logger->file, NULL); } @@ -460,6 +461,7 @@ GlibUtils_CreateFileLogger(const char *path, data->handler.shared = FALSE; data->handler.logfn = FileLoggerLog; data->handler.dtor = FileLoggerDestroy; + data->handler.logHeader = TRUE; data->path = g_filename_from_utf8(path, -1, NULL, NULL, NULL); if (data->path == NULL) { diff --git a/open-vm-tools/lib/include/glibUtils.h b/open-vm-tools/lib/include/glibUtils.h index 228617c36..79e0ade9a 100644 --- a/open-vm-tools/lib/include/glibUtils.h +++ b/open-vm-tools/lib/include/glibUtils.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2011-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2011-2017, 2022 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -54,6 +54,7 @@ typedef struct GlibLogger { gboolean addsTimestamp; /**< Output adds timestamp automatically. */ GLogFunc logfn; /**< The function that writes to the output. */ GDestroyNotify dtor; /**< Destructor. */ + gboolean logHeader; /**< Header needs to be logged. */ } GlibLogger; diff --git a/open-vm-tools/libvmtools/vmtoolsLog.c b/open-vm-tools/libvmtools/vmtoolsLog.c index 3e3d5c11f..0487983b6 100644 --- a/open-vm-tools/libvmtools/vmtoolsLog.c +++ b/open-vm-tools/libvmtools/vmtoolsLog.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2008-2021 VMware, Inc. All rights reserved. + * Copyright (C) 2008-2022 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -125,6 +125,8 @@ #define VMX_LOG_CMD "log " #define VMX_LOG_CMD_LEN (sizeof(VMX_LOG_CMD) - 1) +#define LOG_HEADER_MAX_ENTRIES 2 + typedef struct LogHandler { GlibLogger *logger; @@ -199,6 +201,9 @@ static RpcChannel *gChannel; /* either NULL or allocated AND started */ */ static GLogLevelFlags gLevelMask; +static gchar *gLogHeaderBuf[LOG_HEADER_MAX_ENTRIES]; +static guint gLogHeaderCount; + static enum RpcMode { RPC_OFF = 0, RPC_GUEST_LOG_TEXT, @@ -217,6 +222,7 @@ static void LogWhereLevelV(LogWhere where, const gchar *domain, const gchar *fmt, va_list args); +static LogHandler *GetLogHandlerByDomain(const gchar *domain); /* Internal functions. */ @@ -501,6 +507,31 @@ VMToolsFreeLogEntry(gpointer data) } +/** + * Function that logs a cached log header of Tools version, build details + * and Guest OS details. + * + * @param[in] _data LogEntry pointer. + */ + +static void +VMToolsLogHeader(gpointer _data) +{ + LogEntry *entry = _data; + GlibLogger *logger = entry->handler->logger; + guint i; + + for (i = 0; i < gLogHeaderCount; i++) { + char *message = VMToolsLogFormat(gLogHeaderBuf[i], entry->domain, + G_LOG_LEVEL_MESSAGE, entry->handler, + FALSE); + + logger->logfn(entry->domain, G_LOG_LEVEL_MESSAGE, message, logger); + g_free(message); + } +} + + /** * Function that calls the log handler. * @@ -518,6 +549,10 @@ VMToolsLogMsg(gpointer _data, gpointer userData) gboolean usedSyslog = FALSE; if (logger != NULL) { + if (logger->logHeader) { + VMToolsLogHeader(entry); + logger->logHeader = FALSE; + } logger->logfn(entry->domain, entry->level, entry->msg, logger); usedSyslog = entry->handler->isSysLog; } else if (gErrorData->logger != NULL) { @@ -1496,14 +1531,31 @@ VMToolsConfigLoggingInt(const gchar *defaultDomain, MarkLogInitialized(); /* - * Log Tools version, build information and guest OS details. + * Cache Tools version, build number and guest OS details. + * Cached log headers will be logged at log rotation and reset. + * No need to re-init the log headers in case of config reload. */ - g_message("%s Version: %s (%s)", VMWARE_TOOLS_SHORT_NAME, - TOOLS_VERSION_EXT_CURRENT_STR, BUILD_NUMBER); - gosDetails = Hostinfo_GetOSDetailedData(); - if (gosDetails != NULL) { - g_message("Guest OS details: %s", gosDetails); + if (gLogHeaderCount == 0) { + LogHandler *handler = GetLogHandlerByDomain(gLogDomain); + GlibLogger *logger = handler->logger; + + logger->logHeader = TRUE; + + gLogHeaderBuf[gLogHeaderCount++] = Str_Asprintf(NULL, + "%s Version: %s (%s)", + VMWARE_TOOLS_SHORT_NAME, + TOOLS_VERSION_EXT_CURRENT_STR, + BUILD_NUMBER); + + gosDetails = Hostinfo_GetOSDetailedData(); + if (gosDetails != NULL && gLogHeaderCount < LOG_HEADER_MAX_ENTRIES) { + gLogHeaderBuf[gLogHeaderCount++] = Str_Asprintf(NULL, + "Guest OS details: %s", + gosDetails); + } free(gosDetails); + + ASSERT(gLogHeaderCount <= LOG_HEADER_MAX_ENTRIES); } gMaxCacheEntries = g_key_file_get_integer(cfg, LOGGING_GROUP,