Mercurial > hg > release > heapstats-2.0
changeset 85:d0b7a759116d
Bug 2113: [ADD CONFIG] Add switch to output HeapStats messages to logfile.
reviewed-by: yasuenag
author | KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> |
---|---|
date | Thu, 11 Jun 2015 12:30:59 +0900 |
parents | 60db960255a5 |
children | 93e0a0a66b9c |
files | agent/ChangeLog agent/heapstats.conf.in agent/src/heapstats-engines/configuration.cpp agent/src/heapstats-engines/configuration.hpp agent/src/heapstats-engines/fsUtil.cpp agent/src/heapstats-engines/fsUtil.hpp agent/src/heapstats-engines/libmain.cpp agent/src/heapstats-engines/logger.hpp |
diffstat | 8 files changed, 138 insertions(+), 89 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/ChangeLog Thu May 28 17:01:36 2015 +0900 +++ b/agent/ChangeLog Thu Jun 11 12:30:59 2015 +0900 @@ -1,3 +1,7 @@ +2015-06-11 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> + + * Bug 2113: [ADD CONFIG] Add switch to output HeapStats messages to logfile. + 2015-05-28 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> * Bug 2382: Update Private Enterprise Number for SNMP.
--- a/agent/heapstats.conf.in Thu May 28 17:01:36 2015 +0900 +++ b/agent/heapstats.conf.in Thu Jun 11 12:30:59 2015 +0900 @@ -6,6 +6,7 @@ file=heapstats_snapshot.dat heaplogfile=heapstats_log.csv archivefile=heapstats_analyze.zip +logfile= loglevel=INFO reduce_snapshot=true
--- a/agent/src/heapstats-engines/configuration.cpp Thu May 28 17:01:36 2015 +0900 +++ b/agent/src/heapstats-engines/configuration.cpp Thu Jun 11 12:30:59 2015 +0900 @@ -59,6 +59,7 @@ FileName = strdup("heapstats_snapshot.dat"); heapLogFile = strdup("heapstats_log.csv"); archiveFile = strdup("heapstats_analyze.zip"); + logFile = strdup(""); RankLevel = 5; LogLevel = INFO; reduceSnapShot = true; @@ -107,6 +108,7 @@ : strdup(src.heapLogFile); archiveFile = src.archiveFile == NULL ? NULL : strdup(src.archiveFile); + logFile = src.logFile == NULL ? NULL : strdup(src.logFile); RankLevel = src.RankLevel; LogLevel = src.LogLevel; reduceSnapShot = src.reduceSnapShot; @@ -158,7 +160,10 @@ free(archiveFile); archiveFile = NULL; - + + free(logFile); + logFile = NULL; + if(logSignalNormal != NULL){ free(logSignalNormal); logSignalNormal = NULL; @@ -314,66 +319,6 @@ } } - -/*! - * \brief Check that path is accessible. - * \param value [in] Value of this configuration. - * \return Path is accessible. - */ -bool TConfiguration::IsValidPath(const char *value){ - /* Check archive file path. */ - char *dir = getParentDirectoryPath(value); - if(dir == NULL){ - throw "Cannot get parent directory"; - } - - errno = 0; - int ret = isAccessibleDirectory(dir, true, true); - free(dir); - if(ret == -1){ - throw "Illegal parameter was passed to isAccessibleDirectory()"; - } - else if(errno != 0){ - return false; - } - - struct stat st; - if(stat(value, &st) == -1){ - if(errno == ENOENT){ - return true; - } - else{ - throw errno; - } - } - - bool result = false; - bool isOwner = (st.st_uid == geteuid()); - bool isGroupUser = (st.st_gid == getegid()); - - /* Check access permition as file owner. */ - if(isOwner){ - result |= (st.st_mode & S_IRUSR) && (st.st_mode & S_IWUSR); - } - - /* Check access permition as group user. */ - if(!result && isGroupUser){ - result |= (st.st_mode & S_IRGRP) && (st.st_mode & S_IWGRP); - } - - /* Check access permition as other. */ - if(!result){ - result |= (st.st_mode & S_IROTH) && (st.st_mode & S_IWOTH); - } - - if(!result){ - errno = EPERM; - } - - return result; -} - - /*! * \brief Load configuration from file. * \param filename [in] Read configuration file path. @@ -468,6 +413,8 @@ logger->printInfoMsg("SnapShot FileName = %s", FileName); logger->printInfoMsg("Heap Log FileName = %s", heapLogFile); logger->printInfoMsg("Archive FileName = %s", archiveFile); + logger->printInfoMsg("Console Log FileName = %s", + strlen(logFile) > 0 ? logFile : "None (output to console)"); /* Output log-level. */ const char *loglevelArray[] = {NULL, "CRIT", "WARN", "INFO", "DEBUG"}; @@ -609,12 +556,20 @@ struct{ char *key; char *value; - } filenames[] = {{"file", FileName}, {"heaplogfile", heapLogFile}, - {"archivefile", archiveFile}, {"logdir", logDir}, + } filenames[] = {{"file", FileName}, + {"heaplogfile", heapLogFile}, + {"archivefile", archiveFile}, + {"logfile", logFile}, + {"logdir", logDir}, {NULL, NULL}}; - for(int idx = 0; filenames[idx].key != NULL; idx++){ + + for(int idx = 0; filenames[idx].key != NULL; idx++) { + if (strlen(filenames[idx].value) == 0) { + // "" means "disable", not a file path like "./". + continue; + } try{ - if(!IsValidPath(filenames[idx].value)){ + if(!isValidPath(filenames[idx].value)){ throw "Permission denied"; } } @@ -684,7 +639,7 @@ threadRecordBufferSize); result = false; } - else if(!IsValidPath(threadRecordFileName)){ + else if(!isValidPath(threadRecordFileName)){ logger->printWarnMsg("Permission denied: thread_record_filename = %s", threadRecordFileName); result = false; @@ -720,6 +675,7 @@ setFileName(src->FileName); setHeapLogFile(src->heapLogFile); setArchiveFile(src->archiveFile); + setLogFile(src->logFile); setRankLevel(src->RankLevel); setLogLevel(src->LogLevel); setReduceSnapShot(src->reduceSnapShot); @@ -776,6 +732,9 @@ else if(strcmp(key, "archivefile") == 0){ setArchiveFile(value); } + else if(strcmp(key, "logfile") == 0){ + setLogFile(value); + } else if(strcmp(key, "rank_level") == 0){ setRankLevel(ReadLongValue(value, INT_MAX)); }
--- a/agent/src/heapstats-engines/configuration.hpp Thu May 28 17:01:36 2015 +0900 +++ b/agent/src/heapstats-engines/configuration.hpp Thu Jun 11 12:30:59 2015 +0900 @@ -57,6 +57,9 @@ /*!< Output archive log file name. */ char *archiveFile; + /*!< Output console log file name. */ + char *logFile; + /*!< Is reduced snapshot. */ bool reduceSnapShot; @@ -182,14 +185,6 @@ */ void ReadSignalValue(const char *value, char **dest); - /*! - * \brief Check that path is accessible. - * \param value [in] Value of this configuration. - * \return Path is accessible. - */ - bool IsValidPath(const char *value); - - public: TConfiguration(TJvmInfo *info); @@ -263,6 +258,7 @@ inline char *getFileName(){ return this->FileName; }; inline char *getHeapLogFile(){ return this->heapLogFile; }; inline char *getArchiveFile(){ return this->archiveFile; }; + inline char *getLogFile(){ return this->logFile; }; inline bool getReduceSnapShot(){ return this->reduceSnapShot; }; inline bool getTriggerOnFullGC(){ return this->triggerOnFullGC; }; inline bool getTriggerOnDump(){ return this->triggerOnDump; }; @@ -301,6 +297,7 @@ inline void setFileName(const char *val){ ReadStringValue(val, &FileName); }; inline void setHeapLogFile(const char *val){ ReadStringValue(val, &heapLogFile); }; inline void setArchiveFile(const char *val){ ReadStringValue(val, &archiveFile); }; + inline void setLogFile(const char *val){ ReadStringValue(val, &logFile); }; inline void setReduceSnapShot(bool val){ this->reduceSnapShot = val; }; inline void setTriggerOnFullGC(bool val){ if(isLoaded && !triggerOnFullGC && val){
--- a/agent/src/heapstats-engines/fsUtil.cpp Thu May 28 17:01:36 2015 +0900 +++ b/agent/src/heapstats-engines/fsUtil.cpp Thu Jun 11 12:30:59 2015 +0900 @@ -558,3 +558,64 @@ return (result) ? 0 : EACCES; } +/*! + * \brief Check that path is accessible. + * \param path [in] A path to file. + * \return Path is accessible. + */ +bool isValidPath(const char *path){ + /* Check archive file path. */ + if (strlen(path) == 0) { + throw "Invalid file path"; + } + char *dir = getParentDirectoryPath(path); + if(dir == NULL){ + throw "Cannot get parent directory"; + } + + errno = 0; + int ret = isAccessibleDirectory(dir, true, true); + free(dir); + if(ret == -1){ + throw "Illegal parameter was passed to isAccessibleDirectory()"; + } + else if(errno != 0){ + return false; + } + + struct stat st; + if(stat(path, &st) == -1){ + if(errno == ENOENT){ + return true; + } + else{ + throw errno; + } + } + + bool result = false; + bool isOwner = (st.st_uid == geteuid()); + bool isGroupUser = (st.st_gid == getegid()); + + /* Check access permition as file owner. */ + if(isOwner){ + result |= (st.st_mode & S_IRUSR) && (st.st_mode & S_IWUSR); + } + + /* Check access permition as group user. */ + if(!result && isGroupUser){ + result |= (st.st_mode & S_IRGRP) && (st.st_mode & S_IWGRP); + } + + /* Check access permition as other. */ + if(!result){ + result |= (st.st_mode & S_IROTH) && (st.st_mode & S_IWOTH); + } + + if(!result){ + errno = EPERM; + } + + return result; +} +
--- a/agent/src/heapstats-engines/fsUtil.hpp Thu May 28 17:01:36 2015 +0900 +++ b/agent/src/heapstats-engines/fsUtil.hpp Thu Jun 11 12:30:59 2015 +0900 @@ -98,6 +98,13 @@ int isAccessibleDirectory(char const* path, bool needRead, bool needWrite); /*! + * \brief Check that path is accessible. + * \param path [in] A path to file. + * \return Path is accessible. + */ +bool isValidPath(const char *path); + +/*! * \brief Check disk full error.<br /> * If error is disk full, then print alert message. * \param aErrorNum [in] Number of error code.
--- a/agent/src/heapstats-engines/libmain.cpp Thu May 28 17:01:36 2015 +0900 +++ b/agent/src/heapstats-engines/libmain.cpp Thu Jun 11 12:30:59 2015 +0900 @@ -608,6 +608,7 @@ } logger->setLogLevel(conf->getLogLevel()); + logger->setLogFile(conf->getLogFile()); /* Show package information. */ logger->printInfoMsg(PACKAGE_STRING);
--- a/agent/src/heapstats-engines/logger.hpp Thu May 28 17:01:36 2015 +0900 +++ b/agent/src/heapstats-engines/logger.hpp Thu Jun 11 12:30:59 2015 +0900 @@ -49,6 +49,8 @@ class TLogger{ private: + FILE *out = stdout; + FILE *err = stderr; TLogLevel logLevel; /*! @@ -64,11 +66,9 @@ bool isNewLine, const char *format, va_list ap){ fprintf(stream, "heapstats %s: ", header); vfprintf(stream, format, ap); - if(isNewLine){ fputc('\n', stream); } - } public: @@ -76,16 +76,18 @@ TLogger() : logLevel(INFO) {}; TLogger(TLogLevel level) : logLevel(level) {}; + virtual ~TLogger(){ flush(); + if (out != stdout && out != NULL) { fclose(out); } } /*! * \brief Flush stdout and stderr. */ inline void flush(){ - fflush(stdout); - fflush(stderr); + fflush(out); + if (err != out) { fflush(err); } } /*! @@ -97,33 +99,50 @@ } /*! - * \brief Print critical message to stderr. + * \brief Setter for logFile. + * \param logfile: Console log filename. + */ + inline void setLogFile(char *logfile) { + if (logfile != NULL && strlen(logfile) != 0) { + out = fopen(logfile, "a"); + if (unlikely( out==NULL )) { + // If cannot open file. + this->printWarnMsgWithErrno("Could not open console log file: %s. Agent always output to console.", logfile); + out = stdout; + } else { + err = out; + } + } + } + + /*! + * \brief Print critical error message. * This function treats arguments as printf(3). */ inline void printCritMsg(const char *format, ...){ if(this->logLevel >= CRIT){ va_list ap; va_start(ap, format); - this->printMessageInternal(stderr, "CRIT", true, format, ap); + this->printMessageInternal(err, "CRIT", true, format, ap); va_end(ap); } } /*! - * \brief Print warning message to stderr. + * \brief Print warning error message. * This function treats arguments as printf(3). */ inline void printWarnMsg(const char *format, ...){ if(this->logLevel >= WARN){ va_list ap; va_start(ap, format); - this->printMessageInternal(stderr, "WARN", true, format, ap); + this->printMessageInternal(err, "WARN", true, format, ap); va_end(ap); } } /*! - * \brief Print warning message to stderr with current errno. + * \brief Print warning error message with current errno. * This function treats arguments as printf(3). */ inline void printWarnMsgWithErrno(const char *format, ...){ @@ -133,34 +152,34 @@ va_list ap; va_start(ap, format); - this->printMessageInternal(stderr, "WARN", false, format, ap); + this->printMessageInternal(err, "WARN", false, format, ap); va_end(ap); - fprintf(stderr, " cause: %s\n", output_message); + fprintf(err, " cause: %s\n", output_message); } } /*! - * \brief Print information message to stdout. + * \brief Print information message. * This function treats arguments as printf(3). */ inline void printInfoMsg(const char *format, ...){ if(this->logLevel >= INFO){ va_list ap; va_start(ap, format); - this->printMessageInternal(stdout, "INFO", true, format, ap); + this->printMessageInternal(out, "INFO", true, format, ap); va_end(ap); } } /*! - * \brief Print debug message to stdout. + * \brief Print debug message. * This function treats arguments as printf(3). */ inline void printDebugMsg(const char *format, ...){ if(this->logLevel >= DEBUG){ va_list ap; va_start(ap, format); - this->printMessageInternal(stdout, "DEBUG", true, format, ap); + this->printMessageInternal(out, "DEBUG", true, format, ap); va_end(ap); } }