VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTrayLogging.cpp@ 106945

Last change on this file since 106945 was 106411, checked in by vboxsync, 7 weeks ago

Additions/VBoxTray: Implemented ability for easier user-controllable logging (also via verbose levels), support for running in foreground mode (with a console window attached to) and selective starting of sub services to easier pinpoint errors in release builds. Cleaned up initialization / termination code a little. See command line help for new options. bugref:10763

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1/* $Id: VBoxTrayLogging.cpp 106411 2024-10-17 07:44:43Z vboxsync $ */
2/** @file
3 * VBoxTrayLogging.cpp - Logging.
4 */
5
6/*
7 * Copyright (C) 2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <package-generated.h>
33#include "product-generated.h"
34
35#include "VBoxTray.h"
36#include "VBoxTrayInternal.h"
37
38#include <iprt/buildconfig.h>
39#include <iprt/process.h>
40#include <iprt/system.h>
41
42
43/*********************************************************************************************************************************
44* Global Variables *
45*********************************************************************************************************************************/
46static PRTLOGGER g_pLoggerRelease = NULL; /**< This is actually the debug logger in DEBUG builds! */
47/** Note: The following parameters are not yet modifiable via command line or some such, but keep them here for later. */
48static uint32_t g_cHistory = 10; /**< Enable log rotation, 10 files. */
49static uint32_t g_uHistoryFileTime = RT_SEC_1DAY; /**< Max 1 day per file. */
50static uint64_t g_uHistoryFileSize = 100 * _1M; /**< Max 100MB per file. */
51
52
53/**
54 * Header/footer callback for the release logger.
55 *
56 * @param pLoggerRelease
57 * @param enmPhase
58 * @param pfnLog
59 */
60static DECLCALLBACK(void) vboxTrayLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
61{
62 /* Some introductory information. */
63 static RTTIMESPEC s_TimeSpec;
64 char szTmp[256];
65 if (enmPhase == RTLOGPHASE_BEGIN)
66 RTTimeNow(&s_TimeSpec);
67 RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));
68
69 switch (enmPhase)
70 {
71 case RTLOGPHASE_BEGIN:
72 {
73 pfnLog(pLoggerRelease,
74 "VBoxTray %s r%s %s (%s %s) release log\n"
75 "Log opened %s\n",
76 RTBldCfgVersion(), RTBldCfgRevisionStr(), VBOX_BUILD_TARGET,
77 __DATE__, __TIME__, szTmp);
78
79 int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
80 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
81 pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp);
82 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
83 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
84 pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp);
85 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
86 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
87 pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp);
88 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
89 pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp);
90
91 /* the package type is interesting for Linux distributions */
92 char szExecName[RTPATH_MAX];
93 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
94 pfnLog(pLoggerRelease,
95 "Executable: %s\n"
96 "Process ID: %u\n"
97 "Package type: %s"
98#ifdef VBOX_OSE
99 " (OSE)"
100#endif
101 "\n",
102 pszExecName ? pszExecName : "unknown",
103 RTProcSelf(),
104 VBOX_PACKAGE_STRING);
105 break;
106 }
107
108 case RTLOGPHASE_PREROTATE:
109 pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp);
110 break;
111
112 case RTLOGPHASE_POSTROTATE:
113 pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp);
114 break;
115
116 case RTLOGPHASE_END:
117 pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp);
118 break;
119
120 default:
121 /* nothing */;
122 }
123}
124
125/**
126 * Creates the default release logger outputting to the specified file.
127 *
128 * @return VBox status code.
129 * @param pszLogFile Path to log file to use. Can be NULL if not needed.
130 */
131int VBoxTrayLogCreate(const char *pszLogFile)
132{
133 /* Create release (or debug) logger (stdout + file). */
134 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
135#ifdef DEBUG
136 static const char s_szEnvVarPfx[] = "VBOXTRAY_LOG";
137 static const char s_szGroupSettings[] = "all.e.l.f";
138#else
139 static const char s_szEnvVarPfx[] = "VBOXTRAY_RELEASE_LOG";
140 static const char s_szGroupSettings[] = "all";
141#endif
142 RTERRINFOSTATIC ErrInfo;
143 int rc = RTLogCreateEx(&g_pLoggerRelease, s_szEnvVarPfx,
144 RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_USECRLF,
145 s_szGroupSettings, RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
146 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT,
147 vboxTrayLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
148 NULL /*pOutputIf*/, NULL /*pvOutputIfUser*/,
149 RTErrInfoInitStatic(&ErrInfo), "%s", pszLogFile ? pszLogFile : "");
150 if (RT_SUCCESS(rc))
151 {
152 char szGroupSettings[_1K];
153
154#ifdef DEBUG
155 /* Register this logger as the _debug_ logger. */
156 RTLogSetDefaultInstance(g_pLoggerRelease);
157#else
158 /* Register this logger as the release logger. */
159 RTLogRelSetDefaultInstance(g_pLoggerRelease);
160#endif
161 /* If verbosity is explicitly set, make sure to increase the logging levels for
162 * the logging groups we offer functionality for in VBoxTray. */
163 if (g_cVerbosity)
164 {
165 /* All groups we want to enable logging for VBoxTray. */
166#ifdef DEBUG
167 const char *apszGroups[] = { "guest_dnd", "shared_clipboard" };
168#else /* For release builds we always want all groups being logged in verbose mode. Don't change this! */
169 const char *apszGroups[] = { "all" };
170#endif
171 szGroupSettings[0] = '\0';
172
173 for (size_t i = 0; i < RT_ELEMENTS(apszGroups); i++)
174 {
175 if (i > 0)
176 rc = RTStrCat(szGroupSettings, sizeof(szGroupSettings), "+");
177 if (RT_SUCCESS(rc))
178 rc = RTStrCat(szGroupSettings, sizeof(szGroupSettings), apszGroups[i]);
179 if (RT_FAILURE(rc))
180 break;
181
182 switch (g_cVerbosity)
183 {
184 case 1:
185 rc = RTStrCat(szGroupSettings, sizeof(szGroupSettings), ".e.l.l2");
186 break;
187
188 case 2:
189 rc = RTStrCat(szGroupSettings, sizeof(szGroupSettings), ".e.l.l2.l3");
190 break;
191
192 case 3:
193 rc = RTStrCat(szGroupSettings, sizeof(szGroupSettings), ".e.l.l2.l3.l4");
194 break;
195
196 case 4:
197 RT_FALL_THROUGH();
198 default:
199 rc = RTStrCat(szGroupSettings, sizeof(szGroupSettings), ".e.l.l2.l3.l4.f");
200 break;
201 }
202
203 if (RT_FAILURE(rc))
204 break;
205 }
206
207 if (RT_SUCCESS(rc))
208 {
209 rc = RTLogGroupSettings(g_pLoggerRelease, szGroupSettings);
210 if (RT_FAILURE(rc))
211 VBoxTrayShowError("Setting log group settings failed, rc=%Rrc\n", rc);
212 }
213 }
214
215 /* Explicitly flush the log in case of VBOXTRAY_RELEASE_LOG=buffered. */
216 RTLogFlush(g_pLoggerRelease);
217
218 VBoxTrayInfo("Verbosity level: %d\n", g_cVerbosity);
219
220 int const rc2 = RTLogQueryGroupSettings(g_pLoggerRelease, szGroupSettings, sizeof(szGroupSettings));
221 if (RT_SUCCESS(rc2))
222 VBoxTrayInfo("Log group settings are: %s\n", szGroupSettings);
223 }
224 else
225 VBoxTrayShowError(ErrInfo.szMsg);
226
227 return rc;
228}
229
230/**
231 * Destroys the logging.
232 */
233void VBoxTrayLogDestroy(void)
234{
235 /* Only want to destroy the release logger before calling exit(). The debug
236 logger can be useful after that point... */
237 RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
238}
239
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette