VirtualBox

source: vbox/trunk/include/iprt/log.h@ 103224

Last change on this file since 103224 was 100867, checked in by vboxsync, 14 months ago

IPRT/log.h: Added a bunch of Log*Ex() macros that allows logging to a non-default group w/o too much hazzle. Also added LOG_FN_NAME to go along with LOG_FN_FMT. bugref:10369

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 102.7 KB
Line 
1/** @file
2 * IPRT - Logging.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_log_h
37#define IPRT_INCLUDED_log_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/cdefs.h>
43#include <iprt/types.h>
44#include <iprt/stdarg.h>
45
46RT_C_DECLS_BEGIN
47
48/** @defgroup grp_rt_log RTLog - Logging
49 * @ingroup grp_rt
50 * @{
51 */
52
53/**
54 * IPRT Logging Groups.
55 * (Remember to update RT_LOGGROUP_NAMES!)
56 *
57 * @remark It should be pretty obvious, but just to have
58 * mentioned it, the values are sorted alphabetically (using the
59 * english alphabet) except for _DEFAULT which is always first.
60 *
61 * If anyone might be wondering what the alphabet looks like:
62 * a b c d e f g h i j k l m n o p q r s t u v w x y z
63 */
64typedef enum RTLOGGROUP
65{
66 /** Default logging group. */
67 RTLOGGROUP_DEFAULT,
68 RTLOGGROUP_CRYPTO,
69 RTLOGGROUP_DBG,
70 RTLOGGROUP_DBG_DWARF,
71 RTLOGGROUP_DIR,
72 RTLOGGROUP_FDT,
73 RTLOGGROUP_FILE,
74 RTLOGGROUP_FS,
75 RTLOGGROUP_FTP,
76 RTLOGGROUP_HTTP,
77 RTLOGGROUP_IOQUEUE,
78 RTLOGGROUP_LDR,
79 RTLOGGROUP_LOCALIPC,
80 RTLOGGROUP_PATH,
81 RTLOGGROUP_PROCESS,
82 RTLOGGROUP_REST,
83 RTLOGGROUP_SYMLINK,
84 RTLOGGROUP_THREAD,
85 RTLOGGROUP_TIME,
86 RTLOGGROUP_TIMER,
87 RTLOGGROUP_VFS,
88 RTLOGGROUP_ZIP = 31,
89 RTLOGGROUP_FIRST_USER = 32
90} RTLOGGROUP;
91
92/** @def RT_LOGGROUP_NAMES
93 * IPRT Logging group names.
94 *
95 * Must correspond 100% to RTLOGGROUP!
96 * Don't forget commas!
97 *
98 * @remark It should be pretty obvious, but just to have
99 * mentioned it, the values are sorted alphabetically (using the
100 * english alphabet) except for _DEFAULT which is always first.
101 *
102 * If anyone might be wondering what the alphabet looks like:
103 * a b c d e f g h i j k l m n o p q r s t u v w x y z
104 *
105 * The RT_XX log group names are placeholders for new modules being added,
106 * to make sure that there always is a total of 32 log group entries.
107 */
108#define RT_LOGGROUP_NAMES \
109 "DEFAULT", \
110 "RT_CRYPTO", \
111 "RT_DBG", \
112 "RT_DBG_DWARF", \
113 "RT_DIR", \
114 "RT_FDT", \
115 "RT_FILE", \
116 "RT_FS", \
117 "RT_FTP", \
118 "RT_HTTP", \
119 "RT_IOQUEUE", \
120 "RT_LDR", \
121 "RT_LOCALIPC", \
122 "RT_PATH", \
123 "RT_PROCESS", \
124 "RT_REST", \
125 "RT_SYMLINK", \
126 "RT_THREAD", \
127 "RT_TIME", \
128 "RT_TIMER", \
129 "RT_VFS", \
130 "RT_21", \
131 "RT_22", \
132 "RT_23", \
133 "RT_24", \
134 "RT_25", \
135 "RT_26", \
136 "RT_27", \
137 "RT_28", \
138 "RT_29", \
139 "RT_30", \
140 "RT_ZIP"
141
142
143/** @def LOG_GROUP
144 * Active logging group.
145 */
146#ifndef LOG_GROUP
147# define LOG_GROUP RTLOGGROUP_DEFAULT
148#endif
149
150/** @def LOG_FN_FMT
151 * You can use this to specify your desired way of printing __PRETTY_FUNCTION__
152 * if you dislike the default one.
153 * @todo __PRETTY_FUNCTION__ is not optimal here.
154 */
155#ifndef LOG_FN_FMT
156# define LOG_FN_FMT "%Rfn"
157#endif
158
159/** @def LOG_FN_NAME
160 * Alias for __PRETTY_FUNCTION__ or similar that goes the best with LOG_FN_FMT.
161 * @todo __PRETTY_FUNCTION__ is not optimal here.
162 */
163#ifndef LOG_FN_NAME
164# define LOG_FN_NAME RT_GCC_EXTENSION __PRETTY_FUNCTION__
165#endif
166
167#ifdef LOG_INSTANCE
168# error "LOG_INSTANCE is no longer supported."
169#endif
170#ifdef LOG_REL_INSTANCE
171# error "LOG_REL_INSTANCE is no longer supported."
172#endif
173
174/** Logger structure. */
175typedef struct RTLOGGER RTLOGGER;
176/** Pointer to logger structure. */
177typedef RTLOGGER *PRTLOGGER;
178/** Pointer to const logger structure. */
179typedef const RTLOGGER *PCRTLOGGER;
180
181
182/** Pointer to a log buffer descriptor. */
183typedef struct RTLOGBUFFERDESC *PRTLOGBUFFERDESC;
184
185
186/**
187 * Logger phase.
188 *
189 * Used for signalling the log header/footer callback what to do.
190 */
191typedef enum RTLOGPHASE
192{
193 /** Begin of the logging. */
194 RTLOGPHASE_BEGIN = 0,
195 /** End of the logging. */
196 RTLOGPHASE_END,
197 /** Before rotating the log file. */
198 RTLOGPHASE_PREROTATE,
199 /** After rotating the log file. */
200 RTLOGPHASE_POSTROTATE,
201 /** 32-bit type blow up hack. */
202 RTLOGPHASE_32BIT_HACK = 0x7fffffff
203} RTLOGPHASE;
204
205
206#if 0 /* retired */
207/**
208 * Logger function.
209 *
210 * @param pszFormat Format string.
211 * @param ... Optional arguments as specified in the format string.
212 */
213typedef DECLCALLBACKTYPE(void, FNRTLOGGER,(const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(1, 2);
214/** Pointer to logger function. */
215typedef FNRTLOGGER *PFNRTLOGGER;
216#endif
217
218/**
219 * Custom buffer flushing function.
220 *
221 * @retval true if flushed and the buffer can be reused.
222 * @retval false for switching to the next buffer because an async flush of
223 * @a pBufDesc is still pending. The implementation is responsible for
224 * only returning when the next buffer is ready for reuse, the generic
225 * logger code has no facility to make sure of this.
226 *
227 * @param pLogger Pointer to the logger instance which is to be flushed.
228 * @param pBufDesc The descriptor of the buffer to be flushed.
229 */
230typedef DECLCALLBACKTYPE(bool, FNRTLOGFLUSH,(PRTLOGGER pLogger, PRTLOGBUFFERDESC pBufDesc));
231/** Pointer to flush function. */
232typedef FNRTLOGFLUSH *PFNRTLOGFLUSH;
233
234/**
235 * Header/footer message callback.
236 *
237 * @param pLogger Pointer to the logger instance.
238 * @param pszFormat Format string.
239 * @param ... Optional arguments specified in the format string.
240 */
241typedef DECLCALLBACKTYPE(void, FNRTLOGPHASEMSG,(PRTLOGGER pLogger, const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(2, 3);
242/** Pointer to header/footer message callback function. */
243typedef FNRTLOGPHASEMSG *PFNRTLOGPHASEMSG;
244
245/**
246 * Log file header/footer callback.
247 *
248 * @param pLogger Pointer to the logger instance.
249 * @param enmLogPhase Indicates at what time the callback is invoked.
250 * @param pfnLogPhaseMsg Callback for writing the header/footer (RTLogPrintf
251 * and others are out of bounds).
252 */
253typedef DECLCALLBACKTYPE(void, FNRTLOGPHASE,(PRTLOGGER pLogger, RTLOGPHASE enmLogPhase, PFNRTLOGPHASEMSG pfnLogPhaseMsg));
254/** Pointer to log header/footer callback function. */
255typedef FNRTLOGPHASE *PFNRTLOGPHASE;
256
257/**
258 * Custom log prefix callback.
259 *
260 *
261 * @returns The number of chars written.
262 *
263 * @param pLogger Pointer to the logger instance.
264 * @param pchBuf Output buffer pointer.
265 * No need to terminate the output.
266 * @param cchBuf The size of the output buffer.
267 * @param pvUser The user argument.
268 */
269typedef DECLCALLBACKTYPE(size_t, FNRTLOGPREFIX,(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser));
270/** Pointer to prefix callback function. */
271typedef FNRTLOGPREFIX *PFNRTLOGPREFIX;
272
273
274/** Pointer to a constant log output interface. */
275typedef const struct RTLOGOUTPUTIF *PCRTLOGOUTPUTIF;
276
277/**
278 * Logging output interface.
279 */
280typedef struct RTLOGOUTPUTIF
281{
282 /**
283 * Opens a new log file with the given name.
284 *
285 * @returns IPRT status code.
286 * @param pIf Pointer to this interface.
287 * @param pvUser Opaque user data passed when setting the callbacks.
288 * @param pszFilename The filename to open.
289 * @param fFlags Open flags, combination of RTFILE_O_XXX.
290 */
291 DECLR3CALLBACKMEMBER(int, pfnOpen, (PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename, uint32_t fFlags));
292
293 /**
294 * Closes the currently open file.
295 *
296 * @returns IPRT status code.
297 * @param pIf Pointer to this interface.
298 * @param pvUser Opaque user data passed when setting the callbacks.
299 */
300 DECLR3CALLBACKMEMBER(int, pfnClose, (PCRTLOGOUTPUTIF pIf, void *pvUser));
301
302 /**
303 * Deletes the given file.
304 *
305 * @returns IPRT status code.
306 * @param pIf Pointer to this interface.
307 * @param pvUser Opaque user data passed when setting the callbacks.
308 * @param pszFilename The filename to delete.
309 */
310 DECLR3CALLBACKMEMBER(int, pfnDelete, (PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename));
311
312 /**
313 * Renames the given file.
314 *
315 * @returns IPRT status code.
316 * @param pIf Pointer to this interface.
317 * @param pvUser Opaque user data passed when setting the callbacks.
318 * @param pszFilenameOld The old filename to rename.
319 * @param pszFilenameNew The new filename.
320 * @param fFlags Flags for the operation, combination of RTFILEMOVE_FLAGS_XXX.
321 */
322 DECLR3CALLBACKMEMBER(int, pfnRename, (PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilenameOld,
323 const char *pszFilenameNew, uint32_t fFlags));
324
325 /**
326 * Queries the size of the log file.
327 *
328 * @returns IPRT status code.
329 * @param pIf Pointer to this interface.
330 * @param pvUser Opaque user data passed when setting the callbacks.
331 * @param pcbFile Where to store the file size in bytes on success.
332 */
333 DECLR3CALLBACKMEMBER(int, pfnQuerySize, (PCRTLOGOUTPUTIF pIf, void *pvUser, uint64_t *pcbSize));
334
335 /**
336 * Writes data to the log file.
337 *
338 * @returns IPRT status code.
339 * @param pIf Pointer to this interface.
340 * @param pvUser Opaque user data passed when setting the callbacks.
341 * @param pvBuf The data to write.
342 * @param cbWrite Number of bytes to write.
343 * @param pcbWritten Where to store the actual number of bytes written on success.
344 */
345 DECLR3CALLBACKMEMBER(int, pfnWrite, (PCRTLOGOUTPUTIF pIf, void *pvUser, const void *pvBuf,
346 size_t cbWrite, size_t *pcbWritten));
347
348 /**
349 * Flushes data to the underlying storage medium.
350 *
351 * @returns IPRT status code.
352 * @param pIf Pointer to this interface.
353 * @param pvUser Opaque user data passed when setting the callbacks.
354 */
355 DECLR3CALLBACKMEMBER(int, pfnFlush, (PCRTLOGOUTPUTIF pIf, void *pvUser));
356} RTLOGOUTPUTIF;
357/** Pointer to a logging output interface. */
358typedef struct RTLOGOUTPUTIF *PRTLOGOUTPUTIF;
359
360
361/**
362 * Auxiliary buffer descriptor.
363 *
364 * This is what we share we ring-3 and use for flushing ring-0 EMT loggers when
365 * we return to ring-3.
366 */
367typedef struct RTLOGBUFFERAUXDESC
368{
369 /** Flush indicator.
370 * Ring-3 sets this if it flushed the buffer, ring-0 clears it again after
371 * writing. */
372 bool volatile fFlushedIndicator;
373 bool afPadding[3];
374 /** Copy of RTLOGBUFFERDESC::offBuf. */
375 uint32_t offBuf;
376} RTLOGBUFFERAUXDESC;
377/** Pointer to auxiliary buffer descriptor. */
378typedef RTLOGBUFFERAUXDESC *PRTLOGBUFFERAUXDESC;
379
380/**
381 * Log buffer desciptor.
382 */
383typedef struct RTLOGBUFFERDESC
384{
385 /** Magic value / eye catcher (RTLOGBUFFERDESC_MAGIC). */
386 uint32_t u32Magic;
387 /** Padding. */
388 uint32_t uReserved;
389 /** The buffer size. */
390 uint32_t cbBuf;
391 /** The current buffer offset. */
392 uint32_t offBuf;
393 /** Pointer to the buffer. */
394 char *pchBuf;
395 /** Pointer to auxiliary desciptor, NULL if not used. */
396 PRTLOGBUFFERAUXDESC pAux;
397} RTLOGBUFFERDESC;
398
399/** RTLOGBUFFERDESC::u32Magic value. (Avram Noam Chomsky) */
400#define RTLOGBUFFERDESC_MAGIC UINT32_C(0x19281207)
401
402/**
403 * The public logger instance part.
404 *
405 * The logger instance is mostly abstract and kept as RTLOGGERINTERNAL within
406 * log.cpp. This public part is at the start of RTLOGGERINTERNAL.
407 */
408struct RTLOGGER
409{
410 /** Magic number (RTLOGGER_MAGIC). */
411 uint32_t u32Magic;
412 /** User value \#1, initialized to zero. */
413 uint32_t u32UserValue1;
414 /** User value \#2, initialized to zero. */
415 uint64_t u64UserValue2;
416 /** User value \#3, initialized to zero. */
417 uint64_t u64UserValue3;
418#if 0
419 /** Pointer to the logger function (used in non-C99 mode only).
420 *
421 * This is actually pointer to a wrapper/stub function which will push a pointer
422 * to the instance pointer onto the stack before jumping to the real logger
423 * function. A very unfortunate hack to work around the missing variadic macro
424 * support in older C++/C standards. (The memory is allocated using
425 * RTMemExecAlloc(), except for agnostic R0 code.) */
426 PFNRTLOGGER pfnLogger;
427#else
428 /** Unused. */
429 uintptr_t uUsedToBeNonC99Logger;
430#endif
431#if ARCH_BITS == 32
432 /** Explicit padding. */
433 uint32_t uReserved1;
434#endif
435};
436
437/** RTLOGGER::u32Magic value. (John Rogers Searle) */
438#define RTLOGGER_MAGIC UINT32_C(0x19320731)
439
440/**
441 * Logger flags.
442 */
443typedef enum RTLOGFLAGS
444{
445 /** The logger instance is disabled for normal output. */
446 RTLOGFLAGS_DISABLED = 0x00000001,
447 /** The logger instance is using buffered output. */
448 RTLOGFLAGS_BUFFERED = 0x00000002,
449 /** The logger instance expands LF to CR/LF. */
450 RTLOGFLAGS_USECRLF = 0x00000010,
451 /** Append to the log destination where applicable. */
452 RTLOGFLAGS_APPEND = 0x00000020,
453 /** Show relative timestamps with PREFIX_TSC and PREFIX_TS */
454 RTLOGFLAGS_REL_TS = 0x00000040,
455 /** Show decimal timestamps with PREFIX_TSC and PREFIX_TS */
456 RTLOGFLAGS_DECIMAL_TS = 0x00000080,
457 /** Open the file in write through mode. */
458 RTLOGFLAGS_WRITE_THROUGH = 0x00000100,
459 /** Flush the file to disk when flushing the buffer. */
460 RTLOGFLAGS_FLUSH = 0x00000200,
461 /** Restrict the number of log entries per group. */
462 RTLOGFLAGS_RESTRICT_GROUPS = 0x00000400,
463 /** New lines should be prefixed with the write and read lock counts. */
464 RTLOGFLAGS_PREFIX_LOCK_COUNTS = 0x00008000,
465 /** New lines should be prefixed with the CPU id (ApicID on intel/amd). */
466 RTLOGFLAGS_PREFIX_CPUID = 0x00010000,
467 /** New lines should be prefixed with the native process id. */
468 RTLOGFLAGS_PREFIX_PID = 0x00020000,
469 /** New lines should be prefixed with group flag number causing the output. */
470 RTLOGFLAGS_PREFIX_FLAG_NO = 0x00040000,
471 /** New lines should be prefixed with group flag name causing the output. */
472 RTLOGFLAGS_PREFIX_FLAG = 0x00080000,
473 /** New lines should be prefixed with group number. */
474 RTLOGFLAGS_PREFIX_GROUP_NO = 0x00100000,
475 /** New lines should be prefixed with group name. */
476 RTLOGFLAGS_PREFIX_GROUP = 0x00200000,
477 /** New lines should be prefixed with the native thread id. */
478 RTLOGFLAGS_PREFIX_TID = 0x00400000,
479 /** New lines should be prefixed with thread name. */
480 RTLOGFLAGS_PREFIX_THREAD = 0x00800000,
481 /** New lines should be prefixed with data from a custom callback. */
482 RTLOGFLAGS_PREFIX_CUSTOM = 0x01000000,
483 /** New lines should be prefixed with formatted timestamp since program start. */
484 RTLOGFLAGS_PREFIX_TIME_PROG = 0x04000000,
485 /** New lines should be prefixed with formatted timestamp (UCT). */
486 RTLOGFLAGS_PREFIX_TIME = 0x08000000,
487 /** New lines should be prefixed with milliseconds since program start. */
488 RTLOGFLAGS_PREFIX_MS_PROG = 0x10000000,
489 /** New lines should be prefixed with timestamp. */
490 RTLOGFLAGS_PREFIX_TSC = 0x20000000,
491 /** New lines should be prefixed with timestamp. */
492 RTLOGFLAGS_PREFIX_TS = 0x40000000,
493 /** The prefix mask. */
494 RTLOGFLAGS_PREFIX_MASK = 0x7dff8000
495} RTLOGFLAGS;
496/** Don't use locking. */
497#define RTLOG_F_NO_LOCKING RT_BIT_64(63)
498/** Mask with all valid log flags (for validation). */
499#define RTLOG_F_VALID_MASK UINT64_C(0x800000007fff87f3)
500
501/**
502 * Logger per group flags.
503 *
504 * @remarks We only use the lower 16 bits here. We'll be combining it with the
505 * group number in a few places (e.g. RTLogDefaultInstanceEx,
506 * RTLogGetDefaultInstanceEx, RTLogRelGetDefaultInstanceEx, ++) where
507 * the high 16-bit word is used for the group number.
508 */
509typedef enum RTLOGGRPFLAGS
510{
511 /** Enabled. */
512 RTLOGGRPFLAGS_ENABLED = 0x0001,
513 /** Flow logging. */
514 RTLOGGRPFLAGS_FLOW = 0x0002,
515 /** Warnings logging. */
516 RTLOGGRPFLAGS_WARN = 0x0004,
517 /* 0x0008 for later. */
518 /** Level 1 logging. */
519 RTLOGGRPFLAGS_LEVEL_1 = 0x0010,
520 /** Level 2 logging. */
521 RTLOGGRPFLAGS_LEVEL_2 = 0x0020,
522 /** Level 3 logging. */
523 RTLOGGRPFLAGS_LEVEL_3 = 0x0040,
524 /** Level 4 logging. */
525 RTLOGGRPFLAGS_LEVEL_4 = 0x0080,
526 /** Level 5 logging. */
527 RTLOGGRPFLAGS_LEVEL_5 = 0x0100,
528 /** Level 6 logging. */
529 RTLOGGRPFLAGS_LEVEL_6 = 0x0200,
530 /** Level 7 logging. */
531 RTLOGGRPFLAGS_LEVEL_7 = 0x0400,
532 /** Level 8 logging. */
533 RTLOGGRPFLAGS_LEVEL_8 = 0x0800,
534 /** Level 9 logging. */
535 RTLOGGRPFLAGS_LEVEL_9 = 0x1000,
536 /** Level 10 logging. */
537 RTLOGGRPFLAGS_LEVEL_10 = 0x2000,
538 /** Level 11 logging. */
539 RTLOGGRPFLAGS_LEVEL_11 = 0x4000,
540 /** Level 12 logging. */
541 RTLOGGRPFLAGS_LEVEL_12 = 0x8000,
542
543 /** Restrict the number of log entries. */
544 RTLOGGRPFLAGS_RESTRICT = 0x40000000,
545 /** Blow up the type. */
546 RTLOGGRPFLAGS_32BIT_HACK = 0x7fffffff
547} RTLOGGRPFLAGS;
548
549/**
550 * Logger destination types and flags.
551 */
552typedef enum RTLOGDEST
553{
554 /** Log to file. */
555 RTLOGDEST_FILE = 0x00000001,
556 /** Log to stdout. */
557 RTLOGDEST_STDOUT = 0x00000002,
558 /** Log to stderr. */
559 RTLOGDEST_STDERR = 0x00000004,
560 /** Log to debugger (win32 only). */
561 RTLOGDEST_DEBUGGER = 0x00000008,
562 /** Log to com port. */
563 RTLOGDEST_COM = 0x00000010,
564 /** Log a memory ring buffer. */
565 RTLOGDEST_RINGBUF = 0x00000020,
566 /** The parent VMM debug log. */
567 RTLOGDEST_VMM = 0x00000040,
568 /** The parent VMM release log. */
569 RTLOGDEST_VMM_REL = 0x00000080,
570 /** Open files with no deny (share read, write, delete) on Windows. */
571 RTLOGDEST_F_NO_DENY = 0x00010000,
572 /** Delay opening the log file, logging to the buffer untill
573 * RTLogClearFileDelayFlag is called. */
574 RTLOGDEST_F_DELAY_FILE = 0x00020000,
575 /** Don't allow changes to the filename or mode of opening it. */
576 RTLOGDEST_FIXED_FILE = 0x01000000,
577 /** Don't allow changing the directory. */
578 RTLOGDEST_FIXED_DIR = 0x02000000,
579 /** Just a dummy flag to be used when no other flag applies. */
580 RTLOGDEST_DUMMY = 0x20000000,
581 /** Log to a user defined output stream. */
582 RTLOGDEST_USER = 0x40000000
583} RTLOGDEST;
584/** Valid log destinations. */
585#define RTLOG_DST_VALID_MASK UINT32_C(0x630300ff)
586/** Log destinations that can be changed via RTLogChangeDestinations. */
587#define RTLOG_DST_CHANGE_MASK UINT32_C(0x400000de)
588
589
590#ifdef DOXYGEN_RUNNING
591# define LOG_DISABLED
592# define LOG_ENABLED
593# define LOG_ENABLE_FLOW
594#endif
595
596/** @def LOG_DISABLED
597 * Use this compile time define to disable all logging macros. It can
598 * be overridden for each of the logging macros by the LOG_ENABLE*
599 * compile time defines.
600 */
601
602/** @def LOG_ENABLED
603 * Use this compile time define to enable logging when not in debug mode
604 * or LOG_DISABLED is set.
605 * This will enable Log() only.
606 */
607
608/** @def LOG_ENABLE_FLOW
609 * Use this compile time define to enable flow logging when not in
610 * debug mode or LOG_DISABLED is defined.
611 * This will enable LogFlow() only.
612 */
613
614/*
615 * Determine whether logging is enabled and forcefully normalize the indicators.
616 */
617#if (defined(DEBUG) || defined(LOG_ENABLED)) && !defined(LOG_DISABLED)
618# undef LOG_DISABLED
619# undef LOG_ENABLED
620# define LOG_ENABLED
621#else
622# undef LOG_ENABLED
623# undef LOG_DISABLED
624# define LOG_DISABLED
625#endif
626
627
628/** @def LOG_USE_C99
629 * Governs the use of variadic macros.
630 */
631#ifndef LOG_USE_C99
632# define LOG_USE_C99
633#endif
634
635
636/** @name Macros for checking whether a log level is enabled.
637 * @{ */
638/** @def LogIsItEnabled
639 * Checks whether the specified logging group is enabled or not.
640 */
641#ifdef LOG_ENABLED
642# define LogIsItEnabled(a_fFlags, a_iGroup) ( RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)) != NULL )
643#else
644# define LogIsItEnabled(a_fFlags, a_iGroup) (false)
645#endif
646
647/** @def LogIsEnabledOnly
648 * Checks whether the group is enabled w/o reference to any specific level.
649 */
650#define LogIsEnabledOnly() LogIsItEnabled(RTLOGGRPFLAGS_ENABLED, LOG_GROUP)
651
652/** @def LogIsEnabled
653 * Checks whether level 1 logging is enabled.
654 */
655#define LogIsEnabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
656
657/** @def LogIs2Enabled
658 * Checks whether level 2 logging is enabled.
659 */
660#define LogIs2Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
661
662/** @def LogIs3Enabled
663 * Checks whether level 3 logging is enabled.
664 */
665#define LogIs3Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
666
667/** @def LogIs4Enabled
668 * Checks whether level 4 logging is enabled.
669 */
670#define LogIs4Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
671
672/** @def LogIs5Enabled
673 * Checks whether level 5 logging is enabled.
674 */
675#define LogIs5Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
676
677/** @def LogIs6Enabled
678 * Checks whether level 6 logging is enabled.
679 */
680#define LogIs6Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
681
682/** @def LogIs7Enabled
683 * Checks whether level 7 logging is enabled.
684 */
685#define LogIs7Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP)
686
687/** @def LogIs8Enabled
688 * Checks whether level 8 logging is enabled.
689 */
690#define LogIs8Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP)
691
692/** @def LogIs9Enabled
693 * Checks whether level 9 logging is enabled.
694 */
695#define LogIs9Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP)
696
697/** @def LogIs10Enabled
698 * Checks whether level 10 logging is enabled.
699 */
700#define LogIs10Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP)
701
702/** @def LogIs11Enabled
703 * Checks whether level 11 logging is enabled.
704 */
705#define LogIs11Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP)
706
707/** @def LogIs12Enabled
708 * Checks whether level 12 logging is enabled.
709 */
710#define LogIs12Enabled() LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP)
711
712/** @def LogIsFlowEnabled
713 * Checks whether execution flow logging is enabled.
714 */
715#define LogIsFlowEnabled() LogIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
716
717/** @def LogIsWarnEnabled
718 * Checks whether execution flow logging is enabled.
719 */
720#define LogIsWarnEnabled() LogIsItEnabled(RTLOGGRPFLAGS_WARN, LOG_GROUP)
721/** @} */
722
723
724/** @def LogIt
725 * Write to specific logger if group enabled.
726 */
727#ifdef LOG_ENABLED
728# if defined(LOG_USE_C99)
729# define _LogRemoveParentheseis(...) __VA_ARGS__
730# define _LogIt(a_fFlags, a_iGroup, ...) \
731 do \
732 { \
733 PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
734 if (RT_LIKELY(!LogIt_pLogger)) \
735 { /* likely */ } \
736 else \
737 RTLogLoggerEx(LogIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
738 } while (0)
739# define LogIt(a_fFlags, a_iGroup, fmtargs) _LogIt(a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
740# define _LogItAlways(a_fFlags, a_iGroup, ...) RTLogLoggerEx(NULL, a_fFlags, UINT32_MAX, __VA_ARGS__)
741# define LogItAlways(a_fFlags, a_iGroup, fmtargs) _LogItAlways(a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
742 /** @todo invent a flag or something for skipping the group check so we can pass iGroup. LogItAlways. */
743# else
744# define LogIt(a_fFlags, a_iGroup, fmtargs) \
745 do \
746 { \
747 PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(a_fFlags, a_iGroup)); \
748 if (RT_LIKELY(!LogIt_pLogger)) \
749 { /* likely */ } \
750 else \
751 { \
752 LogIt_pLogger->pfnLogger fmtargs; \
753 } \
754 } while (0)
755# define LogItAlways(a_fFlags, a_iGroup, fmtargs) \
756 do \
757 { \
758 PRTLOGGER LogIt_pLogger = RTLogDefaultInstanceEx(RT_MAKE_U32(0, UINT16_MAX)); \
759 if (LogIt_pLogger) \
760 LogIt_pLogger->pfnLogger fmtargs; \
761 } while (0)
762# endif
763#else
764# define LogIt(a_fFlags, a_iGroup, fmtargs) do { } while (0)
765# define LogItAlways(a_fFlags, a_iGroup, fmtargs) do { } while (0)
766# if defined(LOG_USE_C99)
767# define _LogRemoveParentheseis(...) __VA_ARGS__
768# define _LogIt(a_fFlags, a_iGroup, ...) do { } while (0)
769# define _LogItAlways(a_fFlags, a_iGroup, ...) do { } while (0)
770# endif
771#endif
772
773
774/** @name Basic logging macros
775 * @{ */
776/** @def Log
777 * Level 1 logging that works regardless of the group settings.
778 */
779#define LogAlways(a) LogItAlways(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
780
781/** @def Log
782 * Level 1 logging.
783 */
784#define Log(a) LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
785
786/** @def Log2
787 * Level 2 logging.
788 */
789#define Log2(a) LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
790
791/** @def Log3
792 * Level 3 logging.
793 */
794#define Log3(a) LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
795
796/** @def Log4
797 * Level 4 logging.
798 */
799#define Log4(a) LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
800
801/** @def Log5
802 * Level 5 logging.
803 */
804#define Log5(a) LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
805
806/** @def Log6
807 * Level 6 logging.
808 */
809#define Log6(a) LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
810
811/** @def Log7
812 * Level 7 logging.
813 */
814#define Log7(a) LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, a)
815
816/** @def Log8
817 * Level 8 logging.
818 */
819#define Log8(a) LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, a)
820
821/** @def Log9
822 * Level 9 logging.
823 */
824#define Log9(a) LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, a)
825
826/** @def Log10
827 * Level 10 logging.
828 */
829#define Log10(a) LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
830
831/** @def Log11
832 * Level 11 logging.
833 */
834#define Log11(a) LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
835
836/** @def Log12
837 * Level 12 logging.
838 */
839#define Log12(a) LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
840
841/** @def LogFlow
842 * Logging of execution flow.
843 */
844#define LogFlow(a) LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
845
846/** @def LogWarn
847 * Logging of warnings.
848 */
849#define LogWarn(a) LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, a)
850/** @} */
851
852
853/** @name Logging macros prefixing the current function name.
854 * @{ */
855/** @def LogFunc
856 * Level 1 logging inside C/C++ functions.
857 *
858 * Prepends the given log message with the function name followed by a
859 * semicolon and space.
860 *
861 * @param a Log message in format <tt>("string\n" [, args])</tt>.
862 */
863#ifdef LOG_USE_C99
864# define LogFunc(a) _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
865#else
866# define LogFunc(a) do { Log((LOG_FN_FMT ": ", LOG_FN_NAME)); Log(a); } while (0)
867#endif
868
869/** @def Log2Func
870 * Level 2 logging inside C/C++ functions.
871 *
872 * Prepends the given log message with the function name followed by a
873 * semicolon and space.
874 *
875 * @param a Log message in format <tt>("string\n" [, args])</tt>.
876 */
877#ifdef LOG_USE_C99
878# define Log2Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
879#else
880# define Log2Func(a) do { Log2((LOG_FN_FMT ": ", LOG_FN_NAME)); Log2(a); } while (0)
881#endif
882
883/** @def Log3Func
884 * Level 3 logging inside C/C++ functions.
885 *
886 * Prepends the given log message with the function name followed by a
887 * semicolon and space.
888 *
889 * @param a Log message in format <tt>("string\n" [, args])</tt>.
890 */
891#ifdef LOG_USE_C99
892# define Log3Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
893#else
894# define Log3Func(a) do { Log3((LOG_FN_FMT ": ", LOG_FN_NAME)); Log3(a); } while (0)
895#endif
896
897/** @def Log4Func
898 * Level 4 logging inside C/C++ functions.
899 *
900 * Prepends the given log message with the function name followed by a
901 * semicolon and space.
902 *
903 * @param a Log message in format <tt>("string\n" [, args])</tt>.
904 */
905#ifdef LOG_USE_C99
906# define Log4Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
907#else
908# define Log4Func(a) do { Log4((LOG_FN_FMT ": ", LOG_FN_NAME)); Log4(a); } while (0)
909#endif
910
911/** @def Log5Func
912 * Level 5 logging inside C/C++ functions.
913 *
914 * Prepends the given log message with the function name followed by a
915 * semicolon and space.
916 *
917 * @param a Log message in format <tt>("string\n" [, args])</tt>.
918 */
919#ifdef LOG_USE_C99
920# define Log5Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
921#else
922# define Log5Func(a) do { Log5((LOG_FN_FMT ": ", LOG_FN_NAME)); Log5(a); } while (0)
923#endif
924
925/** @def Log6Func
926 * Level 6 logging inside C/C++ functions.
927 *
928 * Prepends the given log message with the function name followed by a
929 * semicolon and space.
930 *
931 * @param a Log message in format <tt>("string\n" [, args])</tt>.
932 */
933#ifdef LOG_USE_C99
934# define Log6Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
935#else
936# define Log6Func(a) do { Log6((LOG_FN_FMT ": ", LOG_FN_NAME)); Log6(a); } while (0)
937#endif
938
939/** @def Log7Func
940 * Level 7 logging inside C/C++ functions.
941 *
942 * Prepends the given log message with the function name followed by a
943 * semicolon and space.
944 *
945 * @param a Log message in format <tt>("string\n" [, args])</tt>.
946 */
947#ifdef LOG_USE_C99
948# define Log7Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
949#else
950# define Log7Func(a) do { Log7((LOG_FN_FMT ": ", LOG_FN_NAME)); Log7(a); } while (0)
951#endif
952
953/** @def Log8Func
954 * Level 8 logging inside C/C++ functions.
955 *
956 * Prepends the given log message with the function name followed by a
957 * semicolon and space.
958 *
959 * @param a Log message in format <tt>("string\n" [, args])</tt>.
960 */
961#ifdef LOG_USE_C99
962# define Log8Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
963#else
964# define Log8Func(a) do { Log8((LOG_FN_FMT ": ", LOG_FN_NAME)); Log8(a); } while (0)
965#endif
966
967/** @def Log9Func
968 * Level 9 logging inside C/C++ functions.
969 *
970 * Prepends the given log message with the function name followed by a
971 * semicolon and space.
972 *
973 * @param a Log message in format <tt>("string\n" [, args])</tt>.
974 */
975#ifdef LOG_USE_C99
976# define Log9Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
977#else
978# define Log9Func(a) do { Log9((LOG_FN_FMT ": ", LOG_FN_NAME)); Log9(a); } while (0)
979#endif
980
981/** @def Log10Func
982 * Level 10 logging inside C/C++ functions.
983 *
984 * Prepends the given log message with the function name followed by a
985 * semicolon and space.
986 *
987 * @param a Log message in format <tt>("string\n" [, args])</tt>.
988 */
989#ifdef LOG_USE_C99
990# define Log10Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
991#else
992# define Log10Func(a) do { Log10((LOG_FN_FMT ": ", LOG_FN_NAME)); Log10(a); } while (0)
993#endif
994
995/** @def Log11Func
996 * Level 11 logging inside C/C++ functions.
997 *
998 * Prepends the given log message with the function name followed by a
999 * semicolon and space.
1000 *
1001 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1002 */
1003#ifdef LOG_USE_C99
1004# define Log11Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1005#else
1006# define Log11Func(a) do { Log11((LOG_FN_FMT ": ", LOG_FN_NAME)); Log11(a); } while (0)
1007#endif
1008
1009/** @def Log12Func
1010 * Level 12 logging inside C/C++ functions.
1011 *
1012 * Prepends the given log message with the function name followed by a
1013 * semicolon and space.
1014 *
1015 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1016 */
1017#ifdef LOG_USE_C99
1018# define Log12Func(a) _LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1019#else
1020# define Log12Func(a) do { Log12((LOG_FN_FMT ": ", LOG_FN_NAME)); Log12(a); } while (0)
1021#endif
1022
1023/** @def LogFlowFunc
1024 * Macro to log the execution flow inside C/C++ functions.
1025 *
1026 * Prepends the given log message with the function name followed by
1027 * a semicolon and space.
1028 *
1029 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1030 */
1031#ifdef LOG_USE_C99
1032# define LogFlowFunc(a) \
1033 _LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1034#else
1035# define LogFlowFunc(a) \
1036 do { LogFlow((LOG_FN_FMT ": ", LOG_FN_NAME)); LogFlow(a); } while (0)
1037#endif
1038
1039/** @def LogWarnFunc
1040 * Macro to log a warning inside C/C++ functions.
1041 *
1042 * Prepends the given log message with the function name followed by
1043 * a semicolon and space.
1044 *
1045 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1046 */
1047#ifdef LOG_USE_C99
1048# define LogWarnFunc(a) \
1049 _LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1050#else
1051# define LogWarnFunc(a) \
1052 do { LogFlow((LOG_FN_FMT ": ", LOG_FN_NAME)); LogFlow(a); } while (0)
1053#endif
1054/** @} */
1055
1056
1057/** @name Logging macros prefixing the this pointer value and method name.
1058 * @{ */
1059
1060/** @def LogThisFunc
1061 * Level 1 logging inside a C++ non-static method, with object pointer and
1062 * method name prefixed to the given message.
1063 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1064 */
1065#ifdef LOG_USE_C99
1066# define LogThisFunc(a) \
1067 _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1068#else
1069# define LogThisFunc(a) do { Log(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log(a); } while (0)
1070#endif
1071
1072/** @def Log2ThisFunc
1073 * Level 2 logging inside a C++ non-static method, with object pointer and
1074 * method name prefixed to the given message.
1075 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1076 */
1077#ifdef LOG_USE_C99
1078# define Log2ThisFunc(a) \
1079 _LogIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1080#else
1081# define Log2ThisFunc(a) do { Log2(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log2(a); } while (0)
1082#endif
1083
1084/** @def Log3ThisFunc
1085 * Level 3 logging inside a C++ non-static method, with object pointer and
1086 * method name prefixed to the given message.
1087 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1088 */
1089#ifdef LOG_USE_C99
1090# define Log3ThisFunc(a) \
1091 _LogIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1092#else
1093# define Log3ThisFunc(a) do { Log3(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log3(a); } while (0)
1094#endif
1095
1096/** @def Log4ThisFunc
1097 * Level 4 logging inside a C++ non-static method, with object pointer and
1098 * method name prefixed to the given message.
1099 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1100 */
1101#ifdef LOG_USE_C99
1102# define Log4ThisFunc(a) \
1103 _LogIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1104#else
1105# define Log4ThisFunc(a) do { Log4(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log4(a); } while (0)
1106#endif
1107
1108/** @def Log5ThisFunc
1109 * Level 5 logging inside a C++ non-static method, with object pointer and
1110 * method name prefixed to the given message.
1111 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1112 */
1113#ifdef LOG_USE_C99
1114# define Log5ThisFunc(a) \
1115 _LogIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1116#else
1117# define Log5ThisFunc(a) do { Log5(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log5(a); } while (0)
1118#endif
1119
1120/** @def Log6ThisFunc
1121 * Level 6 logging inside a C++ non-static method, with object pointer and
1122 * method name prefixed to the given message.
1123 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1124 */
1125#ifdef LOG_USE_C99
1126# define Log6ThisFunc(a) \
1127 _LogIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1128#else
1129# define Log6ThisFunc(a) do { Log6(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log6(a); } while (0)
1130#endif
1131
1132/** @def Log7ThisFunc
1133 * Level 7 logging inside a C++ non-static method, with object pointer and
1134 * method name prefixed to the given message.
1135 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1136 */
1137#ifdef LOG_USE_C99
1138# define Log7ThisFunc(a) \
1139 _LogIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1140#else
1141# define Log7ThisFunc(a) do { Log7(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log7(a); } while (0)
1142#endif
1143
1144/** @def Log8ThisFunc
1145 * Level 8 logging inside a C++ non-static method, with object pointer and
1146 * method name prefixed to the given message.
1147 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1148 */
1149#ifdef LOG_USE_C99
1150# define Log8ThisFunc(a) \
1151 _LogIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1152#else
1153# define Log8ThisFunc(a) do { Log8(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log8(a); } while (0)
1154#endif
1155
1156/** @def Log9ThisFunc
1157 * Level 9 logging inside a C++ non-static method, with object pointer and
1158 * method name prefixed to the given message.
1159 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1160 */
1161#ifdef LOG_USE_C99
1162# define Log9ThisFunc(a) \
1163 _LogIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1164#else
1165# define Log9ThisFunc(a) do { Log9(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log9(a); } while (0)
1166#endif
1167
1168/** @def Log10ThisFunc
1169 * Level 10 logging inside a C++ non-static method, with object pointer and
1170 * method name prefixed to the given message.
1171 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1172 */
1173#ifdef LOG_USE_C99
1174# define Log10ThisFunc(a) \
1175 _LogIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1176#else
1177# define Log10ThisFunc(a) do { Log10(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log10(a); } while (0)
1178#endif
1179
1180/** @def Log11ThisFunc
1181 * Level 11 logging inside a C++ non-static method, with object pointer and
1182 * method name prefixed to the given message.
1183 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1184 */
1185#ifdef LOG_USE_C99
1186# define Log11ThisFunc(a) \
1187 _LogIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1188#else
1189# define Log11ThisFunc(a) do { Log11(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log11(a); } while (0)
1190#endif
1191
1192/** @def Log12ThisFunc
1193 * Level 12 logging inside a C++ non-static method, with object pointer and
1194 * method name prefixed to the given message.
1195 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1196 */
1197#ifdef LOG_USE_C99
1198# define Log12ThisFunc(a) \
1199 _LogIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1200#else
1201# define Log12ThisFunc(a) do { Log12(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); Log12(a); } while (0)
1202#endif
1203
1204/** @def LogFlowThisFunc
1205 * Flow level logging inside a C++ non-static method, with object pointer and
1206 * method name prefixed to the given message.
1207 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1208 */
1209#ifdef LOG_USE_C99
1210# define LogFlowThisFunc(a) \
1211 _LogIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1212#else
1213# define LogFlowThisFunc(a) do { LogFlow(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogFlow(a); } while (0)
1214#endif
1215
1216/** @def LogWarnThisFunc
1217 * Warning level logging inside a C++ non-static method, with object pointer and
1218 * method name prefixed to the given message.
1219 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1220 */
1221#ifdef LOG_USE_C99
1222# define LogWarnThisFunc(a) \
1223 _LogIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1224#else
1225# define LogWarnThisFunc(a) do { LogWarn(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogWarn(a); } while (0)
1226#endif
1227/** @} */
1228
1229
1230/** @name Misc Logging Macros
1231 * @{ */
1232
1233/** @def Log1Warning
1234 * The same as Log(), but prepents a <tt>"WARNING! "</tt> string to the message.
1235 *
1236 * @param a Custom log message in format <tt>("string\n" [, args])</tt>.
1237 */
1238#if defined(LOG_USE_C99)
1239# define Log1Warning(a) _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "WARNING! %M", _LogRemoveParentheseis a )
1240#else
1241# define Log1Warning(a) do { Log(("WARNING! ")); Log(a); } while (0)
1242#endif
1243
1244/** @def Log1WarningFunc
1245 * The same as LogWarning(), but prepents the log message with the function name.
1246 *
1247 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1248 */
1249#ifdef LOG_USE_C99
1250# define Log1WarningFunc(a) \
1251 _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": WARNING! %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1252#else
1253# define Log1WarningFunc(a) \
1254 do { Log((LOG_FN_FMT ": WARNING! ", LOG_FN_NAME)); Log(a); } while (0)
1255#endif
1256
1257/** @def Log1WarningThisFunc
1258 * The same as LogWarningFunc() but for class functions (methods): the resulting
1259 * log line is additionally prepended with a hex value of |this| pointer.
1260 *
1261 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1262 */
1263#ifdef LOG_USE_C99
1264# define Log1WarningThisFunc(a) \
1265 _LogIt(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": WARNING! %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1266#else
1267# define Log1WarningThisFunc(a) \
1268 do { Log(("{%p} " LOG_FN_FMT ": WARNING! ", this, LOG_FN_NAME)); Log(a); } while (0)
1269#endif
1270
1271
1272/** Shortcut to |LogFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
1273#define LogFlowFuncEnter() LogFlowFunc(("ENTER\n"))
1274
1275/** Shortcut to |LogFlowFunc ("LEAVE\n")|, marks the end of the function. */
1276#define LogFlowFuncLeave() LogFlowFunc(("LEAVE\n"))
1277
1278/** Shortcut to |LogFlowFunc ("LEAVE: %Rrc\n")|, marks the end of the function. */
1279#define LogFlowFuncLeaveRC(rc) LogFlowFunc(("LEAVE: %Rrc\n", (rc)))
1280
1281/** Shortcut to |LogFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
1282#define LogFlowThisFuncEnter() LogFlowThisFunc(("ENTER\n"))
1283
1284/** Shortcut to |LogFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
1285#define LogFlowThisFuncLeave() LogFlowThisFunc(("LEAVE\n"))
1286
1287
1288/** @def LogObjRefCnt
1289 * Helper macro to print the current reference count of the given COM object
1290 * to the log file.
1291 *
1292 * @param pObj Pointer to the object in question (must be a pointer to an
1293 * IUnknown subclass or simply define COM-style AddRef() and
1294 * Release() methods)
1295 */
1296#define LogObjRefCnt(pObj) \
1297 do { \
1298 if (LogIsFlowEnabled()) \
1299 { \
1300 int cRefsForLog = (pObj)->AddRef(); \
1301 LogFlow((#pObj "{%p}.refCnt=%d\n", (pObj), cRefsForLog - 1)); \
1302 (pObj)->Release(); \
1303 } \
1304 } while (0)
1305/** @} */
1306
1307
1308/** @name Logging to specific group.
1309 * @{ */
1310/** @def LogEx
1311 * Level 1 logging to specific group.
1312 */
1313#define LogEx(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_1, a_Grp, a)
1314
1315/** @def Log2Ex
1316 * Level 2 logging to specific group.
1317 */
1318#define Log2Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_2, a_Grp, a)
1319
1320/** @def Log3Ex
1321 * Level 3 logging to specific group.
1322 */
1323#define Log3Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_3, a_Grp, a)
1324
1325/** @def Log4Ex
1326 * Level 4 logging to specific group.
1327 */
1328#define Log4Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_4, a_Grp, a)
1329
1330/** @def Log5Ex
1331 * Level 5 logging to specific group.
1332 */
1333#define Log5Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_5, a_Grp, a)
1334
1335/** @def Log6Ex
1336 * Level 6 logging to specific group.
1337 */
1338#define Log6Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_6, a_Grp, a)
1339
1340/** @def Log7Ex
1341 * Level 7 logging to specific group.
1342 */
1343#define Log7Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_7, a_Grp, a)
1344
1345/** @def Log8Ex
1346 * Level 8 logging to specific group.
1347 */
1348#define Log8Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_8, a_Grp, a)
1349
1350/** @def Log9Ex
1351 * Level 9 logging to specific group.
1352 */
1353#define Log9Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_9, a_Grp, a)
1354
1355/** @def Log10Ex
1356 * Level 10 logging to specific group.
1357 */
1358#define Log10Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_10, a_Grp, a)
1359
1360/** @def Log11Ex
1361 * Level 11 logging to specific group.
1362 */
1363#define Log11Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_11, a_Grp, a)
1364
1365/** @def Log12Ex
1366 * Level 12 logging to specific group.
1367 */
1368#define Log12Ex(a_Grp, a) LogIt(RTLOGGRPFLAGS_LEVEL_12, a_Grp, a)
1369
1370/** @def LogFlowEx
1371 * Logging of execution flow to specific group.
1372 */
1373#define LogFlowEx(a_Grp, a) LogIt(RTLOGGRPFLAGS_FLOW, a_Grp, a)
1374
1375/** @def LogWarnEx
1376 * Logging of warnings to specific group.
1377 */
1378#define LogWarnEx(a_Grp, a) LogIt(RTLOGGRPFLAGS_WARN, a_Grp, a)
1379/** @} */
1380
1381
1382/** @name Passing Function Call Position When Logging.
1383 *
1384 * This is a little bit ugly as we have to omit the comma before the
1385 * position parameters so that we don't inccur any overhead in non-logging
1386 * builds (!defined(LOG_ENABLED).
1387 *
1388 * @{ */
1389/** Source position for passing to a function call. */
1390#ifdef LOG_ENABLED
1391# define RTLOG_COMMA_SRC_POS , __FILE__, __LINE__, LOG_FN_NAME
1392#else
1393# define RTLOG_COMMA_SRC_POS RT_NOTHING
1394#endif
1395/** Source position declaration. */
1396#ifdef LOG_ENABLED
1397# define RTLOG_COMMA_SRC_POS_DECL , const char *pszFile, unsigned iLine, const char *pszFunction
1398#else
1399# define RTLOG_COMMA_SRC_POS_DECL RT_NOTHING
1400#endif
1401/** Source position arguments. */
1402#ifdef LOG_ENABLED
1403# define RTLOG_COMMA_SRC_POS_ARGS , pszFile, iLine, pszFunction
1404#else
1405# define RTLOG_COMMA_SRC_POS_ARGS RT_NOTHING
1406#endif
1407/** Applies NOREF() to the source position arguments. */
1408#ifdef LOG_ENABLED
1409# define RTLOG_SRC_POS_NOREF() do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
1410#else
1411# define RTLOG_SRC_POS_NOREF() do { } while (0)
1412#endif
1413/** @} */
1414
1415
1416
1417/** @defgroup grp_rt_log_rel Release Logging
1418 * @{
1419 */
1420
1421#ifdef DOXYGEN_RUNNING
1422# define RTLOG_REL_DISABLED
1423# define RTLOG_REL_ENABLED
1424#endif
1425
1426/** @def RTLOG_REL_DISABLED
1427 * Use this compile time define to disable all release logging
1428 * macros.
1429 */
1430
1431/** @def RTLOG_REL_ENABLED
1432 * Use this compile time define to override RTLOG_REL_DISABLE.
1433 */
1434
1435/*
1436 * Determine whether release logging is enabled and forcefully normalize the indicators.
1437 */
1438#if !defined(RTLOG_REL_DISABLED) || defined(RTLOG_REL_ENABLED)
1439# undef RTLOG_REL_DISABLED
1440# undef RTLOG_REL_ENABLED
1441# define RTLOG_REL_ENABLED
1442#else
1443# undef RTLOG_REL_ENABLED
1444# undef RTLOG_REL_DISABLED
1445# define RTLOG_REL_DISABLED
1446#endif
1447
1448/** @name Macros for checking whether a release log level is enabled.
1449 * @{ */
1450/** @def LogRelIsItEnabled
1451 * Checks whether the specified release logging group is enabled or not.
1452 */
1453#define LogRelIsItEnabled(a_fFlags, a_iGroup) ( RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)) != NULL )
1454
1455/** @def LogRelIsEnabled
1456 * Checks whether level 1 release logging is enabled.
1457 */
1458#define LogRelIsEnabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
1459
1460/** @def LogRelIs2Enabled
1461 * Checks whether level 2 release logging is enabled.
1462 */
1463#define LogRelIs2Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
1464
1465/** @def LogRelIs3Enabled
1466 * Checks whether level 3 release logging is enabled.
1467 */
1468#define LogRelIs3Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
1469
1470/** @def LogRelIs4Enabled
1471 * Checks whether level 4 release logging is enabled.
1472 */
1473#define LogRelIs4Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
1474
1475/** @def LogRelIs5Enabled
1476 * Checks whether level 5 release logging is enabled.
1477 */
1478#define LogRelIs5Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
1479
1480/** @def LogRelIs6Enabled
1481 * Checks whether level 6 release logging is enabled.
1482 */
1483#define LogRelIs6Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
1484
1485/** @def LogRelIs7Enabled
1486 * Checks whether level 7 release logging is enabled.
1487 */
1488#define LogRelIs7Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP)
1489
1490/** @def LogRelIs8Enabled
1491 * Checks whether level 8 release logging is enabled.
1492 */
1493#define LogRelIs8Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP)
1494
1495/** @def LogRelIs2Enabled
1496 * Checks whether level 9 release logging is enabled.
1497 */
1498#define LogRelIs9Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP)
1499
1500/** @def LogRelIs10Enabled
1501 * Checks whether level 10 release logging is enabled.
1502 */
1503#define LogRelIs10Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP)
1504
1505/** @def LogRelIs11Enabled
1506 * Checks whether level 10 release logging is enabled.
1507 */
1508#define LogRelIs11Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP)
1509
1510/** @def LogRelIs12Enabled
1511 * Checks whether level 12 release logging is enabled.
1512 */
1513#define LogRelIs12Enabled() LogRelIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP)
1514
1515/** @def LogRelIsFlowEnabled
1516 * Checks whether execution flow release logging is enabled.
1517 */
1518#define LogRelIsFlowEnabled() LogRelIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
1519
1520/** @def LogRelIsWarnEnabled
1521 * Checks whether warning level release logging is enabled.
1522 */
1523#define LogRelIsWarnEnabled() LogRelIsItEnabled(RTLOGGRPFLAGS_FLOW, LOG_GROUP)
1524/** @} */
1525
1526
1527/** @def LogRelIt
1528 * Write to specific logger if group enabled.
1529 */
1530/** @def LogRelItLikely
1531 * Write to specific logger if group enabled, assuming it likely it is enabled.
1532 */
1533/** @def LogRelMaxIt
1534 * Write to specific logger if group enabled and at less than a_cMax messages
1535 * have hit the log. Uses a static variable to count.
1536 */
1537#ifdef RTLOG_REL_ENABLED
1538# if defined(LOG_USE_C99)
1539# define _LogRelRemoveParentheseis(...) __VA_ARGS__
1540# define _LogRelIt(a_fFlags, a_iGroup, ...) \
1541 do \
1542 { \
1543 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1544 if (RT_LIKELY(!LogRelIt_pLogger)) \
1545 { /* likely */ } \
1546 else \
1547 RTLogLoggerExWeak(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
1548 _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
1549 } while (0)
1550# define LogRelIt(a_fFlags, a_iGroup, fmtargs) \
1551 _LogRelIt(a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
1552# define _LogRelItLikely(a_fFlags, a_iGroup, ...) \
1553 do \
1554 { \
1555 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1556 if (LogRelIt_pLogger) \
1557 RTLogLoggerExWeak(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
1558 _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
1559 } while (0)
1560# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) \
1561 _LogRelItLikely(a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
1562# define _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, ...) \
1563 do \
1564 { \
1565 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1566 if (LogRelIt_pLogger) \
1567 { \
1568 static uint32_t s_LogRelMaxIt_cLogged = 0; \
1569 if (s_LogRelMaxIt_cLogged < (a_cMax)) \
1570 { \
1571 s_LogRelMaxIt_cLogged++; \
1572 RTLogLoggerExWeak(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
1573 } \
1574 } \
1575 _LogIt(a_fFlags, a_iGroup, __VA_ARGS__); \
1576 } while (0)
1577# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) \
1578 _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
1579# else
1580# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) \
1581 do \
1582 { \
1583 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1584 if (LogRelIt_pLogger) \
1585 { \
1586 LogRelIt_pLogger->pfnLogger fmtargs; \
1587 } \
1588 LogIt(a_fFlags, a_iGroup, fmtargs); \
1589 } while (0)
1590# define LogRelIt(a_fFlags, a_iGroup, fmtargs) \
1591 do \
1592 { \
1593 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1594 if (RT_LIKELY(!LogRelIt_pLogger)) \
1595 { /* likely */ } \
1596 else \
1597 { \
1598 LogRelIt_pLogger->pfnLogger fmtargs; \
1599 } \
1600 LogIt(a_fFlags, a_iGroup, fmtargs); \
1601 } while (0)
1602# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) \
1603 do \
1604 { \
1605 PRTLOGGER LogRelIt_pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(a_fFlags, a_iGroup)); \
1606 if (LogRelIt_pLogger) \
1607 { \
1608 static uint32_t s_LogRelMaxIt_cLogged = 0; \
1609 if (s_LogRelMaxIt_cLogged < (a_cMax)) \
1610 { \
1611 s_LogRelMaxIt_cLogged++; \
1612 LogRelIt_pLogger->pfnLogger fmtargs; \
1613 } \
1614 } \
1615 LogIt(a_fFlags, a_iGroup, fmtargs); \
1616 } while (0)
1617# endif
1618#else /* !RTLOG_REL_ENABLED */
1619# define LogRelIt(a_fFlags, a_iGroup, fmtargs) do { } while (0)
1620# define LogRelItLikely(a_fFlags, a_iGroup, fmtargs) do { } while (0)
1621# define LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, fmtargs) do { } while (0)
1622# if defined(LOG_USE_C99)
1623# define _LogRelRemoveParentheseis(...) __VA_ARGS__
1624# define _LogRelIt(a_fFlags, a_iGroup, ...) do { } while (0)
1625# define _LogRelItLikely(a_fFlags, a_iGroup, ...) do { } while (0)
1626# define _LogRelMaxIt(a_cMax, a_fFlags, a_iGroup, ...) do { } while (0)
1627# endif
1628#endif /* !RTLOG_REL_ENABLED */
1629
1630
1631/** @name Basic release logging macros
1632 * @{ */
1633/** @def LogRel
1634 * Level 1 release logging.
1635 */
1636#define LogRel(a) LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
1637
1638/** @def LogRel2
1639 * Level 2 release logging.
1640 */
1641#define LogRel2(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
1642
1643/** @def LogRel3
1644 * Level 3 release logging.
1645 */
1646#define LogRel3(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
1647
1648/** @def LogRel4
1649 * Level 4 release logging.
1650 */
1651#define LogRel4(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
1652
1653/** @def LogRel5
1654 * Level 5 release logging.
1655 */
1656#define LogRel5(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
1657
1658/** @def LogRel6
1659 * Level 6 release logging.
1660 */
1661#define LogRel6(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
1662
1663/** @def LogRel7
1664 * Level 7 release logging.
1665 */
1666#define LogRel7(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, a)
1667
1668/** @def LogRel8
1669 * Level 8 release logging.
1670 */
1671#define LogRel8(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, a)
1672
1673/** @def LogRel9
1674 * Level 9 release logging.
1675 */
1676#define LogRel9(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, a)
1677
1678/** @def LogRel10
1679 * Level 10 release logging.
1680 */
1681#define LogRel10(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
1682
1683/** @def LogRel11
1684 * Level 11 release logging.
1685 */
1686#define LogRel11(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
1687
1688/** @def LogRel12
1689 * Level 12 release logging.
1690 */
1691#define LogRel12(a) LogRelIt(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
1692
1693/** @def LogRelFlow
1694 * Logging of execution flow.
1695 */
1696#define LogRelFlow(a) LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
1697
1698/** @def LogRelWarn
1699 * Warning level release logging.
1700 */
1701#define LogRelWarn(a) LogRelIt(RTLOGGRPFLAGS_WARN, LOG_GROUP, a)
1702/** @} */
1703
1704
1705
1706/** @name Basic release logging macros with local max
1707 * @{ */
1708/** @def LogRelMax
1709 * Level 1 release logging with a max number of log entries.
1710 */
1711#define LogRelMax(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
1712
1713/** @def LogRelMax2
1714 * Level 2 release logging with a max number of log entries.
1715 */
1716#define LogRelMax2(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
1717
1718/** @def LogRelMax3
1719 * Level 3 release logging with a max number of log entries.
1720 */
1721#define LogRelMax3(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
1722
1723/** @def LogRelMax4
1724 * Level 4 release logging with a max number of log entries.
1725 */
1726#define LogRelMax4(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
1727
1728/** @def LogRelMax5
1729 * Level 5 release logging with a max number of log entries.
1730 */
1731#define LogRelMax5(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
1732
1733/** @def LogRelMax6
1734 * Level 6 release logging with a max number of log entries.
1735 */
1736#define LogRelMax6(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
1737
1738/** @def LogRelMax7
1739 * Level 7 release logging with a max number of log entries.
1740 */
1741#define LogRelMax7(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_7, LOG_GROUP, a)
1742
1743/** @def LogRelMax8
1744 * Level 8 release logging with a max number of log entries.
1745 */
1746#define LogRelMax8(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_8, LOG_GROUP, a)
1747
1748/** @def LogRelMax9
1749 * Level 9 release logging with a max number of log entries.
1750 */
1751#define LogRelMax9(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_9, LOG_GROUP, a)
1752
1753/** @def LogRelMax10
1754 * Level 10 release logging with a max number of log entries.
1755 */
1756#define LogRelMax10(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_10, LOG_GROUP, a)
1757
1758/** @def LogRelMax11
1759 * Level 11 release logging with a max number of log entries.
1760 */
1761#define LogRelMax11(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_11, LOG_GROUP, a)
1762
1763/** @def LogRelMax12
1764 * Level 12 release logging with a max number of log entries.
1765 */
1766#define LogRelMax12(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP, a)
1767
1768/** @def LogRelMaxFlow
1769 * Logging of execution flow with a max number of log entries.
1770 */
1771#define LogRelMaxFlow(a_cMax, a) LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
1772/** @} */
1773
1774
1775/** @name Release logging macros prefixing the current function name.
1776 * @{ */
1777
1778/** @def LogRelFunc
1779 * Release logging. Prepends the given log message with the function name
1780 * followed by a semicolon and space.
1781 */
1782#ifdef LOG_USE_C99
1783# define LogRelFunc(a) \
1784 _LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1785#else
1786# define LogRelFunc(a) do { LogRel((LOG_FN_FMT ": ", LOG_FN_NAME)); LogRel(a); } while (0)
1787#endif
1788
1789/** @def LogRelFlowFunc
1790 * Release logging. Macro to log the execution flow inside C/C++ functions.
1791 *
1792 * Prepends the given log message with the function name followed by
1793 * a semicolon and space.
1794 *
1795 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1796 */
1797#ifdef LOG_USE_C99
1798# define LogRelFlowFunc(a) _LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1799#else
1800# define LogRelFlowFunc(a) do { LogRelFlow((LOG_FN_FMT ": ", LOG_FN_NAME)); LogRelFlow(a); } while (0)
1801#endif
1802
1803/** @def LogRelMaxFunc
1804 * Release logging. Prepends the given log message with the function name
1805 * followed by a semicolon and space.
1806 */
1807#ifdef LOG_USE_C99
1808# define LogRelMaxFunc(a_cMax, a) \
1809 _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1810#else
1811# define LogRelMaxFunc(a_cMax, a) \
1812 do { LogRelMax(a_cMax, (LOG_FN_FMT ": ", LOG_FN_NAME)); LogRelMax(a_cMax, a); } while (0)
1813#endif
1814
1815/** @def LogRelMaxFlowFunc
1816 * Release logging. Macro to log the execution flow inside C/C++ functions.
1817 *
1818 * Prepends the given log message with the function name followed by
1819 * a semicolon and space.
1820 *
1821 * @param a_cMax Max number of times this should hit the log.
1822 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1823 */
1824#ifdef LOG_USE_C99
1825# define LogRelMaxFlowFunc(a_cMax, a) \
1826 _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", LOG_FN_NAME, _LogRemoveParentheseis a )
1827#else
1828# define LogRelMaxFlowFunc(a_cMax, a) \
1829 do { LogRelMaxFlow(a_cMax, (LOG_FN_FMT ": ", LOG_FN_NAME)); LogRelFlow(a_cMax, a); } while (0)
1830#endif
1831
1832/** @} */
1833
1834
1835/** @name Release Logging macros prefixing the this pointer value and method name.
1836 * @{ */
1837
1838/** @def LogRelThisFunc
1839 * The same as LogRelFunc but for class functions (methods): the resulting log
1840 * line is additionally prepended with a hex value of |this| pointer.
1841 */
1842#ifdef LOG_USE_C99
1843# define LogRelThisFunc(a) \
1844 _LogRelItLikely(RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1845#else
1846# define LogRelThisFunc(a) \
1847 do { LogRel(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogRel(a); } while (0)
1848#endif
1849
1850/** @def LogRelMaxThisFunc
1851 * The same as LogRelFunc but for class functions (methods): the resulting log
1852 * line is additionally prepended with a hex value of |this| pointer.
1853 * @param a_cMax Max number of times this should hit the log.
1854 * @param a Log message in format <tt>("string\n" [, args])</tt>.
1855 */
1856#ifdef LOG_USE_C99
1857# define LogRelMaxThisFunc(a_cMax, a) \
1858 _LogRelMaxIt(a_cMax, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1859#else
1860# define LogRelMaxThisFunc(a_cMax, a) \
1861 do { LogRelMax(a_cMax, ("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogRelMax(a_cMax, a); } while (0)
1862#endif
1863
1864/** @def LogRelFlowThisFunc
1865 * The same as LogRelFlowFunc but for class functions (methods): the resulting
1866 * log line is additionally prepended with a hex value of |this| pointer.
1867 */
1868#ifdef LOG_USE_C99
1869# define LogRelFlowThisFunc(a) \
1870 _LogRelIt(RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, LOG_FN_NAME, _LogRemoveParentheseis a )
1871#else
1872# define LogRelFlowThisFunc(a) do { LogRelFlow(("{%p} " LOG_FN_FMT ": ", this, LOG_FN_NAME)); LogRelFlow(a); } while (0)
1873#endif
1874
1875
1876/** Shortcut to |LogRelFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
1877#define LogRelFlowFuncEnter() LogRelFlowFunc(("ENTER\n"))
1878
1879/** Shortcut to |LogRelFlowFunc ("LEAVE\n")|, marks the end of the function. */
1880#define LogRelFlowFuncLeave() LogRelFlowFunc(("LEAVE\n"))
1881
1882/** Shortcut to |LogRelFlowFunc ("LEAVE: %Rrc\n")|, marks the end of the function. */
1883#define LogRelFlowFuncLeaveRC(rc) LogRelFlowFunc(("LEAVE: %Rrc\n", (rc)))
1884
1885/** Shortcut to |LogRelFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
1886#define LogRelFlowThisFuncEnter() LogRelFlowThisFunc(("ENTER\n"))
1887
1888/** Shortcut to |LogRelFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
1889#define LogRelFlowThisFuncLeave() LogRelFlowThisFunc(("LEAVE\n"))
1890
1891/** @} */
1892
1893
1894/**
1895 * Sets the default release logger instance.
1896 *
1897 * @returns The old default instance.
1898 * @param pLogger The new default release logger instance.
1899 */
1900RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger);
1901
1902/**
1903 * Gets the default release logger instance.
1904 *
1905 * @returns Pointer to default release logger instance if availble, otherwise NULL.
1906 */
1907RTDECL(PRTLOGGER) RTLogRelGetDefaultInstance(void);
1908
1909/** @copydoc RTLogRelGetDefaultInstance */
1910typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGRELGETDEFAULTINSTANCE,(void));
1911/** Pointer to RTLogRelGetDefaultInstance. */
1912typedef FNLOGRELGETDEFAULTINSTANCE *PFNLOGRELGETDEFAULTINSTANCE;
1913
1914/** "Weak symbol" emulation for RTLogRelGetDefaultInstance.
1915 * @note This is first set when RTLogRelSetDefaultInstance is called. */
1916extern RTDATADECL(PFNLOGRELGETDEFAULTINSTANCE) g_pfnRTLogRelGetDefaultInstance;
1917
1918/** "Weak symbol" wrapper for RTLogRelGetDefaultInstance. */
1919DECL_FORCE_INLINE(PRTLOGGER) RTLogRelGetDefaultInstanceWeak(void)
1920{
1921#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
1922 if (g_pfnRTLogRelGetDefaultInstance)
1923 return g_pfnRTLogRelGetDefaultInstance();
1924 return NULL;
1925#else
1926 return RTLogRelGetDefaultInstance();
1927#endif
1928}
1929
1930/**
1931 * Gets the default release logger instance.
1932 *
1933 * @returns Pointer to default release logger instance if availble, otherwise NULL.
1934 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
1935 * the high 16 bits.
1936 */
1937RTDECL(PRTLOGGER) RTLogRelGetDefaultInstanceEx(uint32_t fFlagsAndGroup);
1938
1939/** @copydoc RTLogRelGetDefaultInstanceEx */
1940typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGRELGETDEFAULTINSTANCEEX,(uint32_t fFlagsAndGroup));
1941/** Pointer to RTLogRelGetDefaultInstanceEx. */
1942typedef FNLOGRELGETDEFAULTINSTANCEEX *PFNLOGRELGETDEFAULTINSTANCEEX;
1943
1944/** "Weak symbol" emulation for RTLogRelGetDefaultInstanceEx.
1945 * @note This is first set when RTLogRelSetDefaultInstance is called. */
1946extern RTDATADECL(PFNLOGRELGETDEFAULTINSTANCEEX) g_pfnRTLogRelGetDefaultInstanceEx;
1947
1948/** "Weak symbol" wrapper for RTLogRelGetDefaultInstanceEx. */
1949DECL_FORCE_INLINE(PRTLOGGER) RTLogRelGetDefaultInstanceExWeak(uint32_t fFlagsAndGroup)
1950{
1951#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
1952 if (g_pfnRTLogRelGetDefaultInstanceEx)
1953 return g_pfnRTLogRelGetDefaultInstanceEx(fFlagsAndGroup);
1954 return NULL;
1955#else
1956 return RTLogRelGetDefaultInstanceEx(fFlagsAndGroup);
1957#endif
1958}
1959
1960
1961/**
1962 * Write to a logger instance, defaulting to the release one.
1963 *
1964 * This function will check whether the instance, group and flags makes up a
1965 * logging kind which is currently enabled before writing anything to the log.
1966 *
1967 * @param pLogger Pointer to logger instance.
1968 * @param fFlags The logging flags.
1969 * @param iGroup The group.
1970 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
1971 * only for internal usage!
1972 * @param pszFormat Format string.
1973 * @param ... Format arguments.
1974 * @remark This is a worker function for LogRelIt.
1975 */
1976RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
1977 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
1978
1979/**
1980 * Write to a logger instance, defaulting to the release one.
1981 *
1982 * This function will check whether the instance, group and flags makes up a
1983 * logging kind which is currently enabled before writing anything to the log.
1984 *
1985 * @param pLogger Pointer to logger instance. If NULL the default release instance is attempted.
1986 * @param fFlags The logging flags.
1987 * @param iGroup The group.
1988 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
1989 * only for internal usage!
1990 * @param pszFormat Format string.
1991 * @param args Format arguments.
1992 */
1993RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
1994 const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(4, 0);
1995
1996/**
1997 * printf like function for writing to the default release log.
1998 *
1999 * @param pszFormat Printf like format string.
2000 * @param ... Optional arguments as specified in pszFormat.
2001 *
2002 * @remark The API doesn't support formatting of floating point numbers at the moment.
2003 */
2004RTDECL(void) RTLogRelPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2005
2006/**
2007 * vprintf like function for writing to the default release log.
2008 *
2009 * @param pszFormat Printf like format string.
2010 * @param args Optional arguments as specified in pszFormat.
2011 *
2012 * @remark The API doesn't support formatting of floating point numbers at the moment.
2013 */
2014RTDECL(void) RTLogRelPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
2015
2016/**
2017 * Changes the buffering setting of the default release logger.
2018 *
2019 * This can be used for optimizing longish logging sequences.
2020 *
2021 * @returns The old state.
2022 * @param fBuffered The new state.
2023 */
2024RTDECL(bool) RTLogRelSetBuffering(bool fBuffered);
2025
2026/** @} */
2027
2028
2029
2030/** @name COM port logging
2031 * @{
2032 */
2033
2034#ifdef DOXYGEN_RUNNING
2035# define LOG_TO_COM
2036# define LOG_NO_COM
2037#endif
2038
2039/** @def LOG_TO_COM
2040 * Redirects the normal logging macros to the serial versions.
2041 */
2042
2043/** @def LOG_NO_COM
2044 * Disables all LogCom* macros.
2045 */
2046
2047/** @def LogCom
2048 * Generic logging to serial port.
2049 */
2050#if defined(LOG_ENABLED) && !defined(LOG_NO_COM)
2051# define LogCom(a) RTLogComPrintf a
2052#else
2053# define LogCom(a) do { } while (0)
2054#endif
2055
2056/** @def LogComFlow
2057 * Logging to serial port of execution flow.
2058 */
2059#if defined(LOG_ENABLED) && defined(LOG_ENABLE_FLOW) && !defined(LOG_NO_COM)
2060# define LogComFlow(a) RTLogComPrintf a
2061#else
2062# define LogComFlow(a) do { } while (0)
2063#endif
2064
2065#ifdef LOG_TO_COM
2066# undef Log
2067# define Log(a) LogCom(a)
2068# undef LogFlow
2069# define LogFlow(a) LogComFlow(a)
2070#endif
2071
2072/** @} */
2073
2074
2075/** @name Backdoor Logging
2076 * @{
2077 */
2078
2079#ifdef DOXYGEN_RUNNING
2080# define LOG_TO_BACKDOOR
2081# define LOG_NO_BACKDOOR
2082#endif
2083
2084/** @def LOG_TO_BACKDOOR
2085 * Redirects the normal logging macros to the backdoor versions.
2086 */
2087
2088/** @def LOG_NO_BACKDOOR
2089 * Disables all LogBackdoor* macros.
2090 */
2091
2092/** @def LogBackdoor
2093 * Generic logging to the VBox backdoor via port I/O.
2094 */
2095#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
2096# define LogBackdoor(a) RTLogBackdoorPrintf a
2097#else
2098# define LogBackdoor(a) do { } while (0)
2099#endif
2100
2101/** @def LogBackdoorFlow
2102 * Logging of execution flow messages to the backdoor I/O port.
2103 */
2104#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
2105# define LogBackdoorFlow(a) RTLogBackdoorPrintf a
2106#else
2107# define LogBackdoorFlow(a) do { } while (0)
2108#endif
2109
2110/** @def LogRelBackdoor
2111 * Release logging to the VBox backdoor via port I/O.
2112 */
2113#if !defined(LOG_NO_BACKDOOR)
2114# define LogRelBackdoor(a) RTLogBackdoorPrintf a
2115#else
2116# define LogRelBackdoor(a) do { } while (0)
2117#endif
2118
2119#ifdef LOG_TO_BACKDOOR
2120# undef Log
2121# define Log(a) LogBackdoor(a)
2122# undef LogFlow
2123# define LogFlow(a) LogBackdoorFlow(a)
2124# undef LogRel
2125# define LogRel(a) LogRelBackdoor(a)
2126# if defined(LOG_USE_C99)
2127# undef _LogIt
2128# define _LogIt(a_fFlags, a_iGroup, ...) LogBackdoor((__VA_ARGS__))
2129# endif
2130#endif
2131
2132/** @} */
2133
2134
2135
2136/**
2137 * Gets the default logger instance, creating it if necessary.
2138 *
2139 * @returns Pointer to default logger instance if availble, otherwise NULL.
2140 */
2141RTDECL(PRTLOGGER) RTLogDefaultInstance(void);
2142
2143/**
2144 * Gets the logger instance if enabled, creating it if necessary.
2145 *
2146 * @returns Pointer to default logger instance, if group has the specified
2147 * flags enabled. Otherwise NULL is returned.
2148 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
2149 * the high 16 bits.
2150 */
2151RTDECL(PRTLOGGER) RTLogDefaultInstanceEx(uint32_t fFlagsAndGroup);
2152
2153/**
2154 * Gets the default logger instance (does not create one).
2155 *
2156 * @returns Pointer to default logger instance if availble, otherwise NULL.
2157 */
2158RTDECL(PRTLOGGER) RTLogGetDefaultInstance(void);
2159
2160/** @copydoc RTLogGetDefaultInstance */
2161typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGGETDEFAULTINSTANCE,(void));
2162/** Pointer to RTLogGetDefaultInstance. */
2163typedef FNLOGGETDEFAULTINSTANCE *PFNLOGGETDEFAULTINSTANCE;
2164
2165/** "Weak symbol" emulation for RTLogGetDefaultInstance.
2166 * @note This is first set when RTLogSetDefaultInstance is called. */
2167extern RTDATADECL(PFNLOGGETDEFAULTINSTANCE) g_pfnRTLogGetDefaultInstance;
2168
2169/** "Weak symbol" wrapper for RTLogGetDefaultInstance. */
2170DECL_FORCE_INLINE(PRTLOGGER) RTLogGetDefaultInstanceWeak(void)
2171{
2172#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2173 if (g_pfnRTLogGetDefaultInstance)
2174 return g_pfnRTLogGetDefaultInstance();
2175 return NULL;
2176#else
2177 return RTLogGetDefaultInstance();
2178#endif
2179}
2180
2181/**
2182 * Gets the default logger instance if enabled (does not create one).
2183 *
2184 * @returns Pointer to default logger instance, if group has the specified
2185 * flags enabled. Otherwise NULL is returned.
2186 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
2187 * the high 16 bits.
2188 */
2189RTDECL(PRTLOGGER) RTLogGetDefaultInstanceEx(uint32_t fFlagsAndGroup);
2190
2191/** @copydoc RTLogGetDefaultInstanceEx */
2192typedef DECLCALLBACKTYPE(PRTLOGGER, FNLOGGETDEFAULTINSTANCEEX,(uint32_t fFlagsAndGroup));
2193/** Pointer to RTLogGetDefaultInstanceEx. */
2194typedef FNLOGGETDEFAULTINSTANCEEX *PFNLOGGETDEFAULTINSTANCEEX;
2195
2196/** "Weak symbol" emulation for RTLogGetDefaultInstanceEx.
2197 * @note This is first set when RTLogSetDefaultInstance is called. */
2198extern RTDATADECL(PFNLOGGETDEFAULTINSTANCEEX) g_pfnRTLogGetDefaultInstanceEx;
2199
2200/** "Weak symbol" wrapper for RTLogGetDefaultInstanceEx. */
2201DECL_FORCE_INLINE(PRTLOGGER) RTLogGetDefaultInstanceExWeak(uint32_t fFlagsAndGroup)
2202{
2203#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2204 if (g_pfnRTLogGetDefaultInstanceEx)
2205 return g_pfnRTLogGetDefaultInstanceEx(fFlagsAndGroup);
2206 return NULL;
2207#else
2208 return RTLogGetDefaultInstanceEx(fFlagsAndGroup);
2209#endif
2210}
2211
2212/**
2213 * Sets the default logger instance.
2214 *
2215 * @returns The old default instance.
2216 * @param pLogger The new default logger instance.
2217 */
2218RTDECL(PRTLOGGER) RTLogSetDefaultInstance(PRTLOGGER pLogger);
2219
2220#ifdef IN_RING0
2221/**
2222 * Changes the default logger instance for the current thread.
2223 *
2224 * @returns IPRT status code.
2225 * @param pLogger The logger instance. Pass NULL for deregistration.
2226 * @param uKey Associated key for cleanup purposes. If pLogger is NULL,
2227 * all instances with this key will be deregistered. So in
2228 * order to only deregister the instance associated with the
2229 * current thread use 0.
2230 */
2231RTR0DECL(int) RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey);
2232#endif /* IN_RING0 */
2233
2234/**
2235 * Creates the default logger instance for IPRT users.
2236 *
2237 * Any user of the logging features will need to implement
2238 * this or use the generic dummy.
2239 *
2240 * @returns Pointer to the logger instance.
2241 */
2242RTDECL(PRTLOGGER) RTLogDefaultInit(void);
2243
2244/**
2245 * This is the 2nd half of what RTLogGetDefaultInstanceEx() and
2246 * RTLogRelGetDefaultInstanceEx() does.
2247 *
2248 * @returns If the group has the specified flags enabled @a pLogger will be
2249 * returned returned. Otherwise NULL is returned.
2250 * @param pLogger The logger. NULL is NULL.
2251 * @param fFlagsAndGroup The flags in the lower 16 bits, the group number in
2252 * the high 16 bits.
2253 */
2254RTDECL(PRTLOGGER) RTLogCheckGroupFlags(PRTLOGGER pLogger, uint32_t fFlagsAndGroup);
2255
2256/**
2257 * Create a logger instance.
2258 *
2259 * @returns iprt status code.
2260 *
2261 * @param ppLogger Where to store the logger instance.
2262 * @param fFlags Logger instance flags, a combination of the
2263 * RTLOGFLAGS_* values.
2264 * @param pszGroupSettings The initial group settings.
2265 * @param pszEnvVarBase Base name for the environment variables for
2266 * this instance.
2267 * @param cGroups Number of groups in the array.
2268 * @param papszGroups Pointer to array of groups. This must stick
2269 * around for the life of the logger instance.
2270 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
2271 * if pszFilenameFmt specified.
2272 * @param pszFilenameFmt Log filename format string. Standard
2273 * RTStrFormat().
2274 * @param ... Format arguments.
2275 */
2276RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint64_t fFlags, const char *pszGroupSettings,
2277 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
2278 uint32_t fDestFlags, const char *pszFilenameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 9);
2279
2280/**
2281 * Create a logger instance.
2282 *
2283 * @returns iprt status code.
2284 *
2285 * @param ppLogger Where to store the logger instance.
2286 * @param pszEnvVarBase Base name for the environment variables for
2287 * this instance (ring-3 only).
2288 * @param fFlags Logger instance flags, a combination of the
2289 * RTLOGFLAGS_* values.
2290 * @param pszGroupSettings The initial group settings.
2291 * @param cGroups Number of groups in the array.
2292 * @param papszGroups Pointer to array of groups. This must stick
2293 * around for the life of the logger instance.
2294 * @param cMaxEntriesPerGroup The max number of entries per group. UINT32_MAX
2295 * or zero for unlimited.
2296 * @param cBufDescs Number of buffer descriptors that @a paBufDescs
2297 * points to. Zero for defaults.
2298 * @param paBufDescs Buffer descriptors, optional.
2299 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
2300 * if pszFilenameFmt specified.
2301 * @param pfnPhase Callback function for starting logging and for
2302 * ending or starting a new file for log history
2303 * rotation. NULL is OK.
2304 * @param cHistory Number of old log files to keep when performing
2305 * log history rotation. 0 means no history.
2306 * @param cbHistoryFileMax Maximum size of log file when performing
2307 * history rotation. 0 means no size limit.
2308 * @param cSecsHistoryTimeSlot Maximum time interval per log file when
2309 * performing history rotation, in seconds.
2310 * 0 means time limit.
2311 * @param pOutputIf The optional file output interface, can be NULL which will
2312 * make use of the default one.
2313 * @param pvOutputIfUser The opaque user data to pass to the callbacks in the output interface.
2314 * @param pErrInfo Where to return extended error information.
2315 * Optional.
2316 * @param pszFilenameFmt Log filename format string. Standard RTStrFormat().
2317 * @param ... Format arguments.
2318 */
2319RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
2320 unsigned cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
2321 uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags,
2322 PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
2323 PCRTLOGOUTPUTIF pOutputIf, void *pvOutputIfUser,
2324 PRTERRINFO pErrInfo, const char *pszFilenameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(18, 19);
2325
2326/**
2327 * Create a logger instance.
2328 *
2329 * @returns iprt status code.
2330 *
2331 * @param ppLogger Where to store the logger instance.
2332 * @param pszEnvVarBase Base name for the environment variables for
2333 * this instance (ring-3 only).
2334 * @param fFlags Logger instance flags, a combination of the
2335 * RTLOGFLAGS_* values.
2336 * @param pszGroupSettings The initial group settings.
2337 * @param cGroups Number of groups in the array.
2338 * @param papszGroups Pointer to array of groups. This must stick
2339 * around for the life of the logger instance.
2340 * @param cMaxEntriesPerGroup The max number of entries per group. UINT32_MAX
2341 * or zero for unlimited.
2342 * @param cBufDescs Number of buffer descriptors that @a paBufDescs
2343 * points to. Zero for defaults.
2344 * @param paBufDescs Buffer descriptors, optional.
2345 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
2346 * if pszFilenameFmt specified.
2347 * @param pfnPhase Callback function for starting logging and for
2348 * ending or starting a new file for log history
2349 * rotation.
2350 * @param cHistory Number of old log files to keep when performing
2351 * log history rotation. 0 means no history.
2352 * @param cbHistoryFileMax Maximum size of log file when performing
2353 * history rotation. 0 means no size limit.
2354 * @param cSecsHistoryTimeSlot Maximum time interval per log file when
2355 * performing history rotation, in seconds.
2356 * 0 means no time limit.
2357 * @param pOutputIf The optional file output interface, can be NULL which will
2358 * make use of the default one.
2359 * @param pvOutputIfUser The opaque user data to pass to the callbacks in the output interface.
2360 * @param pErrInfo Where to return extended error information.
2361 * Optional.
2362 * @param pszFilenameFmt Log filename format string. Standard
2363 * RTStrFormat().
2364 * @param va Format arguments.
2365 */
2366RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, const char *pszEnvVarBase, uint64_t fFlags, const char *pszGroupSettings,
2367 uint32_t cGroups, const char * const *papszGroups, uint32_t cMaxEntriesPerGroup,
2368 uint32_t cBufDescs, PRTLOGBUFFERDESC paBufDescs, uint32_t fDestFlags,
2369 PFNRTLOGPHASE pfnPhase, uint32_t cHistory, uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
2370 PCRTLOGOUTPUTIF pOutputIf, void *pvOutputIfUser,
2371 PRTERRINFO pErrInfo, const char *pszFilenameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(18, 0);
2372
2373/**
2374 * Destroys a logger instance.
2375 *
2376 * The instance is flushed and all output destinations closed (where applicable).
2377 *
2378 * @returns iprt status code.
2379 * @param pLogger The logger instance which close destroyed. NULL is fine.
2380 */
2381RTDECL(int) RTLogDestroy(PRTLOGGER pLogger);
2382
2383/**
2384 * Sets the custom prefix callback.
2385 *
2386 * @returns IPRT status code.
2387 * @param pLogger The logger instance.
2388 * @param pfnCallback The callback.
2389 * @param pvUser The user argument for the callback.
2390 * */
2391RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCallback, void *pvUser);
2392
2393/**
2394 * Sets the custom flush callback.
2395 *
2396 * This can be handy for special loggers like the per-EMT ones in ring-0,
2397 * but also for implementing a log viewer in the debugger GUI.
2398 *
2399 * @returns IPRT status code.
2400 * @retval VWRN_ALREADY_EXISTS if it was set to a different flusher.
2401 * @param pLogger The logger instance.
2402 * @param pfnFlush The flush callback.
2403 */
2404RTDECL(int) RTLogSetFlushCallback(PRTLOGGER pLogger, PFNRTLOGFLUSH pfnFlush);
2405
2406/**
2407 * Sets the thread name for a thread specific ring-0 logger.
2408 *
2409 * @returns IPRT status code.
2410 * @param pLogger The logger. NULL is not allowed.
2411 * @param pszNameFmt The format string for the thread name.
2412 * @param ... Format arguments.
2413 */
2414RTR0DECL(int) RTLogSetR0ThreadNameF(PRTLOGGER pLogger, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(2, 3);
2415
2416/**
2417 * Sets the thread name for a thread specific ring-0 logger.
2418 *
2419 * @returns IPRT status code.
2420 * @param pLogger The logger. NULL is not allowed.
2421 * @param pszNameFmt The format string for the thread name.
2422 * @param va Format arguments.
2423 */
2424RTR0DECL(int) RTLogSetR0ThreadNameV(PRTLOGGER pLogger, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
2425
2426/**
2427 * Sets the program start time for a thread specific ring-0 logger.
2428 *
2429 * @returns IPRT status code.
2430 * @param pLogger The logger. NULL is not allowed.
2431 * @param nsStart The RTTimeNanoTS() value at program start.
2432 */
2433RTR0DECL(int) RTLogSetR0ProgramStart(PRTLOGGER pLogger, uint64_t nsStart);
2434
2435/**
2436 * Get the current log group settings as a string.
2437 *
2438 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2439 * @param pLogger Logger instance (NULL for default logger).
2440 * @param pszBuf The output buffer.
2441 * @param cchBuf The size of the output buffer. Must be greater than
2442 * zero.
2443 */
2444RTDECL(int) RTLogQueryGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
2445
2446/**
2447 * Updates the group settings for the logger instance using the specified
2448 * specification string.
2449 *
2450 * @returns iprt status code.
2451 * Failures can safely be ignored.
2452 * @param pLogger Logger instance (NULL for default logger).
2453 * @param pszValue Value to parse.
2454 */
2455RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue);
2456
2457/**
2458 * Sets the max number of entries per group.
2459 *
2460 * @returns Old restriction.
2461 *
2462 * @param pLogger The logger instance (NULL is an alias for the
2463 * default logger).
2464 * @param cMaxEntriesPerGroup The max number of entries per group.
2465 *
2466 * @remarks Lowering the limit of an active logger may quietly mute groups.
2467 * Raising it may reactive already muted groups.
2468 */
2469RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup);
2470
2471/**
2472 * Gets the current flag settings for the given logger.
2473 *
2474 * @returns Logger flags, UINT64_MAX if no logger.
2475 * @param pLogger Logger instance (NULL for default logger).
2476 */
2477RTDECL(uint64_t) RTLogGetFlags(PRTLOGGER pLogger);
2478
2479/**
2480 * Modifies the flag settings for the given logger.
2481 *
2482 * @returns IPRT status code. Returns VINF_LOG_NO_LOGGER if no default logger
2483 * and @a pLogger is NULL.
2484 * @param pLogger Logger instance (NULL for default logger).
2485 * @param fSet Mask of flags to set (OR).
2486 * @param fClear Mask of flags to clear (NAND). This is allowed to
2487 * include invalid flags - e.g. UINT64_MAX is okay.
2488 */
2489RTDECL(int) RTLogChangeFlags(PRTLOGGER pLogger, uint64_t fSet, uint64_t fClear);
2490
2491/**
2492 * Updates the flags for the logger instance using the specified
2493 * specification string.
2494 *
2495 * @returns iprt status code.
2496 * Failures can safely be ignored.
2497 * @param pLogger Logger instance (NULL for default logger).
2498 * @param pszValue Value to parse.
2499 */
2500RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue);
2501
2502/**
2503 * Changes the buffering setting of the specified logger.
2504 *
2505 * This can be used for optimizing longish logging sequences.
2506 *
2507 * @returns The old state.
2508 * @param pLogger The logger instance (NULL is an alias for the default
2509 * logger).
2510 * @param fBuffered The new state.
2511 */
2512RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered);
2513
2514/**
2515 * Get the current log flags as a string.
2516 *
2517 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2518 * @param pLogger Logger instance (NULL for default logger).
2519 * @param pszBuf The output buffer.
2520 * @param cchBuf The size of the output buffer. Must be greater than
2521 * zero.
2522 */
2523RTDECL(int) RTLogQueryFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
2524
2525/**
2526 * Gets the current destinations flags for the given logger.
2527 *
2528 * @returns Logger destination flags, UINT32_MAX if no logger.
2529 * @param pLogger Logger instance (NULL for default logger).
2530 */
2531RTDECL(uint32_t) RTLogGetDestinations(PRTLOGGER pLogger);
2532
2533/**
2534 * Modifies the log destinations settings for the given logger.
2535 *
2536 * This is only suitable for simple destination settings that doesn't take
2537 * additional arguments, like RTLOGDEST_FILE.
2538 *
2539 * @returns IPRT status code. Returns VINF_LOG_NO_LOGGER if no default logger
2540 * and @a pLogger is NULL.
2541 * @param pLogger Logger instance (NULL for default logger).
2542 * @param fSet Mask of destinations to set (OR).
2543 * @param fClear Mask of destinations to clear (NAND).
2544 */
2545RTDECL(int) RTLogChangeDestinations(PRTLOGGER pLogger, uint32_t fSet, uint32_t fClear);
2546
2547/**
2548 * Updates the logger destination using the specified string.
2549 *
2550 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2551 * @param pLogger Logger instance (NULL for default logger).
2552 * @param pszValue The value to parse.
2553 */
2554RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszValue);
2555
2556/**
2557 * Clear the file delay flag if set, opening the destination and flushing.
2558 *
2559 * @returns IPRT status code.
2560 * @param pLogger Logger instance (NULL for default logger).
2561 * @param pErrInfo Where to return extended error info. Optional.
2562 */
2563RTDECL(int) RTLogClearFileDelayFlag(PRTLOGGER pLogger, PRTERRINFO pErrInfo);
2564
2565/**
2566 * Get the current log destinations as a string.
2567 *
2568 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
2569 * @param pLogger Logger instance (NULL for default logger).
2570 * @param pszBuf The output buffer.
2571 * @param cchBuf The size of the output buffer. Must be greater than 0.
2572 */
2573RTDECL(int) RTLogQueryDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
2574
2575/**
2576 * Performs a bulk update of logger flags and group flags.
2577 *
2578 * This is for instanced used for copying settings from ring-3 to ring-0
2579 * loggers.
2580 *
2581 * @returns IPRT status code.
2582 * @param pLogger The logger instance (NULL for default logger).
2583 * @param fFlags The new logger flags.
2584 * @param uGroupCrc32 The CRC32 of the group name strings.
2585 * @param cGroups Number of groups.
2586 * @param pafGroups Array of group flags.
2587 * @sa RTLogQueryBulk
2588 */
2589RTDECL(int) RTLogBulkUpdate(PRTLOGGER pLogger, uint64_t fFlags, uint32_t uGroupCrc32, uint32_t cGroups, uint32_t const *pafGroups);
2590
2591/**
2592 * Queries data for a bulk update of logger flags and group flags.
2593 *
2594 * This is for instanced used for copying settings from ring-3 to ring-0
2595 * loggers.
2596 *
2597 * @returns IPRT status code.
2598 * @retval VERR_BUFFER_OVERFLOW if pafGroups is too small, @a pcGroups will be
2599 * set to the actual number of groups.
2600 * @param pLogger The logger instance (NULL for default logger).
2601 * @param pfFlags Where to return the logger flags.
2602 * @param puGroupCrc32 Where to return the CRC32 of the group names.
2603 * @param pcGroups Input: Size of the @a pafGroups allocation.
2604 * Output: Actual number of groups returned.
2605 * @param pafGroups Where to return the flags for each group.
2606 * @sa RTLogBulkUpdate
2607 */
2608RTDECL(int) RTLogQueryBulk(PRTLOGGER pLogger, uint64_t *pfFlags, uint32_t *puGroupCrc32, uint32_t *pcGroups, uint32_t *pafGroups);
2609
2610/**
2611 * Write/copy bulk log data from another logger.
2612 *
2613 * This is used for transferring stuff from the ring-0 loggers and into the
2614 * ring-3 one. The text goes in as-is w/o any processing (i.e. prefixing or
2615 * newline fun).
2616 *
2617 * @returns IRPT status code.
2618 * @param pLogger The logger instance (NULL for default logger).
2619 * @param pszBefore Text to log before the bulk text. Optional.
2620 * @param pch Pointer to the block of bulk log text to write.
2621 * @param cch Size of the block of bulk log text to write.
2622 * @param pszAfter Text to log after the bulk text. Optional.
2623 */
2624RTDECL(int) RTLogBulkWrite(PRTLOGGER pLogger, const char *pszBefore, const char *pch, size_t cch, const char *pszAfter);
2625
2626/**
2627 * Write/copy bulk log data from a nested VM logger.
2628 *
2629 * This is used for
2630 *
2631 * @returns IRPT status code.
2632 * @param pLogger The logger instance (NULL for default logger).
2633 * @param pch Pointer to the block of bulk log text to write.
2634 * @param cch Size of the block of bulk log text to write.
2635 * @param pszInfix String to put after the line prefixes and the
2636 * line content.
2637 */
2638RTDECL(int) RTLogBulkNestedWrite(PRTLOGGER pLogger, const char *pch, size_t cch, const char *pszInfix);
2639
2640/**
2641 * Flushes the specified logger.
2642 *
2643 * @returns IRPT status code.
2644 * @param pLogger The logger instance to flush.
2645 * If NULL the default instance is used. The default instance
2646 * will not be initialized by this call.
2647 */
2648RTDECL(int) RTLogFlush(PRTLOGGER pLogger);
2649
2650/**
2651 * Write to a logger instance.
2652 *
2653 * @param pLogger Pointer to logger instance.
2654 * @param pvCallerRet Ignored.
2655 * @param pszFormat Format string.
2656 * @param ... Format arguments.
2657 */
2658RTDECL(void) RTLogLogger(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
2659
2660/**
2661 * Write to a logger instance, weak version.
2662 *
2663 * @param pLogger Pointer to logger instance.
2664 * @param pvCallerRet Ignored.
2665 * @param pszFormat Format string.
2666 * @param ... Format arguments.
2667 */
2668#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2669RTDECL(void) RTLogLoggerWeak(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
2670#else /* Cannot use a DECL_FORCE_INLINE because older GCC versions doesn't support inlining va_start. */
2671# undef RTLogLoggerWeak /* in case of mangling */
2672# define RTLogLoggerWeak RTLogLogger
2673#endif
2674
2675/**
2676 * Write to a logger instance.
2677 *
2678 * @param pLogger Pointer to logger instance.
2679 * @param pszFormat Format string.
2680 * @param args Format arguments.
2681 */
2682RTDECL(void) RTLogLoggerV(PRTLOGGER pLogger, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(2, 0);
2683
2684/**
2685 * Write to a logger instance.
2686 *
2687 * This function will check whether the instance, group and flags makes up a
2688 * logging kind which is currently enabled before writing anything to the log.
2689 *
2690 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
2691 * @param fFlags The logging flags.
2692 * @param iGroup The group.
2693 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2694 * only for internal usage!
2695 * @param pszFormat Format string.
2696 * @param ... Format arguments.
2697 * @remark This is a worker function of LogIt.
2698 */
2699RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2700 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
2701
2702/**
2703 * Write to a logger instance, weak version.
2704 *
2705 * This function will check whether the instance, group and flags makes up a
2706 * logging kind which is currently enabled before writing anything to the log.
2707 *
2708 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
2709 * @param fFlags The logging flags.
2710 * @param iGroup The group.
2711 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2712 * only for internal usage!
2713 * @param pszFormat Format string.
2714 * @param ... Format arguments.
2715 * @remark This is a worker function of LogIt.
2716 */
2717#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2718RTDECL(void) RTLogLoggerExWeak(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2719 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5);
2720#else /* Cannot use a DECL_FORCE_INLINE because older GCC versions doesn't support inlining va_start. */
2721# undef RTLogLoggerExWeak /* in case of mangling */
2722# define RTLogLoggerExWeak RTLogLoggerEx
2723#endif
2724
2725/**
2726 * Write to a logger instance.
2727 *
2728 * This function will check whether the instance, group and flags makes up a
2729 * logging kind which is currently enabled before writing anything to the log.
2730 *
2731 * @returns VINF_SUCCESS, VINF_LOG_NO_LOGGER, VINF_LOG_DISABLED, or IPRT error
2732 * status.
2733 * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
2734 * @param fFlags The logging flags.
2735 * @param iGroup The group.
2736 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
2737 * only for internal usage!
2738 * @param pszFormat Format string.
2739 * @param args Format arguments.
2740 */
2741RTDECL(int) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2742 const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(4, 0);
2743
2744/** @copydoc RTLogLoggerExV */
2745typedef DECLCALLBACKTYPE(int, FNRTLOGLOGGEREXV,(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2746 const char *pszFormat, va_list args)) RT_IPRT_FORMAT_ATTR(4, 0);
2747/** Pointer to RTLogLoggerExV. */
2748typedef FNRTLOGLOGGEREXV *PFNRTLOGLOGGEREXV;
2749/** "Weak symbol" emulation for RTLogLoggerExV.
2750 * @note This is first set when RTLogCreateEx or RTLogCreate is called. */
2751extern RTDATADECL(PFNRTLOGLOGGEREXV) g_pfnRTLogLoggerExV;
2752
2753/** "Weak symbol" wrapper for RTLogLoggerExV. */
2754DECL_FORCE_INLINE(int) RTLogLoggerExVWeak(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup,
2755 const char *pszFormat, va_list args) /* RT_IPRT_FORMAT_ATTR(4, 0) */
2756{
2757#if defined(IN_RING3) && (defined(IN_RT_STATIC) || defined(IPRT_NO_CRT))
2758 if (g_pfnRTLogLoggerExV)
2759 return g_pfnRTLogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args);
2760 return 22301; /* VINF_LOG_DISABLED, don't want err.h dependency here. */
2761#else
2762 return RTLogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args);
2763#endif
2764}
2765
2766/**
2767 * printf like function for writing to the default log.
2768 *
2769 * @param pszFormat Printf like format string.
2770 * @param ... Optional arguments as specified in pszFormat.
2771 *
2772 * @remark The API doesn't support formatting of floating point numbers at the moment.
2773 */
2774RTDECL(void) RTLogPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2775
2776/**
2777 * vprintf like function for writing to the default log.
2778 *
2779 * @param pszFormat Printf like format string.
2780 * @param va Optional arguments as specified in pszFormat.
2781 *
2782 * @remark The API doesn't support formatting of floating point numbers at the moment.
2783 */
2784RTDECL(void) RTLogPrintfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
2785
2786/**
2787 * Dumper vprintf-like function outputting to a logger.
2788 *
2789 * @param pvUser Pointer to the logger instance to use, NULL for default
2790 * instance.
2791 * @param pszFormat Format string.
2792 * @param va Format arguments.
2793 */
2794RTDECL(void) RTLogDumpPrintfV(void *pvUser, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
2795
2796/**
2797 * Used for logging assertions, debug and release log as appropriate.
2798 *
2799 * Implies flushing.
2800 *
2801 * @param pszFormat Format string.
2802 * @param ... Format arguments.
2803 */
2804typedef DECLCALLBACKTYPE(void, FNRTLOGASSERTION,(const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(1, 2);
2805/** Pointer to an assertion logger, ellipsis variant. */
2806typedef FNRTLOGASSERTION *PFNRTLOGASSERTION;
2807
2808/**
2809 * Used for logging assertions, debug and release log as appropriate.
2810 *
2811 * Implies flushing.
2812 *
2813 * @param pszFormat Format string.
2814 * @param va Format arguments.
2815 */
2816typedef DECLCALLBACKTYPE(void, FNRTLOGASSERTIONV,(const char *pszFormat, va_list va)) RT_IPRT_FORMAT_ATTR(1, 0);
2817/** Pointer to an assertion logger, va_list variant. */
2818typedef FNRTLOGASSERTIONV *PFNRTLOGASSERTIONV;
2819
2820/** @copydoc FNRTLOGASSERTION */
2821RTDECL(void) RTLogAssert(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2822/** @copydoc FNRTLOGASSERTIONV */
2823RTDECL(void) RTLogAssertV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
2824
2825/** "Weak symbol" emulation for RTLogAssert. */
2826extern RTDATADECL(PFNRTLOGASSERTION) g_pfnRTLogAssert;
2827/** "Weak symbol" emulation for RTLogAssertV. */
2828extern RTDATADECL(PFNRTLOGASSERTIONV) g_pfnRTLogAssertV;
2829
2830
2831#ifndef DECLARED_FNRTSTROUTPUT /* duplicated in iprt/string.h & iprt/errcore.h */
2832#define DECLARED_FNRTSTROUTPUT
2833/**
2834 * Output callback.
2835 *
2836 * @returns number of bytes written.
2837 * @param pvArg User argument.
2838 * @param pachChars Pointer to an array of utf-8 characters.
2839 * @param cbChars Number of bytes in the character array pointed to by pachChars.
2840 */
2841typedef DECLCALLBACKTYPE(size_t, FNRTSTROUTPUT,(void *pvArg, const char *pachChars, size_t cbChars));
2842/** Pointer to callback function. */
2843typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
2844#endif
2845
2846/**
2847 * Partial vsprintf worker implementation.
2848 *
2849 * @returns number of bytes formatted.
2850 * @param pfnOutput Output worker.
2851 * Called in two ways. Normally with a string an it's length.
2852 * For termination, it's called with NULL for string, 0 for length.
2853 * @param pvArg Argument to output worker.
2854 * @param pszFormat Format string.
2855 * @param args Argument list.
2856 */
2857RTDECL(size_t) RTLogFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArg, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(3, 0);
2858
2859/**
2860 * Write log buffer to COM port.
2861 *
2862 * @param pach Pointer to the buffer to write.
2863 * @param cb Number of bytes to write.
2864 */
2865RTDECL(void) RTLogWriteCom(const char *pach, size_t cb);
2866
2867/**
2868 * Prints a formatted string to the serial port used for logging.
2869 *
2870 * @returns Number of bytes written.
2871 * @param pszFormat Format string.
2872 * @param ... Optional arguments specified in the format string.
2873 */
2874RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2875
2876/**
2877 * Prints a formatted string to the serial port used for logging.
2878 *
2879 * @returns Number of bytes written.
2880 * @param pszFormat Format string.
2881 * @param args Optional arguments specified in the format string.
2882 */
2883RTDECL(size_t) RTLogComPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
2884
2885/**
2886 * Write log buffer to a debugger (RTLOGDEST_DEBUGGER).
2887 *
2888 * @param pach What to write.
2889 * @param cb How much to write.
2890 * @remark When linking statically, this function can be replaced by defining your own.
2891 */
2892RTDECL(void) RTLogWriteDebugger(const char *pach, size_t cb);
2893
2894/**
2895 * Write log buffer to a user defined output stream (RTLOGDEST_USER).
2896 *
2897 * @param pach What to write.
2898 * @param cb How much to write.
2899 * @remark When linking statically, this function can be replaced by defining your own.
2900 */
2901RTDECL(void) RTLogWriteUser(const char *pach, size_t cb);
2902
2903/**
2904 * Write log buffer to a parent VMM (hypervisor).
2905 *
2906 * @param pach What to write.
2907 * @param cb How much to write.
2908 * @param fRelease Set if targeting the release log, clear if debug log.
2909 *
2910 * @note Currently only available on AMD64 and x86.
2911 */
2912RTDECL(void) RTLogWriteVmm(const char *pach, size_t cb, bool fRelease);
2913
2914/**
2915 * Write log buffer to stdout (RTLOGDEST_STDOUT).
2916 *
2917 * @param pach What to write.
2918 * @param cb How much to write.
2919 * @remark When linking statically, this function can be replaced by defining your own.
2920 */
2921RTDECL(void) RTLogWriteStdOut(const char *pach, size_t cb);
2922
2923/**
2924 * Write log buffer to stdout (RTLOGDEST_STDERR).
2925 *
2926 * @param pach What to write.
2927 * @param cb How much to write.
2928 * @remark When linking statically, this function can be replaced by defining your own.
2929 */
2930RTDECL(void) RTLogWriteStdErr(const char *pach, size_t cb);
2931
2932#ifdef VBOX
2933
2934/**
2935 * Prints a formatted string to the backdoor port.
2936 *
2937 * @returns Number of bytes written.
2938 * @param pszFormat Format string.
2939 * @param ... Optional arguments specified in the format string.
2940 */
2941RTDECL(size_t) RTLogBackdoorPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
2942
2943/**
2944 * Prints a formatted string to the backdoor port.
2945 *
2946 * @returns Number of bytes written.
2947 * @param pszFormat Format string.
2948 * @param args Optional arguments specified in the format string.
2949 */
2950RTDECL(size_t) RTLogBackdoorPrintfV(const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(1, 0);
2951
2952#endif /* VBOX */
2953
2954RT_C_DECLS_END
2955
2956/** @} */
2957
2958#endif /* !IPRT_INCLUDED_log_h */
2959
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