// Copyright 2020 Siemens Digital Industries Software // ================================================== // Copyright 2011. // Siemens Product Lifecycle Management Software Inc. // All Rights Reserved. // ================================================== // Copyright 2020 Siemens Digital Industries Software /** @file Logger.hxx Defines a facility to write messages to the Teamcenter system log file (syslog). It maintains a hierarchical tree of named loggers with distinct logging priority levels.
When a log message is issued by the caller, the message is written to the log file if the priority level of the message is at least the level of the logger. Example
        std::string str("Teamcenter.MyComponent.MyCode");
        Logger *logger = Logger::getLogger(str);
        if (logger->isErrorEnabled())
        {
            logger->error("Could not read the configuration file");
        }
    
Configuration
Loggers are configured upon startup by a file named logger.properties in the TC_DATA directory or in a directory defined by the TC_LOGGER_CONFIGURATION environment variable. Each line of the file is of the form: logging.logger.<hierarchical_logger_name>=<level>
If a logger does not have a specific priority level configured, it inherits its parent's level. Example
    logging.logger.Teamcenter=INFO
    logging.logger.Teamcenter.SOA=INFO
    logging.logger.Teamcenter.SOA.Gateway=TRACE
    
In production, loggers should usually be configured to INFO priority level.
For additional detail and diagonostics, loggers may be configured to DEBUG or TRACE priority level. A logger can be configured to write no messages by setting the priority level to OFF. In a Teamcenter J2EE Middle Tier environment, the administrator can change the priority level of a Teamcenter session's loggers dynamically while the session is running. See the System Administration Guide for more information. Format Log messages are written in a fixed format with the following fields separated by dashes: Examples
    TRACE - 2010/10/15-22:07:29 UTC - ws010.40171.02.usr1.00008 - Something Happened. - Teamcenter.Logging.Sample at D:/workdir/dynalog/src/foundation/mld/cppunit/LoggerTestFixture.cxx(825)
    
