VirtualBox

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

Last change on this file since 86871 was 86871, checked in by vboxsync, 4 years ago

Additions/VBoxClient: Big revamp of the internal service handling and termination fixes. A service now runs as part of a worker thread, while the main thread is used for initialization / shutdown and signal handling.

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