/* * (c) Copyright 2003-2024, Real-Time Innovations, Inc. All rights reserved. * All rights reserved. * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef advlog_logger_h #define advlog_logger_h #include #include #ifndef osapi_thread_h #include "osapi/osapi_thread.h" #endif #ifndef reda_worker_h #include "reda/reda_worker.h" #endif #include "advlog/advlog_dll.h" #ifndef log_common_h #include "log/log_common.h" #endif #ifndef clock_interface_h #include "clock/clock_interface.h" #endif #ifdef __cplusplus extern "C" { #endif /*e \defgroup ADVLOGLoggerModule Logger * \ingroup AdvLogModule * * @brief Module that configures the RTILog infrastructure to log * messages. * * The Logger module is responsible for installing 'log' functions * into RTI's Logging API. It should be possible to re-direct the logging * done by any threads in the process to come out into a file, memory region, * a user-specified function, or a combination of the above. * * This module offers generic services and API's, most fundamentally the * LoggerDevice API. This is a "plug-in" API that can be used * to install "logging devices" which are the actual implementations that * handle the logging messages. * * This module also provides some "built-in devices" that actually implement * the behaviors (write to file, memory, etc.) stated earlier. * * This module is flexible in that additional "user devices" can be installed * and mixed with the built-in devices up to a total of * ADVLOG_LOGGER_MAX_DEVICES which can be all simultaneously getting the * output messages. The relative order in the output is sent to each device is * also configurable. The built-in devices have a 'fixed' order defined by the * LoggerBuiltinSlotValues, but the user-devices can pick any of the * remaining slots and be placed anywhere relative to the built-in devices. * * IMPORTANT IMPLEMENTATION NOTE: * To avoid infinite recursions any functions that are called as a result of * a log message should themselves never attempt to write any log messages. * The infinite loop can occur if say when writing a log message the Logging * infrastructure encounters some resource limit or fails to acquire a * resource and tries to log this error. * * Initially Gerardo tried to do this by introducing a stereotype * <> that identifies these functions and also adding * the suffix "LNP" to make it clear programmatically as well. These * functions would be subject to the following restrictions: * * (a) they cannot call any logging functions * * (b) They can only call other functions that also have stereotype * <> (this is because (a) really applies to the * transitive closure of all the functions that are called. * * However it was not possible to implement this as: * * (a) the functions need to * call other functions (like REDAWorker_get) that had no idea of this and * moreover the actual device callbacks being user code or invoking the * TCP layer may also have this problem. * * (b) the same functions sometimes are called from the logging function * and are also called from some other functions. We could duplicate * this code but it would seem unwise. * * So a 'defensive' mechanism that * uses additional thread-specific storage had to be added. Now only * the 'entrypoint' to the logging is marked with the stereotype and it * uses the protection before calling any functions. The functions within * the infrastructure that are called in that chain are given an additional * parameter ( RTIBool isLoggingBlocked ) that tells them that logging * is blocked so there is no point in trying as it would end up in a * recursive call that would be terminated and produce no output. * * For the functions that would *always* be called with the * isLoggingBlocked==TRUE we introduce the stereotype <> and * name it with the suffix "LNOOP" to avoid writing code that is never * executed. * * USAGE: * The pseudo-code below illustrates the use of this module: * * // Define devices * struct ADVLOGLoggerDeviceMyDevice { * struct ADVLOGLoggerDevice base; * // Add additional information to teh device * int myValue; * } * * void ADVLOGLoggerDeviceMyDevice_write( * struct ADVLOGLoggerDevice *device; * struct REDAWorker *worker, * const char *msg ) * { * struct ADVLOGLoggerDeviceMyDevice *myDevice = * (struct ADVLOGLoggerDeviceMyDevice *)device * // do as needed * // can also use the worker to enter exclusive areas, etc. * ... * } * * void ADVLOGLoggerDeviceMyDevice_close( * struct ADVLOGLoggerDevice *device; * struct REDAWorker *worker) * { * struct ADVLOGLoggerDeviceMyDevice *myDevice = * (struct ADVLOGLoggerDeviceMyDevice *)device * // do as needed * // can also use the worker to enter exclusive areas, etc. * ... * } * * // MAIN CODE * ADVLOGLogger_init( ); * * // Create the device * struct ADVLOGLoggerDeviceMyDevice *myDevice = * (struct ADVLOGLoggerDeviceMyDevice *)malloc(myDevice); * * // Initilize the device * myDevice->writeFnc = ADVLOGLoggerDeviceMyDevice_write; * myDevice->readFnc = ADVLOGLoggerDeviceMyDevice_read; * myDevice->myValue = ...; * * // Install the device * ADVLOGLogger_setDevice(, myDevice, ); * * // if installed as thread-specific, optionally indcate that it must chain to * // global logger * ADVLOGLogger_setThreadLogAlsoToGlobal(RTI_TRUE); * * // ANY OTHER CODE * ... when using the RTILog API it will route the messages to * ADVLOGLoggerDeviceMyDevice_write() * * // Prior to destroying the tread installed the device, the * // application must call * ADVLOGLogger_closeAllThreadLoggers(); * * // This will cause the ADVLOGLoggerDeviceMyDevice_close() to * // be called. * * WARNING: The close semantics need some thinking!! */ struct ADVLOGMessageInfo; /*e \ingroup ADVLOGLoggerModule * The number of different kinds of devices */ #define ADVLOG_NUM_BUILTIN_DEVICE_KINDS (6) /*e \ingroup ADVLOGLoggerModule * The maximum number of installed devices */ #define ADVLOG_LOGGER_MAX_DEVICES (10) #define ADVLOG_LOGGER_MESSAGE_COUNT_MAX 10 /* max number of errors or warnings stored in the queue*/ /* Max number of pointers to function name stored in the queue */ #define ADVLOG_LOGGER_FUNCTION_HISTORY_COUNT_MAX 20 /* * Max length for category section of log message is number of categories * * the max string length of the category names (plus one for a comma), * plus the padding needed to add the LC label and additional separators * ("LC:" + the closing "]" or "|" + the null terminator). */ #define ADVLOG_CATEGORY_FORMAT_LENGTH \ (RTI_LOG_NUM_CATEGORY_MASKS * (RTI_LOG_CATEGORY_LABEL_MAX_LENGTH + 1)) + 5 /*e * \ingroup ADVLOGLoggerModule * Pre-defined slots for the dispatcher * * ADVLOG_LOGGER_SLOT_MEMORY (circular memory buffer) * ADVLOG_LOGGER_SLOT_FILE (potentially a multiplicity) * ADVLOG_LOGGER_SLOT_MONITORING (used by the Monitoring Library Logging) * ADVLOG_LOGGER_SLOT_STDIO (Uses the OS-dependant function provided by * RTILog) * ADVLOG_LOGGER_SLOT_FILE_SET (User-level device: used for redirect the * output to a set of files) * ADVLOG_LOGGER_SLOT_USER (User-level device) * * NOTE: The number of each slot determines its precedence since devices * are executed in the order of the slot numbers (low to high). * Slots 0, 2, 4, and 6 are free just in case the user of this module wants * to add a device with a precedence between any of the already existing * built-in slots. */ typedef enum { /* * WARNING: any changes to this must be reflected in * ADVLOG_NUM_BUILTIN_DEVICE_KINDS */ ADVLOG_LOGGER_SLOT_MEMORY = 1, ADVLOG_LOGGER_SLOT_FILE = 3, ADVLOG_LOGGER_SLOT_MONITORING = 5, ADVLOG_LOGGER_SLOT_STDIO = 7, ADVLOG_LOGGER_SLOT_FILE_SET = 8, ADVLOG_LOGGER_SLOT_USER = 9 /* * WARNING: any changes to this must be reflected in * ADVLOG_NUM_BUILTIN_DEVICE_KINDS */ } ADVLOGLoggerBuiltinSlotValues; struct ADVLOGLoggerDevice; /*e \ingroup ADVLOGLoggerModule * * @brief A ADVLOGLoggerDevice write function. */ typedef void (*ADVLOGLoggerDeviceWriteFnc)( struct ADVLOGLoggerDevice *device, struct REDAWorker *worker, const struct ADVLOGMessageInfo *msg); /*e \ingroup ADVLOGLoggerModule * * @brief A ADVLOGLoggerDevice close function. */ typedef void (*ADVLOGLoggerDeviceCloseFnc)( struct ADVLOGLoggerDevice *device, struct REDAWorker *worker); /*e \ingroup ADVLOGLoggerModule * * @brief Device interface. Used for the user-defined devices. * * The interface defined by the functions in this structure must be * implemented by anybody that wishes to install a logging device. */ struct ADVLOGLoggerDevice { /*e Identify device. Number below 100 are reserved for built-in devices.*/ int deviceKind; /*e Write a logged message to this device.*/ ADVLOGLoggerDeviceWriteFnc writeFnc; /*e Close this device.*/ ADVLOGLoggerDeviceCloseFnc closeFnc; }; /* Forward declaration */ struct ADVLOGWorkerProvider; /*e \ingroup ADVLOGLoggerModule * * @brief Get the worker associated with the calling thread. */ typedef struct REDAWorker *(*ADVLOGWorkerProvider_GetWorkerFunction)( struct ADVLOGWorkerProvider *self); /*e \ingroup ADVLOGLoggerModule * * @brief Create a worker. * Note: This API does not associate the worker to the current thread. */ typedef struct REDAWorker * (*ADVLOGWorkerProvider_CreateWorkerFunction)( struct ADVLOGWorkerProvider *self, const char *name); /*e \ingroup ADVLOGLoggerModule * * @brief Destroy a worker associated with the calling thread. */ typedef void (*ADVLOGWorkerProvider_DestroyWorkerFunction)( struct ADVLOGWorkerProvider *self, struct REDAWorker *worker); /*e \ingroup ADVLOGLoggerModule * * @brief Store reference to a worker associated with the calling thread. */ typedef void (*ADVLOGWorkerProvider_AssociateWorkerFunction)( struct ADVLOGWorkerProvider *self, struct REDAWorker *worker); /*e \ingroup ADVLOGLoggerModule * * @brief An object capable of getting the worker associated with a * particular thread. * * The RTILib logging framework, on which this module is built, is * independent of the worker abstraction. Therefore, when a logging callback * arrives, a mechanism is needed to map from the calling thread to a worker. * That task is performed by an object of this type, which is provided by * the user of this module. The policy to be used is not specified by this * module. * * However, one limitation applies: the implementor of this type must take * care that accesses to the data pointer are thread-safe. The object cannot * be effectively protected by this module because when the * ADVLOGWorkerProvider is invoked, there is not yet a worker. */ struct ADVLOGWorkerProvider { ADVLOGWorkerProvider_GetWorkerFunction getWorker; ADVLOGWorkerProvider_CreateWorkerFunction createWorker; ADVLOGWorkerProvider_DestroyWorkerFunction destroyWorker; ADVLOGWorkerProvider_AssociateWorkerFunction associateWorker; void *data; }; /*e * \ingroup ADVLOGLoggerModule * @brief An object storing the information of the log messages generated. * message - the message string. * logLevel - the log level associated with the log message. * moduleId - the number associated with the module that generated the * log message. * messageId - the number associated with the log message. * timestamp - the time when the message was logged. * facility - according to the syslog definition, a number that identifies * a process. In RTI Connext, it will identify the source of * the message: user, security, middleware, or service. */ struct ADVLOGMessageInfo { char message[RTI_LOG_MSG_SIZE_MAX]; RTILogLevel logLevel; RTI_UINT32 moduleId; RTI_UINT32 messageId; RTINtpTime timestamp; RTILogFacility facility; }; /* ------------------------------------------------------------------------ * Public Methods * ------------------------------------------------------------------------ */ /*e \ingroup ADVLOGLoggerModule * * @brief This operation pre-initializes the ADVLOGLogger infrastructure * before global resources are available. * * This function can be called prior to init in order to allow some pre- * configuration of _global_ ADVLOG devices before it is activated. Note * that ADVLOG can only be cleanly finalized after a full init. * * @return RTI_TRUE on success. RTI_FALSE if already initialized or failed * to allocate resources. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_preinit(void); /*e \ingroup ADVLOGLoggerModule * @brief This operation finalizes the ADVLOGLogger infrastructure * before global resources are available. */ extern ADVLOGDllExport void ADVLOGLogger_finalize_preinit(struct REDAWorker * worker); /*e \ingroup ADVLOGLoggerModule * * @brief This operation initializes the ADVLOGLogger infrastructure * it must be called before any other calls to the ADVLOGLogger * API's. * * The init function must be passed the \em same workerFactory that * is used by the rest of NDDS. This is very important otherwise * functions installed into the symbol table of the ADVLOGServer * will not be able to safely call the internal NDDS API's i.e. * they will not be able to call any functions in the NDDS core that * expects a worker (as all workers passed to a function * must come from the same WorkerFactory [[GPC: this statement * must be verified but even if it was false it would still be * safer to share the worker factory]]. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_init( struct REDAWorkerFactory *workerFactory, struct ADVLOGWorkerProvider *workerProvider, struct RTIClock *timestampClock, RTIOsapiThreadTssFactory * tssFactory); /*e \ingroup ADVLOGLoggerModule * * @brief install onMessage callback */ extern ADVLOGDllExport RTIBool ADVLOGLogger_install(void); /*e \ingroup ADVLOGLoggerModule * * @brief uninstall onMessage callback */ extern ADVLOGDllExport RTIBool ADVLOGLogger_uninstall(void); /*e \ingroup ADVLOGLoggerModule * * @brief cleanup ADVLOGLogger * * @param worker The worker associated with the calling thread. It will be used * for taking any EAs required for destroying objectPerWorker instances. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_finalize(struct REDAWorker * worker); /*e * \ingroup ADVLOGLoggerModule * * @brief Remove STDIO and File devices if installed. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_resetStdioAndFileDevice(void); /*e * \ingroup ADVLOGLoggerModule * * @brief Sets a logging device at a specific slot value. * * If there is a device at that slot value, this new device will * replace the old device. * * If there was no device, then the new device will be inserted * in the right place based on slot number. * * The function may fail if either the device list cannot be obtained, * indicating some resource limit, or else if there are already * more than the allowed maximum devices in the device list. * * @param slot the slot number where to place the device. Slot numbers * are used to identify each device (so they can be replaced) and also * to indicate precedence of execution. The devices are executed in the * order of the slot numbers (low to high). The slot number must be * non-negative, otherwise the function will fail. * * @param device the new logger to place at the slot number. The special * value device==NULL indicates that the device at that slot (if * present) should be removed. * * @param workerSpecific indicates whether the device should be * placed in the worker-specific device list or on the global one * RTI_TRUE => worker-specific */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setDevice( int slot, struct ADVLOGLoggerDevice *device, struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Gets a non-worker-specific logging device at a specific slot value. * * @param slot the slot number of the desired device */ extern ADVLOGDllExport struct ADVLOGLoggerDevice *ADVLOGLogger_getDevice(int slot); /*e \ingroup ADVLOGLoggerModule * * @brief Gets print mask configuration of the Logger of the most * common log level (RTI_LOG_LEVEL_ERROR). * * @param workerSpecific indicates whether the retrieved mask should be * from the worker-specific device manager or the global one (default) * RTI_TRUE => worker-specific */ extern ADVLOGDllExport RTILogPrintFormatKindMask ADVLOGLogger_getPrintMask( struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Get print mask configuration of the Logger by log level. * * @param logLevel. The log level for the print mask. * @param worker. * @param workerSpecific indicates whether the retrieved mask should be * from the worker-specific device manager or the global one (default) * RTI_TRUE => worker-specific */ extern ADVLOGDllExport RTILogPrintFormatKindMask ADVLOGLogger_getPrintMaskByLogLevel( RTILogLevel logLevel, struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Sets print mask configuration of the Logger for all the log levels, * except for (RTI_LOG_LEVEL_FATAL_ERROR). * * @param mask the new mask * * @param workerSpecific indicates whether the modified mask should be * placed in the worker-specific device manager or the global one (default) * RTI_TRUE => worker-specific */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setPrintMask( RTILogPrintFormatKindMask mask, struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Sets print mask configuration of the Logger by log level. * * @param mask. The new mask for the log level. * @param logLevel. The log level for the print mask. * @param worker. * @param workerSpecific indicates whether the modified mask should be * placed in the worker device manager or the global one (default). */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setPrintMaskByLogLevel( RTILogPrintFormatKindMask mask, RTILogLevel logLevel, struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Sets the built-in File logger-device * * The built-in FILE-logger-device is always installed at slot * ADVLOG_LOGGER_SLOT_FILE */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setDeviceBuiltinFile( FILE *file, RTI_UINT32 maxCapacity, struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Sets the built-in Memmory logger-device * * The built-in MEMORY-logger-device is always installed at slot * ADVLOG_LOGGER_SLOT_MEMORY */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setDeviceBuiltinMemory( char *buffer, RTI_UINT32 maxCapacity, struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Sets the built-in STDIO logger-device * * The built-in STDIO-logger-device is always installed at slot * ADVLOG_LOGGER_SLOT_STDIO */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setDeviceBuiltinStdio( struct REDAWorker *worker, RTIBool workerSpecific); /*e \ingroup ADVLOGLoggerModule * * @brief Writes the thread-specific logging messages also to the * 'global' process logger. * * This operation can be used if the calling thread has installed * a thread-specific logger. If this operation is called then * the thread-specific logger will be chained to the 'global' * (i.e. non-thread-specific) logger. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_setThreadLogAlsoToGlobal( struct REDAWorker *worker, RTIBool sendAlsoToGlobal); /*e \ingroup ADVLOGLoggerModule * * @brief Take the read lock. * * Returns false on failure. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_takeLockForReading(void); /*e \ingroup ADVLOGLoggerModule * * @brief Give the read lock. * * Returns false on failure. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_giveLockForReading(void); /*e \ingroup ADVLOGLoggerModule * * @brief Take the write lock. * * Returns false on failure. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_takeLockForWriting(void); /*e \ingroup ADVLOGLoggerModule * * @brief Give the write lock. * * Returns false on failure. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_giveLockForWriting(void); /*e Define bits used by RTILOG * @brief non-ADVLOG print bit mask */ #define ADVLOG_PRINT_MASK_RTILOG 0xf00000ff /*e Define bits used by ADVLOG * @brief ADVLOG-only print bit mask */ #define ADVLOG_PRINT_MASK 0xf000ff00 /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Print a timestamp */ #define ADVLOG_PRINT_BIT_TIMESTAMP 0x100 /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Print thread ID */ #define ADVLOG_PRINT_BIT_THREAD_ID 0x200 /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Print the context stack state */ #define ADVLOG_PRINT_BIT_ACTIVITY_CONTEXT 0x400 /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Print in two lines */ #define ADVLOG_PRINT_BIT_TWO_LINES 0x800 /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Print the context category */ #define ADVLOG_PRINT_BIT_CATEGORY 0x1000 /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Print the severity of the message */ #define ADVLOG_PRINT_BIT_LOG_LEVEL RTI_LOG_PRINT_BIT_LOG_LEVEL /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief Default ADVLOG print mask */ #define ADVLOG_PRINT_MASK_DEFAULT \ (ADVLOG_PRINT_BIT_ACTIVITY_CONTEXT | ADVLOG_PRINT_BIT_LOG_LEVEL) /* \ingroup ADVLOGLoggerPrintBitmapClass * @brief ADVLOG print mask value to force use of global default */ #define ADVLOG_PRINT_MASK_USE_DEFAULT RTI_LOG_PRINT_COMMON_BIT_USE_DEFAULT /*e \ingroup ADVLOGLoggerModule * @brief register a worker to be associated with the current thread */ extern ADVLOGDllExport RTIBool ADVLOGLogger_associateWorkerWithCurrentThread(void *worker); /*i \ingroup ADVLOGLoggerModule * * @brief ADVLOG version of printContextAndMsg [NOT YET IMPLEMENTED] * * If worker is NULL, it will be looked up; this is functionally equivalent * to calling the RTILog version of this function when ADVLOG is installed. * If ADVLOG has not yet been initialized, the call is passed to RTILog. */ Peer ADVLOGDllExport RTIBool ADVLOGLogger_printContextAndMsg( struct REDAWorker *worker, const char *context, const struct RTILogMessage *errMsg, ...); /*i \ingroup ADVLOGLoggerModule * @brief ADVLOG version of printLocationContextAndMsg [NOT YET IMPLEMENTED] * * If worker is NULL, it will be looked up; this is functionally equivalent * to calling the RTILog version of this function when ADVLOG is installed. * * If ADVLOG has not yet been initialized, the call is passed to RTILog. */ Peer ADVLOGDllExport RTIBool ADVLOGLogger_printLocationContextAndMsg( struct REDAWorker *worker, RTI_UINT32 module, const char *filename, const char *method, RTI_UINT32 lineno, const struct RTILogMessage *errMsg, ...); /*e \ingroup ADVLOGLoggerModule * @brief This method will return the last n error or warning messages or * simply calculate the amount of space needed to hold the last n error * messages. * * If worker is NULL, it will be looked up. * * If stackMessage is NULL then the length will be calculated and returned in * len. Otherwise, stackMessage will be populated with the last n error or * warning messages, each on their own line, with increasing indentation. * * If stackMessage is NULL, len will be returned with the length needed to store * the last n error or warning messages. Otherwise, len should equal the amount * of available space and the actual length of the string will be returned in * the size parameter. * * If ADVLOG has not yet been initialized, the call will fail. */ extern ADVLOGDllExport void ADVLOGLogger_getLastErrorMessages( struct REDAWorker *worker, char* stackMessage, RTI_INT32 *size); /* The messageInfos for errors and warning are stored in the * logger as a circular queue. The circular queue is implemented * on top of an array of messageInfo structure. Whenever a new * error/warning is encountered the start index of the array is * advanced and the information about the error or the warning * is then stored in the location pointed by the start index. */ /*e \ingroup ADVLOGLoggerModule * @brief This method will clear the ADVLOGMessageInfo queue * associated with the worker. * * If worker is NULL, it will be looked up. * * If ADVLOG has not yet been initialized, the call will fail. */ extern ADVLOGDllExport void ADVLOGLogger_emptyMessageInfoQueue(struct REDAWorker *worker); /*i \ingroup ADVLOGLoggerModule * @brief This method changes the clock used by the logger to get the timestamp * for the log messages. * @param clock The clock to be used by the logger. * @mtsafety This method is not thread safe. However, assigning a pointer should * be an atomic operation. */ extern ADVLOGDllExport void ADVLOGLogger_setClock(struct RTIClock *clock); extern ADVLOGDllExport struct REDAWorker* ADVLOGLogger_getWorker(void); /*e \ingroup ADVLOGLoggerModule * @brief Uses ADVLOGLogger_getWorker() to get the worker and prints all the EAs * that worker is currently in. */ extern ADVLOGDllExport void ADVLOGLogger_printWorkerExclusiveAreas(void); extern ADVLOGDllExport struct REDAWorker * ADVLOGLogger_createWorker(const char *name); extern ADVLOGDllExport void ADVLOGLogger_destroyWorker(void *worker); /*e \ingroup ADVLOGLoggerModule * @brief Enable: * - Save a pointer to the method name in a queue everytime a precondition * is called using "ADVLOGLogger_addToFunctionHistory" * - Log the function history when is requiered using * "ADVLOGLogger_logFunctionHistory" * * @return RTI_TRUE on success. * RTI_FALSE on failure enabling the Function History feature. */ extern ADVLOGDllExport RTIBool ADVLOGLogger_enableFunctionHistory(void); /*e \ingroup ADVLOGLoggerModule * Disable: * - Save a pointer to the method name in a queue everytime a precondition * is called using "ADVLOGLogger_addToFunctionHistory" * - Log the function history when is requiered using * "ADVLOGLogger_logFunctionHistory" */ extern ADVLOGDllExport void ADVLOGLogger_disableFunctionHistorySupport(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* advlog_logger_h */