Additionally, information about errors added to the error stack (error, error message and traceback) will also be printed to the logger if the priority level for "Teamcenter.MonitorDebug.mld" is set to @c LOG_INFO or lower, and if the environment variable @c TC_CATCH_THIS_IFAIL is set as follows: Call Stack Traces
To assist in development and debugging environments, a call stack trace is written for each high priority log message (fatal, error, warn). A maximum of 100 stack traces will be written in a session. **/ #ifndef TEAMCENTER_LOGGING_LOGGER_HXX #define TEAMCENTER_LOGGING_LOGGER_HXX #include #include #include #include #include // The string representation of the allowed appenders. #define APPENDER_SYSLOG_STR "syslog" #define APPENDER_STDOUT_STR "stdout" #define APPENDER_STDERR_STR "stderr" namespace Teamcenter { namespace Logging { class MLD_API Logger { public: friend class LoggerTree; friend class Node; /** * Log message priority levels */ enum level{LOG_TRACE=1,LOG_DEBUG=2,LOG_INFO=3,LOG_WARN=4,LOG_ERROR=5,LOG_FATAL=6,LOG_NOTE=7,LOG_OFF=8}; /** * Appender (The logging framework uses the word "appender" to declare the output destination.) */ enum appender{APPENDER_SYSLOG=0, APPENDER_STDOUT=1, APPENDER_STDERR=2}; /** * Get the logger name * * @return string returns the logger name */ std::string getLoggerName() const { return loggerName; }; /** * Set the log level for the logger. * * @param lvl The new log level for the logger. */ void setLogLevel(level lvl); /** * Return the log level set for the logger. * * @return level return the log level set for the logger. */ level getLogLevel() const { return logLevel; }; /** * Check whether log level trace is enabled * * @return boolean true if trace is enabled, false otherwise */ bool isTraceEnabled() const { return ( LOG_TRACE >= logLevel ); }; /** * Check whether log level debug is enabled * * @return boolean true if debug is enabled, false otherwise */ bool isDebugEnabled() const { return ( LOG_DEBUG >= logLevel ); }; /** * Check whether log level info is enabled * * @return boolean true if info is enabled, false otherwise */ bool isInfoEnabled() const { return ( LOG_INFO >= logLevel ); }; /** * Check whether log level warn is enabled * * @return boolean true if warn is enabled, false otherwise */ bool isWarnEnabled() const { return ( LOG_WARN >= logLevel ); }; /** * Check whether log level error is enabled * * @return boolean true if error is enabled, false otherwise */ bool isErrorEnabled() const { return ( LOG_ERROR >= logLevel ); }; /** * Check whether log level fatal is enabled * * @return boolean true if fatal is enabled, false otherwise */ bool isFatalEnabled() const { return ( LOG_FATAL >= logLevel ); }; /** * Log a fatal message. * * @param msg The message to log. */ void fatal(const std::string &msg) { log(LOG_FATAL, msg); }; /** * Log a fatal message. * * @param errorCode The error code. * @param msg The message to log. */ void fatal(const int errorCode, const std::string &msg) { log(LOG_FATAL, errorCode, msg); }; /** * Log a fatal message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode The error code. * @param msg The message to log. */ void fatal( const char* file, const int line, const int errorCode, const std::string &msg) { log(LOG_FATAL, file, line, errorCode, msg); }; /** * Log a fatal message, formatting the message with a printf-style * control string and variable arguments. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param errorCode The error code. * @param control_string The message control string. * @param ... Substitution arguments */ void fatal( const char* file, const int line, const int errorCode, const char* control_string, ... ); /** * Log an error message. * * @param msg The message to log. */ void error(const std::string &msg) { log(LOG_ERROR, msg); }; /** * Log an error message. * * @param errorCode The error code. * @param msg The message to log. */ void error(const int errorCode, const std::string &msg) { log(LOG_ERROR, errorCode, msg); }; /** * Log an error message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode The error code. * @param msg The message to log. */ void error( const char* file, const int line, const int errorCode, const std::string &msg) { log(LOG_ERROR, file, line, errorCode, msg); }; /** * Log an error message, formatting the message with a printf-style * control string and variable arguments. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param errorCode The error code. * @param control_string The message control string. * @param ... Substitution arguments */ void error( const char* file, const int line, const int errorCode, const char* control_string, ... ); /** * Log a warning message * * @param msg The message to log. */ void warn(const std::string &msg) { log(LOG_WARN, msg); }; /** * Log a warning message * * @param errorCode The error code. * @param msg The message to log. */ void warn(const int errorCode, const std::string &msg) { log(LOG_WARN, errorCode, msg); }; /** * Log a warn message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode The error code. * @param msg The message to log. */ void warn ( const char* file, const int line, const int errorCode, const std::string &msg) { log(LOG_WARN, file, line, errorCode, msg); }; /** * Log a warning message, formatting the message with a printf-style * control string and variable arguments. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param errorCode The error code. * @param control_string The message control string. * @param ... Substitution arguments */ void warn( const char* file, const int line, const int errorCode, const char* control_string, ... ); /** * Log an info message. * * @param msg The message to log. */ void info(const std::string &msg) { log(LOG_INFO, msg); }; /** * Log an info message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param msg The message to log. */ void info ( const char* file, const int line, const std::string &msg) { log(LOG_INFO, file, line, msg); }; /** * Log an info message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode A error or message code. * @param msg The message to log. */ void info ( const char* file, const int line, const int errorCode, const std::string &msg) { log(LOG_INFO, file, line, errorCode, msg); }; /** * Log an info message, formatting the message with a printf-style * control string and variable arguments. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param control_string The message control string. * @param ... Substitution arguments */ void info( const char* file, const int line, const char *control_string, ... ); /** * Log a debug message. * * @param msg The message to log. */ void debug(const std::string &msg) { log(LOG_DEBUG, msg); }; /** * Log a debug message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param msg The message to log. */ void debug( const char* file, const int line, const std::string &msg) { log(LOG_DEBUG, file, line, msg); }; /** * Log a debug message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode A error or message code. * @param msg The message to log. */ void debug ( const char* file, const int line, const int errorCode, const std::string &msg) { log(LOG_DEBUG, file, line, errorCode, msg); }; /** * Log a debug message, formatting the message with a printf-style * control string and variable arguments. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param control_string The message control string. * @param ... Substitution arguments */ void debug( const char* file, const int line, const char* control_string, ... ); /** * Log a trace message. * * @param msg The message to log. */ void trace(const std::string &msg) { log(LOG_TRACE, msg); }; /** * Log a trace message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param msg The message to log. */ void trace( const char* file, const int line, const std::string &msg) { log(LOG_TRACE, file, line, msg); }; /** * Log a trace message. * * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode A error or message code. * @param msg The message to log. */ void trace ( const char* file, const int line, const int errorCode, const std::string &msg) { log(LOG_TRACE, file, line, errorCode, msg); }; /** * Log a trace message, formatting the message with a printf-style * control string and variable arguments. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param control_string The message control string. * @param ... Substitution arguments */ void trace( const char* file, const int line, const char *control_string, ... ); /** * @deprecated #Teamcenter::Logging::Logger::note deprecated in Teamcenter 11.4. *
Use an appropriate logging level method: fatal, error, warn, info, debug, trace. * * Log a note message. * A note message is always written to the log file regardless * of the priority level setting of the logger. * * @param msg The message to log. */ TC_DEPRECATED_NO_REPLACEMENT( "11.4", "Teamcenter::Logging::Logger::note" ) void note(const std::string &msg) { log(LOG_NOTE, msg); }; /** * @deprecated #Teamcenter::Logging::Logger::note deprecated in Teamcenter 11.4. *
Use an appropriate logging level method: fatal, error, warn, info, debug, trace. * * Log a note message, formatting the message with a printf-style * control string and variable arguments. * A note message is always written to the log file regardless * of the priority level setting of the logger. * * @param file The name of the source code file logging the message. * @param line The line number of the file logging the message. * @param control_string The message control string. * @param ... Substitution arguments */ TC_DEPRECATED_NO_REPLACEMENT( "11.4", "Teamcenter::Logging::Logger::note" ) void note( const char* file, const int line, const char *control_string, ... ); /** * Check whether the input level is * enabled for logging and log the messages. * * @param lvl The priority level of the message * @param msg The message to log */ void log (const Logger::level lvl, const std::string &msg); /** * Checks whether the input level is * enabled for logging and log the message * * @param lvl The priority level of the message * @param errorCode An error code, in string form * @param msg The message to log. */ void log (const Logger::level lvl, const std::string errorCode, const std::string &msg); /** * Checks whether the input level is * enabled for logging and log the message * * @param lvl The priority level of the message * @param errorCode An error code, in int form * @param msg The message to log. */ void log (const Logger::level lvl, const int errorCode, const std::string &msg); /** * Checks whether the input level is * enabled for logging and log the message * Also add the file and line number from where * the log message is logged. * * @param lvl The priority level of the message * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode An error code, in int form * @param msg The message to log. */ void log ( const Logger::level lvl, const char *file, const int line, const int errorCode, const std::string &msg); /** * Checks whether the input level is * enabled for logging and log the message * Also add the file and line number from where * the log message is logged. * * @param lvl The priority level of the message * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param msg The message to log. */ void log ( const Logger::level lvl, const char *file, const int line, const std::string &msg); /** * Log the message with no stack trace. * Add the file and line number from where * the log message is logged. * * @param lvl The priority level of the message * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode An error code, in int form * @param msg The message to log. */ void logNoStackTrace ( const Logger::level lvl, const char *file, const int line, const int errorCode, const std::string &msg); /** * Checks whether the logger level * is set to the input level * * @param lvl The priority level of the message * @return the boolean whether input level is set */ bool isEnabled (const Logger::level lvl) const { return ( lvl >= logLevel ); }; /** * If a logger exists for the key in the tree, a pointer * to the existing logger. Otherwise created a new logger * object and return a pointer to the new logger * * @param key The logger name * @return Logger pointer. */ static Logger* getLogger(const std::string &key); /** * Log a message, formatting the message with a printf-style, * control string and a variable number of arguments. * * @param lvl The priority level of the message * @param errorCode An error code, in int form * @param control_string The control string to be printed in the log */ void logf( const Logger::level lvl, const int errorCode, const char *control_string, ... ) ; /** * Log a message, formatting the message with a printf-style, * control string and a variable number of arguments. * * @param lvl The priority level of the message * @param file The file name logging a message. * @param line The line number from which a call to log a message called. * @param errorCode An error code, in int form * @param control_string The control string to be printed in the log */ void logf( const Logger::level lvl, const char *file, const int line, const int errorCode, const char *control_string, ... ); /** * Print formatted text to the log file, * without log message fields or terminating newline, * if the logger is enabled for the given priority. * * @param lvl The priority level of the message * @param control_string The control string to be printed in the log */ void printf( const Logger::level lvl, const char *control_string, ... ); /** * Print formatted text to the log file, * without log message fields or a terminating newline. * The text will be printed regardless of the logger's level. * * @param control_string The control string to be printed in the log */ void printf( const char *control_string, ... ); /** * Get the logger object from the tree given the logger name. * * @param key logger name */ static Logger* getLoggerObject(const std::string &key); // this method sets the given name to the logger. void setLoggerName(const std::string &name) { loggerName=name; }; //Returns all the child loggers for a logger. static std::vector getListOfLoggers(std::string key); // returns the log level inheritance flag bool isLogLevelInherited () const { return logLevelInherited; }; // sets the log level inheritance flag void setInheritanceLevel ( bool isInherited) { logLevelInherited = isInherited; }; // set the logLevelInherited member variable // if set to true log level will be inherited from parent. // if set to false log level will not be inherited from parent. void setLogLevelInheritance (bool isInherited); private: // unique name for each logger. std::string loggerName; // logger level level logLevel; // We used a static data member to remember the choice of the appender, which is defined in the logger property file. // The syntax is as the following, if there is no appender specified, or if the value is invalid, syslog will be the appender // logging.rootLogger=INFO{,syslog|stderr|stdout} // Note that currently we only support a single choice of appender defined inside the rootLogger only. All loggers will inherit the same appender as the rootLogger. // We may consider supporting any individual logger setting its own appender, and even allowing multiple appenders for a single loggers. static int appender; // flag to check whether log level is inherited from parent. bool logLevelInherited; // Copy constructor and assignment operator are disabled and unimplemented // Since a Logger need not exist outside a LoggerTree Logger( const Logger& ); Logger& operator=( const Logger& ); /** * Constructor, set the logger name and * gets the syslog file pointer * * @param name logger name */ explicit Logger(const std::string &name); /** * Set the logger name log level and * gets the syslog file pointer * * @param name name for the logger name * @param lvl log level to be set for this logger */ Logger(const std::string &name, level lvl); /** * get the time in UTC format * */ std::string getTime() const; /** * get the log correlation id * */ std::string getId() const; /** * Format the first portion of the log message * */ std::string formatLogEntry ( const Logger::level lvl, const std::string errCode ) const; std::string formatLogEntry ( const Logger::level lvl ) const; std::string formatLogEntry ( const Logger::level lvl, const int errCode ) const; /** * Obtain the file pointer of the log file */ FILE* getLogFilePointer(); /** * Print the message to the syslog file. */ void writeToLog( const std::string &str ); /** * Add file name and the line number to the * message to be logged. */ void appendFileAndLine(std::string &str, const char* file, const int line) const; ~Logger(); Logger(); /** * Set the log level for the logger. * * @param lvl the log level for the logger. */ void setLogLevelAttribute(level lvl) { logLevel = lvl; logLevelInherited = false; }; /** * Check for invalid variable arguments, and return a substitute message if necessary. * @param control_string The control string to be written * @param ap1 The variable argument list of substitution values * @return null if OK, or a safe string that can be written in place of the original. */ std::string substituteForInvalidArgs ( const char* control_string, va_list ap1 ); /** * Check whether any %s format spec has a null argument. * This would cause vfprintf (and printf) to seg fault * on some platforms (SUN, Linux, AIX), though not on others (Windows, HP) * * @param control_string The control string to be written * @param ap1 The variable argument list of substitution values * @return 0 if OK, or the argument number of the first invalid null substitution for a %s specification. */ int checkForNullPointer ( const char* control_string, va_list ap1); void logv( const Logger::level lvl, const char* file, const int line, const int errorCode, const char* control_string, std::va_list va ); /** * Write a call stack trace if appropriate. * * @param lvl The priority level of the message. */ void stackTrace( const Logger::level lvl ); /** * This function appends the log file to each log event if Centralized Logging is enabled on * host machine. This is to group similar log lines together in Centralized Logging * by using the filename as an identifier. * * Enable by setting environment variable "TEAMCENTER_CENTRALIZED_LOGGING" to "TRUE" on host machine. * * @param str The Log line that will have filename appended. */ void appendFileNameForCentralizedLogging(std::string &str); /** * static function to extract leafName from absolute path * * @param absolutePath Absolute path to extract lwoest folder or filename */ static std::string getLeafName(std::string absolutePath ); }; } } #include #endif