in source/code/scxsystemlib/disk/statisticallogicaldiskinstance.cpp [149:330]
void StatisticalLogicalDiskInstance::Sample()
{
#if defined(hpux)
SCXCoreLib::SCXHandle<DeviceInstance> di = m_deps->FindDeviceInstance(m_device);
if ((0 == di) || (DiskDepend::s_cINVALID_INSTANCE == di->m_instance))
{
if (m_NrOfFailedFinds < 10)
{
SCX_LOGERROR(m_log, SCXCoreLib::StrAppend(L"Unable to find disk in device map: ", m_device));
++m_NrOfFailedFinds;
}
else if (m_NrOfFailedFinds == 10)
{
SCX_LOGERROR(m_log, SCXCoreLib::StrAppend(L"Unable to find disk in device map: ", m_device)
.append(L" This has happened 10 times in a row for this device and will not be reported again."));
++m_NrOfFailedFinds;
}
return;
}
m_NrOfFailedFinds = 0;
m_timeStamp.AddSample(time(0));
struct pst_lvinfo lvi;
memset(&lvi, 0, sizeof(lvi));
if (di->m_instance < 0 || 1 != m_deps->pstat_getlv(&lvi, sizeof(lvi), 1, di->m_instance))
{ // Check if the struct has moved
di->m_instance = FindLVInfoByID(di->m_devID);
if (di->m_instance < 0 || 1 != m_deps->pstat_getlv(&lvi, sizeof(lvi), 1, di->m_instance))
{
SCX_LOGTRACE(m_log, SCXCoreLib::StrAppend(L"No instance for: ", m_device));
return;
}
}
// Sanity check of cahed instance id
if (di->m_devID != ((lvi.psl_dev.psd_major << 24) | lvi.psl_dev.psd_minor))
{
SCX_LOGWARNING(m_log, L"Instance changed");
di->m_instance = FindLVInfoByID(di->m_devID);
return;
}
m_reads.AddSample(lvi.psl_rxfer);
m_writes.AddSample(lvi.psl_wxfer);
m_rBytes.AddSample(lvi.psl_rcount);
m_wBytes.AddSample(lvi.psl_wcount);
m_transfers.AddSample(m_reads[0] + m_writes[0]);
m_tBytes.AddSample(m_rBytes[0] + m_wBytes[0]);
#elif defined(linux)
std::wstring device = m_device;
std::vector<std::wstring> parts;
std::wstringstream out;
if (!m_samplerDevices.empty())
{
// this is an LVM partition
//
// Note: m_samplerDevices is a vector due to the original v1 implementation.
// After fixing the LVM support for CU5, it could be changed to
// a simple string, but it was left as is to reduce total code
// change.
SCXASSERT( 1 == m_samplerDevices.size() );
device = m_samplerDevices[0];
}
parts = m_deps->GetProcDiskStats(device);
m_timeStamp.AddSample(time(0));
if (parts.size() >= eNumberOfDiskColumns) // > condition for handling additional fields in kernel 4.18+ and 5.5+
{
// this looks like a diskstats entry for a disk-type device
try
{
m_reads.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfReadsCompleted]));
m_writes.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfWritesCompleted]));
m_rBytes.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfSectorsRead])*m_sectorSize);
m_wBytes.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfSectorsWritten])*m_sectorSize);
m_transfers.AddSample(m_reads[0] + m_writes[0]);
m_tBytes.AddSample(m_rBytes[0] + m_wBytes[0]);
}
catch (const SCXCoreLib::SCXNotSupportedException& e)
{
out.str(L"");
out << L"Could not parse disk device line from diskstats for device \"" << device << L"\" - " << e.What();
SCX_LOGWARNING(m_log, out.str());
}
}
else if (parts.size() == eNumberOfPartitionColumns)
{
// this looks like a diskstats entry for a partition-type device
try
{
m_reads.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfReadsIssued]));
m_writes.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfWritesIssued]));
m_rBytes.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfReadSectorRequests])*m_sectorSize);
m_wBytes.AddSample(SCXCoreLib::StrToULong(parts[eNumberOfWriteSectorRequests])*m_sectorSize);
m_transfers.AddSample(m_reads[0] + m_writes[0]);
m_tBytes.AddSample(m_rBytes[0] + m_wBytes[0]);
}
catch (const SCXCoreLib::SCXNotSupportedException& e)
{
out.str(L"");
out << L"Could not parse partition device line from diskstats for device \"" << device << L"\" - " << e.What();
SCX_LOGWARNING(m_log, out.str());
}
}
else
{
static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eWarning, SCXCoreLib::eTrace);
out.str(L"");
// Note: If this message shows up in the logs and the device in question
// shouldn't even be getting enumerated, then maybe the device
// type needs to be added to the list of ignored device types in
// diskdepend (see WI 33450).
out << L"The diskstats map does not contain a key matching the device named \"" << device << L"\", or only " << parts.size() << L" columns were found";
SCX_LOG(m_log, suppressor.GetSeverity(out.str()), out.str());
}
#elif defined(sun)
std::wstringstream out;
out << L"Sample : Entering";
SCX_LOGHYSTERICAL(m_log, out.str());
try
{
if ( ! m_deps->ReadKstat(m_kstat, m_device, m_mountPoint))
{
out.str(L"");
out << L"Sample : Failed : Unable to determine kstat parameters for device " << m_device;
SCX_LOGTRACE(m_log, out.str());
return;
}
}
catch (SCXCoreLib::SCXException& exception)
{
out.str(L"");
out << L"Sample : Error : An unexpected exception prevented reading kstat for device " << m_device
<< L" : " << typeid(exception).name()
<< L" : " << exception.What()
<< L" : " << exception.Where();
SCX_LOGERROR(m_log, out.str());
return;
}
try
{
SCXKstatFSSample sample = m_kstat->GetFSSample();
m_reads.AddSample(sample.GetNumReadOps());
m_writes.AddSample(sample.GetNumWriteOps());
m_transfers.AddSample(m_reads[0] + m_writes[0]);
m_rBytes.AddSample(sample.GetBytesRead());
m_wBytes.AddSample(sample.GetBytesWritten());
m_tBytes.AddSample(m_rBytes[0] + m_wBytes[0]);
out.str(L"");
out << L"Sample : Succeeded : Got kstat sample for device " << m_device
<< L", nR: " << m_reads[0]
<< L", nw: " << m_writes[0]
<< L", bR: " << m_rBytes[0]
<< L", bW: " << m_wBytes[0];
SCX_LOGHYSTERICAL(m_log, out.str());
}
catch (SCXKstatException& exception)
{
out.str(L"");
out << L"Sample : Error : An unexpected exception prevented sampling the kstat data for device " << m_device
<< L" : " << typeid(exception).name()
<< L" : " << exception.What()
<< L" : " << exception.Where();
SCX_LOGERROR(m_log, out.str());
}
#endif
}