You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

728 lines
33 KiB

// 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.
<br/>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.
<B>Example</B>
<CODE><PRE>
std::string str("Teamcenter.MyComponent.MyCode");
Logger *logger = Logger::getLogger(str);
if (logger->isErrorEnabled())
{
logger->error("Could not read the configuration file");
}
</PRE></CODE>
<B>Configuration</B>
<br/>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:
<code>logging.logger.&lt;hierarchical_logger_name&gt;=&lt;level&gt;</code>
<br/>If a logger does not have a specific priority level configured, it inherits its parent's level.
<B>Example</B>
<CODE><PRE>
logging.logger.Teamcenter=INFO
logging.logger.Teamcenter.SOA=INFO
logging.logger.Teamcenter.SOA.Gateway=TRACE
</PRE></CODE>
In production, loggers should usually be configured to INFO priority level.
<br/>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.
<B>Format</B>
Log messages are written in a fixed format with the following fields separated by dashes:
<ul>
<li>Priority Level
<li>Date/Time in UTC form
<li>Log Correlation ID
<li>Error Code (if supplied) and its localized error text (when applicable)
<li>Message
<li>Logger name
<li>File name and line number (if supplied)
</ul>
<B>Examples</B>
<CODE><PRE>
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)
</PRE></CODE>
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:
<ul>
<li>value of @c -42: all errors are logged.
<li>value of an error base (i.e. a multiple of 1000): all errors using the error base (error_base+0 to
error_base+999) are logged.
<li>value of a specific error: only the addition of this error to the error stack is logged.
</ul>
<b>Call Stack Traces</b>
<br/>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 <string>
#include <vector>
#include <cstdarg>
#include <common/tc_deprecation_macros.h>
#include <mld/libmld_exports.h>
// 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.
* <br/>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.
* <br/> 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<Logger *> 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 <mld/libmld_undef.h>
#endif