blob: 765f8dfcf1de5e59d3d978532a712042d88bcef6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gfcpp/gfcpp_globals.hpp>
#include <ace/ACE.h>
#include <ace/Thread_Mutex.h>
#include <ace/Task.h>
#include <ace/OS_NS_sys_utsname.h>
#include <ace/INET_Addr.h>
#include <ace/Dirent.h>
#include <ace/Dirent_Selector.h>
#include <ace/OS_NS_sys_stat.h>
#include <utility>
#include <vector>
#include "HostStatSampler.hpp"
#include "HostStatHelper.hpp"
#include "StatArchiveWriter.hpp"
#include <NanoTimer.hpp>
#include <gfcpp/DistributedSystem.hpp>
#include <gfcpp/SystemProperties.hpp>
#include <gfcpp/Log.hpp>
#include "GeodeStatisticsFactory.hpp"
#include <ClientHealthStats.hpp>
#include <ClientProxyMembershipID.hpp>
using namespace apache::geode::statistics;
using namespace apache::geode::client;
namespace apache {
namespace geode {
namespace statistics {
namespace globals {
std::string g_statFile;
std::string g_statFileWithExt;
int64 g_spaceUsed = 0;
int64 g_previoussamplesize = 0;
int64 g_previoussamplesizeLastFile = 0;
// Make a pair for the filename & its size
std::pair<std::string, size_t> g_fileInfoPair;
// Vector to hold the fileInformation
typedef std::vector<std::pair<std::string, int64> > g_fileInfo;
} // namespace globals
} // namespace statistics
} // namespace geode
} // namespace apache
using namespace apache::geode::statistics::globals;
extern "C" {
int selector(const dirent* d) {
std::string inputname(d->d_name);
std::string filebasename = ACE::basename(
apache::geode::statistics::globals::g_statFileWithExt.c_str());
size_t actualHyphenPos = filebasename.find_last_of('.');
if (strcmp(filebasename.c_str(), d->d_name) == 0) return 1;
size_t fileExtPos = inputname.find_last_of('.');
std::string extName = inputname.substr(fileExtPos + 1, inputname.length());
if (strcmp(extName.c_str(), "gfs") != 0) return 0;
if (fileExtPos != std::string::npos) {
std::string tempname = inputname.substr(0, fileExtPos);
size_t fileHyphenPos = tempname.find_last_of('-');
if (fileHyphenPos != std::string::npos) {
std::string buff1 = tempname.substr(0, fileHyphenPos);
if (ACE_OS::strstr(filebasename.c_str(), buff1.c_str()) == 0) {
return 0;
}
if (fileHyphenPos != actualHyphenPos) return 0;
std::string buff = tempname.substr(fileHyphenPos + 1,
tempname.length() - fileHyphenPos - 1);
for (std::string::iterator iter = buff.begin(); iter != buff.end();
++iter) {
if (*iter < '0' || *iter > '9') {
return 0;
}
}
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
int comparator(const dirent** d1, const dirent** d2) {
if (strlen((*d1)->d_name) < strlen((*d2)->d_name)) {
return -1;
} else if (strlen((*d1)->d_name) > strlen((*d2)->d_name)) {
return 1;
}
int diff = ACE_OS::strcmp((*d1)->d_name, (*d2)->d_name);
if (diff < 0) {
return -1;
} else if (diff > 0) {
return 1;
} else {
return 0;
}
}
}
const char* HostStatSampler::NC_HSS_Thread = "NC HSS Thread";
HostStatSampler::HostStatSampler(const char* filePath, int64 sampleIntervalMs,
StatisticsManager* statMngr,
int64 statFileLimit,
int64 statDiskSpaceLimit) {
m_isStatDiskSpaceEnabled = false;
m_adminError = false;
m_running = false;
m_stopRequested = false;
m_archiver = NULL;
m_samplerStats = new StatSamplerStats();
ACE_Time_Value startTimeValue = ACE_OS::gettimeofday();
m_startTime = startTimeValue.msec();
m_pid = ACE_OS::getpid();
m_statMngr = statMngr;
m_archiveFileName = filePath;
g_statFile = filePath;
m_sampleRate = sampleIntervalMs;
rollIndex = 0;
m_archiveDiskSpaceLimit = statDiskSpaceLimit;
g_spaceUsed = 0;
if (statDiskSpaceLimit != 0) {
m_isStatDiskSpaceEnabled = true;
}
m_archiveFileSizeLimit = statFileLimit * 1024 * 1024; // 10000000;
if (m_archiveFileSizeLimit < 0 ||
m_archiveFileSizeLimit > GEMFIRE_MAX_STATS_FILE_LIMIT) {
m_archiveFileSizeLimit = GEMFIRE_MAX_STATS_FILE_LIMIT;
}
if (m_isStatDiskSpaceEnabled) {
m_archiveDiskSpaceLimit = statDiskSpaceLimit * 1024 * 1024; // 10000000;
if (m_archiveDiskSpaceLimit <
0 /*|| m_archiveDiskSpaceLimit > GEMFIRE_MAX_STAT_DISK_LIMIT*/) {
m_archiveDiskSpaceLimit = GEMFIRE_MAX_STAT_DISK_LIMIT;
}
// If FileSizelimit is greater than DiskSpaceLimit & diskspaceLimit is set,
// then set DiskSpaceLimit to FileSizelimit
if (m_archiveFileSizeLimit > m_archiveDiskSpaceLimit) {
m_archiveFileSizeLimit = m_archiveDiskSpaceLimit;
}
// If only DiskSpaceLimit is specified and no FileSizeLimit specified, then
// set DiskSpaceLimit to FileSizelimit.
// This helps in getting the file handle that is exceeded the limit.
if (m_archiveFileSizeLimit == 0) {
m_archiveFileSizeLimit = m_archiveDiskSpaceLimit;
}
g_statFileWithExt = initStatFileWithExt();
#ifdef _WIN32
// replace all '\' with '/' to make everything easier..
size_t len = g_statFile.length() + 1;
char* slashtmp = new char[len];
ACE_OS::strncpy(slashtmp, g_statFile.c_str(), len);
for (size_t i = 0; i < g_statFile.length(); i++) {
if (slashtmp[i] == '/') {
slashtmp[i] = '\\';
}
}
g_statFile = slashtmp;
delete[] slashtmp;
slashtmp = NULL;
#endif
std::string dirname = ACE::dirname(g_statFile.c_str());
// struct dirent **resultArray;
// int entries_count = ACE_OS::scandir(dirname.c_str(), &resultArray,
// selector, comparator);
ACE_Dirent_Selector sds;
int status = sds.open(dirname.c_str(), selector, comparator);
if (status != -1) {
for (int i = 0; i < sds.length(); i++) {
// std::string strname = ACE::basename(resultArray[i]->d_name);
std::string strname = ACE::basename(sds[i]->d_name);
size_t fileExtPos = strname.find_last_of('.', strname.length());
if (fileExtPos != std::string::npos) {
std::string tempname = strname.substr(0, fileExtPos);
size_t fileHyphenPos = tempname.find_last_of('-', tempname.length());
if (fileHyphenPos != std::string::npos) {
std::string buff =
tempname.substr(fileHyphenPos + 1, tempname.length());
rollIndex = ACE_OS::atoi(buff.c_str()) + 1;
}
}
}
sds.close();
}
/*for(int i = 0; i < entries_count; i++) {
ACE_OS::free ( resultArray[i] );
}
if (entries_count >= 0) {
ACE_OS::free( resultArray );
resultArray = NULL;
}*/
FILE* existingFile = fopen(g_statFileWithExt.c_str(), "r");
if (existingFile != NULL && statFileLimit > 0) {
fclose(existingFile);
/* adongre
* CID 28820: Resource leak (RESOURCE_LEAK)
*/
existingFile = NULL;
changeArchive(g_statFileWithExt);
} else {
writeGfs();
}
/* adongre
* CID 28820: Resource leak (RESOURCE_LEAK)
*/
if (existingFile != NULL) {
fclose(existingFile);
existingFile = NULL;
}
}
}
std::string HostStatSampler::initStatFileWithExt() {
std::string archivefilename = createArchiveFileName();
archivefilename = chkForGFSExt(archivefilename);
return archivefilename;
}
HostStatSampler::~HostStatSampler() {
if (m_samplerStats != NULL) {
delete m_samplerStats;
m_samplerStats = NULL;
}
if (m_archiver != NULL) {
delete m_archiver;
m_archiver = NULL;
}
}
std::string HostStatSampler::createArchiveFileName() {
if (!m_isStatDiskSpaceEnabled) {
char buff[1024] = {0};
int32 pid = ACE_OS::getpid();
int32 len = static_cast<int32>(m_archiveFileName.length());
size_t fileExtPos = m_archiveFileName.find_last_of('.', len);
if (fileExtPos == std::string::npos) {
ACE_OS::snprintf(buff, 1024, "%s-%d.gfs", m_archiveFileName.c_str(), pid);
} else {
std::string tmp;
tmp = m_archiveFileName.substr(0, fileExtPos);
ACE_OS::snprintf(buff, 1024, "%s-%d.gfs", tmp.c_str(), pid);
}
m_archiveFileName = buff;
return m_archiveFileName;
} else {
return m_archiveFileName;
}
}
std::string HostStatSampler::getArchiveFileName() { return m_archiveFileName; }
int64 HostStatSampler::getArchiveFileSizeLimit() {
return m_archiveFileSizeLimit;
}
int64 HostStatSampler::getArchiveDiskSpaceLimit() {
return m_archiveDiskSpaceLimit;
}
int64 HostStatSampler::getSampleRate() { return m_sampleRate; }
bool HostStatSampler::isSamplingEnabled() { return true; }
void HostStatSampler::accountForTimeSpentWorking(int64 nanosSpentWorking) {
m_samplerStats->tookSample(nanosSpentWorking);
}
bool HostStatSampler::statisticsExists(const int64 id) {
ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_statMngr->getListMutex());
std::vector<Statistics*>& statsList = m_statMngr->getStatsList();
std::vector<Statistics*>::iterator i;
for (i = statsList.begin(); i != statsList.end(); ++i) {
if ((*i)->getUniqueId() == id) {
return true;
}
}
return false;
}
Statistics* HostStatSampler::findStatistics(const int64 id) {
ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_statMngr->getListMutex());
std::vector<Statistics*>& statsList = m_statMngr->getStatsList();
std::vector<Statistics*>::iterator i;
for (i = statsList.begin(); i != statsList.end(); ++i) {
if ((*i)->getUniqueId() == id) {
return *i;
}
}
return NULL;
}
ACE_Recursive_Thread_Mutex& HostStatSampler::getStatListMutex() {
return m_statMngr->getListMutex();
}
int32 HostStatSampler::getStatisticsModCount() {
return m_statMngr->getStatListModCount();
}
std::vector<Statistics*>& HostStatSampler::getStatistics() {
return m_statMngr->getStatsList();
}
std::vector<Statistics*>& HostStatSampler::getNewStatistics() {
return m_statMngr->getNewlyAddedStatsList();
}
int64 HostStatSampler::getSystemId() { return m_pid; }
int64 HostStatSampler::getSystemStartTime() { return m_startTime; }
std::string HostStatSampler::getSystemDirectoryPath() {
ACE_utsname u;
ACE_OS::uname(&u);
std::string dirPath(u.nodename);
return dirPath;
}
std::string HostStatSampler::getProductDescription() {
return "Pivotal Geode Native Client ";
}
void HostStatSampler::changeArchive(std::string filename) {
if (filename.length() == 0) {
// terminate the sampling thread
m_stopRequested = true;
return;
}
filename = chkForGFSExt(filename);
if (m_archiver != NULL) {
g_previoussamplesize = m_archiver->getSampleSize();
m_archiver->closeFile();
}
// create new file only when tis file has some data; otherwise reuse it
if (rollArchive(filename) != 0) {
delete m_archiver;
m_archiver = NULL;
// throw exception
return;
} else {
/*
if (m_archiver != NULL) {
m_archiver->openFile(filename);
m_archiver->close();
}
*/
delete m_archiver;
m_archiver = NULL;
}
m_archiver = new StatArchiveWriter(filename, this);
}
std::string HostStatSampler::chkForGFSExt(std::string filename) {
if (!m_isStatDiskSpaceEnabled) {
int32 len = static_cast<int32>(filename.length());
size_t posOfExt = filename.find_last_of('.', len);
if (posOfExt == std::string::npos) {
std::string newFilename = filename + "." + "gfs";
return newFilename;
}
std::string extName = filename.substr(posOfExt + 1);
if (extName != "gfs") {
std::string newFilename = filename.substr(0, posOfExt) + "." + "gfs";
return newFilename;
}
return filename;
} else {
std::string filebasename = ACE::basename(filename.c_str());
int32 len = static_cast<int32>(filebasename.length());
size_t fileExtPos = filebasename.find_last_of('.', len);
// if no extension then add .gfs extension
if (fileExtPos == std::string::npos) {
std::string newFilename = filename + "." + "gfs";
return newFilename;
} else {
std::string extName = filebasename.substr(fileExtPos + 1);
// if extension other than .gfs change it to ext + .log
if (extName != "gfs") {
std::string newFilename = filename + "." + "gfs";
return newFilename;
}
// .gfs Extension already provided, no need to append any extension.
else {
return filename;
}
}
}
}
int32 HostStatSampler::rollArchive(std::string filename) {
FILE* fpExist = fopen(filename.c_str(), "r");
if (fpExist == NULL) {
return 0; // no need to roll
} else {
fclose(fpExist);
ACE_stat statBuf = {0};
ACE_OS::stat(filename.c_str(), &statBuf);
if (statBuf.st_size == 0) return 0; // reuse this file
}
std::string statsdirname;
std::string statsbasename;
std::string fnameBeforeExt;
std::string extName;
std::string newfilestr;
bool gotNewFileName = false;
int32 len = static_cast<int32>(filename.length());
int32 lastPosOfSep = static_cast<int32>(
filename.find_last_of(ACE_DIRECTORY_SEPARATOR_CHAR, len));
if (lastPosOfSep == -1) {
statsdirname = ".";
} else {
statsdirname = filename.substr(0, lastPosOfSep);
}
statsbasename = filename.substr(lastPosOfSep + 1, len);
char gfsFileExtAfter = '.';
int32 baselen = static_cast<int32>(statsbasename.length());
int32 posOfExt = static_cast<int32>(
statsbasename.find_last_of(gfsFileExtAfter, static_cast<int32>(baselen)));
if (posOfExt == -1) {
// throw IllegalArgument;
} else {
fnameBeforeExt = statsbasename.substr(0, posOfExt);
extName = statsbasename.substr(posOfExt + 1, baselen);
}
int32 i = this->rollIndex;
// 1000 is a good enough val to hold even a very int64 filename.
while (!gotNewFileName) {
char newfilename[1000] = {0};
if (i < 10) {
ACE_OS::snprintf(newfilename, 1000, "%s%c%s-%d.%s", statsdirname.c_str(),
ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(), i,
extName.c_str());
} else {
ACE_OS::snprintf(newfilename, 1000, "%s%c%s-%d.%s", statsdirname.c_str(),
ACE_DIRECTORY_SEPARATOR_CHAR, fnameBeforeExt.c_str(), i,
extName.c_str());
}
FILE* fp = fopen(newfilename, "r");
if (fp != NULL) {
// file exists; increment i and try the next filename
i++;
fclose(fp);
} else {
newfilestr = newfilename;
// In the next call it will start looking from rollIndex = i+1
if (rename(filename.c_str(), newfilestr.c_str()) < 0) {
return -1;
} else {
this->rollIndex = i + 1;
return 0;
}
}
}
// The control will come here in case of error only.
// This return looks redundant but introduced to remove warnings
// while compiling the code.
return -1;
}
void HostStatSampler::initSpecialStats() {
// After Special categories are decided initialize them here
HostStatHelper::newProcessStats(m_pid, "ProcessStats");
}
void HostStatSampler::sampleSpecialStats() { HostStatHelper::refresh(); }
void HostStatSampler::closeSpecialStats() {
ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_statMngr->getListMutex());
HostStatHelper::close();
HostStatHelper::cleanup();
}
void HostStatSampler::checkListeners() {}
void HostStatSampler::start() {
if (!m_running) {
m_running = true;
this->activate();
}
}
void HostStatSampler::stop() {
m_stopRequested = true;
this->wait();
// while (m_running) {
// ACE_OS::sleep(100);
//}
}
bool HostStatSampler::isRunning() { return m_running; }
void HostStatSampler::putStatsInAdminRegion() {
try {
// Get Values of gets, puts,misses,listCalls,numThreads
static bool initDone = false;
static std::string clientId = "";
AdminRegionPtr adminRgn = m_statMngr->getAdminRegion();
if (adminRgn == NULLPTR) return;
TryReadGuard _guard(adminRgn->getRWLock(), adminRgn->isDestroyed());
if (!adminRgn->isDestroyed()) {
TcrConnectionManager* m_conn_man = adminRgn->getConnectionManager();
if (m_conn_man->getNumEndPoints() > 0) {
if (!initDone) {
adminRgn->init();
initDone = true;
}
int puts = 0, gets = 0, misses = 0, numListeners = 0, numThreads = 0,
creates = 0;
int64 cpuTime = 0;
GeodeStatisticsFactory* gf =
GeodeStatisticsFactory::getExistingInstance();
if (gf) {
StatisticsType* cacheStatType = gf->findType("CachePerfStats");
if (cacheStatType) {
Statistics* cachePerfStats =
gf->findFirstStatisticsByType(cacheStatType);
if (cachePerfStats) {
puts = cachePerfStats->getInt((char*)"puts");
gets = cachePerfStats->getInt((char*)"gets");
misses = cachePerfStats->getInt((char*)"misses");
creates = cachePerfStats->getInt((char*)"creates");
numListeners =
cachePerfStats->getInt((char*)"cacheListenerCallsCompleted");
puts += creates;
}
}
numThreads = HostStatHelper::getNumThreads();
cpuTime = HostStatHelper::getCpuTime();
}
static int numCPU = ACE_OS::num_processors();
ClientHealthStatsPtr obj = ClientHealthStats::create(
gets, puts, misses, numListeners, numThreads, cpuTime, numCPU);
if (clientId.empty()) {
ACE_TCHAR hostName[256];
ACE_OS::hostname(hostName, sizeof(hostName) - 1);
ACE_INET_Addr driver("", hostName, "tcp");
uint32_t hostAddr = driver.get_ip_address();
uint16_t hostPort = 0;
SystemProperties* sysProp = DistributedSystem::getSystemProperties();
const char* durableId =
(sysProp != NULL) ? sysProp->durableClientId() : NULL;
const uint32_t durableTimeOut =
(sysProp != NULL) ? sysProp->durableTimeout() : 0;
ClientProxyMembershipID memId(hostName, hostAddr, hostPort, durableId,
durableTimeOut);
clientId = memId.getDSMemberIdForThinClientUse();
}
CacheableKeyPtr keyPtr = CacheableString::create(clientId.c_str());
adminRgn->put(keyPtr, obj);
}
}
} catch (const Exception&) {
m_adminError = true;
}
}
void HostStatSampler::writeGfs() {
std::string archivefilename = createArchiveFileName();
changeArchive(archivefilename);
}
void HostStatSampler::forceSample() {
ACE_Guard<ACE_Recursive_Thread_Mutex> samplingGuard(m_samplingLock);
if (m_archiver) {
sampleSpecialStats();
m_archiver->sample();
m_archiver->flush();
}
}
void HostStatSampler::doSample(std::string& archivefilename) {
ACE_Guard<ACE_Recursive_Thread_Mutex> samplingGuard(m_samplingLock);
sampleSpecialStats();
checkListeners();
// Populate Admin Region for GFMon
if (isSamplingEnabled() && !m_adminError &&
!TcrConnectionManager::isNetDown) {
putStatsInAdminRegion();
}
m_archiver->sample();
if (m_archiveFileSizeLimit != 0) {
int64 size = m_archiver->getSampleSize();
int64 bytesWritten = m_archiver->bytesWritten(); // + g_previoussamplesize;
if (bytesWritten > (m_archiveFileSizeLimit - size)) {
// roll the archive
changeArchive(archivefilename);
}
}
g_spaceUsed += m_archiver->bytesWritten();
// delete older stat files if disk limit is about to be exceeded.
if ((m_archiveDiskSpaceLimit != 0) &&
(g_spaceUsed >=
(m_archiveDiskSpaceLimit - m_archiver->getSampleSize()))) {
checkDiskLimit();
}
// It will flush the contents to the archive file, in every
// sample run.
m_archiver->flush();
}
void HostStatSampler::checkDiskLimit() {
g_fileInfo fileInfo;
g_spaceUsed = 0;
char fullpath[512] = {0};
std::string dirname = ACE::dirname(g_statFile.c_str());
// struct dirent **resultArray;
// int entries_count = ACE_OS::scandir(dirname.c_str(), &resultArray,
// selector, comparator);
ACE_stat statBuf = {0};
ACE_Dirent_Selector sds;
int status = sds.open(dirname.c_str(), selector, comparator);
if (status != -1) {
for (int i = 1; i < sds.length(); i++) {
ACE_OS::snprintf(fullpath, 512, "%s%c%s", dirname.c_str(),
ACE_DIRECTORY_SEPARATOR_CHAR, sds[i]->d_name);
ACE_OS::stat(fullpath, &statBuf);
g_fileInfoPair = std::make_pair(fullpath, statBuf.st_size);
fileInfo.push_back(g_fileInfoPair);
g_spaceUsed += fileInfo[i - 1].second;
}
g_spaceUsed += m_archiver->bytesWritten();
/*for(int i = 0; i < entries_count; i++) {
ACE_OS::free ( resultArray[i] );
}
if (entries_count >= 0) {
ACE_OS::free( resultArray );
resultArray = NULL;
}*/
sds.close();
}
int fileIndex = 0;
while ((g_spaceUsed >
m_archiveDiskSpaceLimit) /*&& (fileIndex < entries_count)*/) {
int64 fileSize = fileInfo[fileIndex].second;
if (ACE_OS::unlink(fileInfo[fileIndex].first.c_str()) == 0) {
g_spaceUsed -= fileSize;
} else {
LOGWARN("%s\t%s\n", "Could not delete",
fileInfo[fileIndex].first.c_str());
}
fileIndex++;
}
}
int32 HostStatSampler::svc(void) {
DistributedSystemImpl::setThreadName(NC_HSS_Thread);
try {
initSpecialStats();
// createArchiveFileName instead of getArchiveFileName here because
// for the first time the sampler needs to add the pid to the filename
// passed to it.
std::string archivefilename = createArchiveFileName();
if (!m_isStatDiskSpaceEnabled) {
changeArchive(archivefilename);
}
int32 msSpentWorking = 0;
int32 msRate = static_cast<int32>(getSampleRate());
bool gotexception = false;
int waitTime = 0;
while (!m_stopRequested) {
try {
if (gotexception) {
ACE_OS::sleep(1);
waitTime++;
if (waitTime < 60) { // sleep for minute and then try to recreate
continue;
}
waitTime = 0;
gotexception = false;
changeArchive(archivefilename);
}
int64 sampleStartNanos = NanoTimer::now();
doSample(archivefilename);
int64 sampleEndNanos = NanoTimer::now();
int64 nanosSpentWorking = sampleEndNanos - sampleStartNanos;
// updating the sampler statistics
accountForTimeSpentWorking(nanosSpentWorking);
msSpentWorking = static_cast<int32>(nanosSpentWorking / 1000000);
// Continous check for m_stopRequested to sped up stop time.
int32 msToWait = msRate - msSpentWorking;
while (msToWait > 0) {
ACE_Time_Value sleepTime;
sleepTime.msec(msToWait > 100 ? 100 : msToWait);
ACE_OS::sleep(sleepTime);
msToWait -= 100;
if (m_stopRequested) {
break;
}
}
} catch (Exception& e) {
// log the exception and let the thread exit.
LOGERROR("Exception in statistics sampler thread: %s: %s", e.getName(),
e.getMessage());
// now close current archiver and see if we can start new one
gotexception = true;
} catch (...) {
LOGERROR("Unknown Exception in statistics sampler thread: ");
gotexception = true;
}
}
closeSpecialStats();
m_samplerStats->close();
if (m_archiver != NULL) {
m_archiver->close();
}
} catch (Exception& e) {
// log the exception and let the thread exit.
LOGERROR("Exception in statistics sampler thread: %s: %s", e.getName(),
e.getMessage());
closeSpecialStats();
} /* catch (...) {
// log the exception and let the thread exit.
LOGERROR("Exception in sampler thread ");
closeSpecialStats();
}*/
m_running = false;
return 0;
}