VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/logging.cpp@ 93115

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/* $Id: logging.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VirtualBox Guest Additions - X11 Client.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19#include <sys/wait.h>
20#include <stdlib.h>
21#include <iprt/buildconfig.h>
22#include <iprt/file.h>
23#include <iprt/process.h>
24#include <iprt/stream.h>
25#include <iprt/system.h>
26#include <VBox/VBoxGuestLib.h>
27#include <package-generated.h>
28#include "VBoxClient.h"
29
30/** Logging parameters. */
31/** @todo Make this configurable later. */
32static PRTLOGGER g_pLoggerRelease = NULL;
33static uint32_t g_cHistory = 10; /* Enable log rotation, 10 files. */
34static uint32_t g_uHistoryFileTime = RT_SEC_1DAY; /* Max 1 day per file. */
35static uint64_t g_uHistoryFileSize = 100 * _1M; /* Max 100MB per file. */
36
37extern unsigned g_cRespawn;
38extern unsigned g_cVerbosity;
39
40/**
41 * Notifies the desktop environment with a message.
42 *
43 * @param pszMessage Message to notify desktop environment with.
44 */
45int vbclLogNotify(const char *pszMessage)
46{
47 AssertPtrReturn(pszMessage, VERR_INVALID_POINTER);
48
49 int rc = VINF_SUCCESS;
50
51 if (g_cRespawn == 0)
52 {
53 char *pszCommand = RTStrAPrintf2("notify-send \"VBoxClient: %s\"", pszMessage);
54 if (pszCommand)
55 {
56 int status = system(pszCommand);
57
58 RTStrFree(pszCommand);
59
60 if (WEXITSTATUS(status) != 0) /* Utility or extension not available. */
61 {
62 pszCommand = RTStrAPrintf2("xmessage -buttons OK:0 -center \"VBoxClient: %s\"",
63 pszMessage);
64 if (pszCommand)
65 {
66 status = system(pszCommand);
67 if (WEXITSTATUS(status) != 0) /* Utility or extension not available. */
68 {
69 RTPrintf("VBoxClient: %s", pszMessage);
70 }
71
72 RTStrFree(pszCommand);
73 }
74 else
75 rc = VERR_NO_MEMORY;
76 }
77 }
78 else
79 rc = VERR_NO_MEMORY;
80 }
81
82 return rc;
83}
84
85/**
86 * Logs a verbose message.
87 *
88 * @param pszFormat The message text.
89 * @param va Format arguments.
90 */
91static void vbClLogV(const char *pszFormat, va_list va)
92{
93 char *psz = NULL;
94 RTStrAPrintfV(&psz, pszFormat, va);
95 AssertPtrReturnVoid(psz);
96 LogRel(("%s", psz));
97 RTStrFree(psz);
98}
99
100/**
101 * Logs a fatal error, notifies the desktop environment via a message and
102 * exits the application immediately.
103 *
104 * @param pszFormat Format string to log.
105 * @param ... Variable arguments for format string. Optional.
106 */
107void VBClLogFatalError(const char *pszFormat, ...)
108{
109 va_list args;
110 va_start(args, pszFormat);
111 char *psz = NULL;
112 RTStrAPrintfV(&psz, pszFormat, args);
113 va_end(args);
114
115 AssertPtrReturnVoid(psz);
116 LogFunc(("Fatal Error: %s", psz));
117 LogRel(("Fatal Error: %s", psz));
118
119 vbclLogNotify(psz);
120
121 RTStrFree(psz);
122}
123
124/**
125 * Logs an error message to the (release) logging instance.
126 *
127 * @param pszFormat Format string to log.
128 */
129void VBClLogError(const char *pszFormat, ...)
130{
131 va_list args;
132 va_start(args, pszFormat);
133 char *psz = NULL;
134 RTStrAPrintfV(&psz, pszFormat, args);
135 va_end(args);
136
137 AssertPtrReturnVoid(psz);
138 LogFunc(("Error: %s", psz));
139 LogRel(("Error: %s", psz));
140
141 RTStrFree(psz);
142}
143
144/**
145 * Logs an info message to the (release) logging instance.
146 *
147 * @param pszFormat Format string to log.
148 */
149void VBClLogInfo(const char *pszFormat, ...)
150{
151 va_list args;
152 va_start(args, pszFormat);
153 vbClLogV(pszFormat, args);
154 va_end(args);
155}
156
157/**
158 * Displays a verbose message based on the currently
159 * set global verbosity level.
160 *
161 * @param iLevel Minimum log level required to display this message.
162 * @param pszFormat The message text.
163 * @param ... Format arguments.
164 */
165void VBClLogVerbose(unsigned iLevel, const char *pszFormat, ...)
166{
167 if (iLevel <= g_cVerbosity)
168 {
169 va_list va;
170 va_start(va, pszFormat);
171 vbClLogV(pszFormat, va);
172 va_end(va);
173 }
174}
175
176/**
177 * @callback_method_impl{FNRTLOGPHASE, Release logger callback}
178 */
179static DECLCALLBACK(void) vbClLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
180{
181 /* Some introductory information. */
182 static RTTIMESPEC s_TimeSpec;
183 char szTmp[256];
184 if (enmPhase == RTLOGPHASE_BEGIN)
185 RTTimeNow(&s_TimeSpec);
186 RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));
187
188 switch (enmPhase)
189 {
190 case RTLOGPHASE_BEGIN:
191 {
192 pfnLog(pLoggerRelease,
193 "VBoxClient %s r%s (verbosity: %u) %s (%s %s) release log\n"
194 "Log opened %s\n",
195 RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity, VBOX_BUILD_TARGET,
196 __DATE__, __TIME__, szTmp);
197
198 int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
199 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
200 pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp);
201 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
202 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
203 pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp);
204 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
205 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
206 pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp);
207 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp));
208 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
209 pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp);
210
211 /* the package type is interesting for Linux distributions */
212 char szExecName[RTPATH_MAX];
213 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
214 pfnLog(pLoggerRelease,
215 "Executable: %s\n"
216 "Process ID: %u\n"
217 "Package type: %s"
218#ifdef VBOX_OSE
219 " (OSE)"
220#endif
221 "\n",
222 pszExecName ? pszExecName : "unknown",
223 RTProcSelf(),
224 VBOX_PACKAGE_STRING);
225 break;
226 }
227
228 case RTLOGPHASE_PREROTATE:
229 pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp);
230 break;
231
232 case RTLOGPHASE_POSTROTATE:
233 pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp);
234 break;
235
236 case RTLOGPHASE_END:
237 pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp);
238 break;
239
240 default:
241 /* nothing */
242 break;
243 }
244}
245
246/**
247 * Creates the default release logger outputting to the specified file.
248 *
249 * Pass NULL to disabled logging.
250 *
251 * @return IPRT status code.
252 * @param pszLogFile Filename for log output. NULL disables custom handling.
253 */
254int VBClLogCreate(const char *pszLogFile)
255{
256 if (!pszLogFile)
257 return VINF_SUCCESS;
258
259 /* Create release logger (stdout + file). */
260 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
261 RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME;
262#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
263 fFlags |= RTLOGFLAGS_USECRLF;
264#endif
265 int rc = RTLogCreateEx(&g_pLoggerRelease, "VBOXCLIENT_RELEASE_LOG", fFlags, "all",
266 RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/,
267 0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT | RTLOGDEST_USER,
268 vbClLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
269 NULL /*pErrInfo*/, "%s", pszLogFile ? pszLogFile : "");
270 if (RT_SUCCESS(rc))
271 {
272 /* register this logger as the release logger */
273 RTLogRelSetDefaultInstance(g_pLoggerRelease);
274
275 /* Explicitly flush the log in case of VBOXSERVICE_RELEASE_LOG=buffered. */
276 RTLogFlush(g_pLoggerRelease);
277 }
278
279 return rc;
280}
281
282/**
283 * Destroys the currently active logging instance.
284 */
285void VBClLogDestroy(void)
286{
287 RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
288}
289
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