void StatisticalPhysicalDiskInstance::Sample()

in source/code/scxsystemlib/disk/statisticalphysicaldiskinstance.cpp [107:277]


    void StatisticalPhysicalDiskInstance::Sample()
    {
#if defined(aix)
        perfstat_id_t id;
        perfstat_disk_t data;

        memset(&id, 0, sizeof(id));

        std::wstring name = L"";
        static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eError, SCXCoreLib::eInfo);
        if (m_device.substr(0,5) == L"/dev/")
        {
            // Some device paths can have subdirectories inside /dev/, like: /dev/asm/acfs_vol001-41
            // perfstat_disk is expecting id.name to look like "asm/acfs_vol001-41" in this example.
            name = m_device.substr(5);
        }
        else
        {
            std::wstring msg = L"Device path (" + m_device + L") does not begin with /dev/";

            SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(msg));
            SCX_LOG(m_log, severity, msg);
            return;
        }

        strncpy(id.name, SCXCoreLib::StrToUTF8(name).c_str(), sizeof(id.name)-1);
        int retval;
        if (1 == (retval = m_deps->perfstat_disk(&id, &data, sizeof(data), 1)))
        {
            m_transfers.AddSample(data.xfers);
            m_rBytes.AddSample(data.rblks * data.bsize);
            m_wBytes.AddSample(data.wblks * data.bsize);
            m_tBytes.AddSample(m_rBytes[0] + m_wBytes[0]);
            m_tTimes.AddSample(data.time * 1000);

/* XINTFRAC definition now depends on patch level of AIX 6.1 system ... */
#if PF_MAJOR < 7 && !defined(XINTFRAC)

/* See /usr/include/sys/iplcb.h to explain the below */
#define XINTFRAC        (static_cast<double>(_system_configuration.Xint)/static_cast<double>(_system_configuration.Xfrac))

#endif

/* hardware ticks per millisecond */
#define HWTICS2MSECS(x)    ((static_cast<double>(x) * XINTFRAC)/1000000.0)

            m_rTimes.AddSample(HWTICS2MSECS(data.rserv));
            m_wTimes.AddSample(HWTICS2MSECS(data.wserv));
            m_qLengths.AddSample(data.qdepth);
        }
        else
        {
            SCXCoreLib::SCXErrnoException e(L"name = " + name, errno, SCXSRCLOCATION);
            std::wstring msg = L"perfstat_disk failed with retval = " + SCXCoreLib::StrFrom(retval) + L" " + e.What();

            SCXCoreLib::SCXLogSeverity severity(suppressor.GetSeverity(msg));
            SCX_LOG(m_log, severity, msg);
            return;
        }
#elif defined(hpux)
        SCXCoreLib::SCXHandle<DeviceInstance> di = m_deps->FindDeviceInstance(m_device);

        if ((0 == di) || (DiskDepend::s_cINVALID_INSTANCE == di->m_instance))
        {
            SCX_LOGERROR(m_log, L"Unable to find disk in device map");
            return;
        }
        m_timeStamp.AddSample(time(0));
        
        struct pst_diskinfo diski;
        memset(&diski, 0, sizeof(diski)); 
        if (1 != m_deps->pstat_getdisk(&diski, sizeof(diski), 1, di->m_instance))
        {
            SCX_LOGERROR(m_log, L"pstat_getdisk failed");
            return;
        }
        // Sanity check of cahed instance id
        if (di->m_devID != ((diski.psd_dev.psd_major << 24) | diski.psd_dev.psd_minor))
        {
            SCX_LOGWARNING(m_log, L"Instance changed");
            di->m_instance = FindDiskInfoByID(di->m_devID);
            return;
        }
        m_transfers.AddSample(diski.psd_dkxfer);
        m_tBytes.AddSample(diski.psd_dkwds * 64);
        m_tTimes.AddSample(diski.psd_dkresp.pst_sec * 1000 + diski.psd_dkresp.pst_usec / 1000);
        m_waitTimes.AddSample(diski.psd_dkwait.pst_sec * 1000 + diski.psd_dkwait.pst_usec / 1000);
        m_qLengths.AddSample(diski.psd_dkqlen_curr);
#elif defined(linux)
        std::vector<std::wstring> parts = m_deps->GetProcDiskStats(m_device);
        for (size_t i=0; parts.size() == 0 && i < m_samplerDevices.size(); ++i)
        {
            parts = m_deps->GetProcDiskStats(m_samplerDevices[i]);
        }
        m_timeStamp.AddSample(time(0));
        if (parts.size() > 11)
        {
            try
            {
                m_reads.AddSample(SCXCoreLib::StrToULong(parts[3]));
                m_writes.AddSample(SCXCoreLib::StrToULong(parts[7]));
                m_rBytes.AddSample(SCXCoreLib::StrToULong(parts[5])*m_sectorSize);
                m_wBytes.AddSample(SCXCoreLib::StrToULong(parts[9])*m_sectorSize);
                m_rTimes.AddSample(SCXCoreLib::StrToULong(parts[6]));
                m_wTimes.AddSample(SCXCoreLib::StrToULong(parts[10]));
                m_transfers.AddSample(m_reads[0] + m_writes[0]);
                m_tBytes.AddSample(m_rBytes[0] + m_wBytes[0]);
                m_qLengths.AddSample(SCXCoreLib::StrToULong(parts[11]));
            }
            catch (const SCXCoreLib::SCXNotSupportedException& e)
            {
                SCX_LOGWARNING(m_log, std::wstring(L"Could not parse line from diskstats: ").append(L" - ").append(e.What()));
            }
        }
#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))
            {
                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
        {
            m_reads.AddSample(m_kstat->GetValue(L"reads"));
            m_writes.AddSample(m_kstat->GetValue(L"writes"));
            m_transfers.AddSample(m_reads[0] + m_writes[0]); 
            m_rBytes.AddSample(m_kstat->GetValue(L"nread"));
            m_wBytes.AddSample(m_kstat->GetValue(L"nwritten"));
            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
    }