예제 #1
0
        public PerformanceCounterSampleSet ReadNextSet()
        {
            this._firstRead.Wait();
            long fileTimeStamp = 0;
            uint returnCode    = this._isPreVista ? Apis.PdhCollectQueryData(this._safeQueryHandle)
                                : Apis.PdhCollectQueryDataWithTime(this._safeQueryHandle, ref fileTimeStamp);

            if (this._isLastSampleBad)
            {
                return(null);
            }
            if (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA)
            {
                //this makes sure next call to ReadNextSet doesn't examine the data, and just returns null
                this._isLastSampleBad = true;
                return(null);
            }

            DateTime now = (_isPreVista || returnCode == PdhResults.PDH_NO_DATA) ? DateTime.Now :
                           new DateTime(DateTime.FromFileTimeUtc(fileTimeStamp).Ticks, DateTimeKind.Local);

            PerformanceCounterSample[] counterSamples = new PerformanceCounterSample[this._consumerPathToHandleAndInstanceMap.Count];
            int samplesRead = 0;

            foreach (string key in this._consumerPathToHandleAndInstanceMap.Keys)
            {
                IntPtr      counterHandle = this._consumerPathToHandleAndInstanceMap[key].CounterHandle;
                CounterInfo info          = PdhHelper.GetCounterInfo(counterHandle);

                var sample            = GetRawCounterSample(counterHandle, key, info, now);
                var performanceSample = sample.PerformanceCounterSample ?? GetFormattedCounterSample(counterHandle, key, info, sample.RawCounter);

                if (!this._ignoreBadStatusCodes && (performanceSample.Status != 0))
                {
                    throw BuildException(performanceSample.Status);
                }

                if (performanceSample.Status != 0)
                {
                    _log.Info(() => string.Format("Status {0:x} ignored for counter {1}", performanceSample.Status, key));
                    continue;
                }
                counterSamples[samplesRead++] = performanceSample;
            }

            this._isLastSampleBad = false;
            //in the event we skipped bad data
            if (samplesRead < counterSamples.Length)
            {
                Array.Resize(ref counterSamples, samplesRead);
            }
            return(new PerformanceCounterSampleSet(this._isPreVista ? counterSamples[samplesRead].Timestamp : now, counterSamples));
        }
예제 #2
0
        private PerformanceCounterSample GetFormattedCounterSample(IntPtr counterHandle, string name, CounterInfo info, PDH_RAW_COUNTER rawCounter)
        {
            IntPtr   counterType = new IntPtr(0);
            long     fileTime    = (((long)rawCounter.TimeStamp.dwHighDateTime) << 0x20) + rawCounter.TimeStamp.dwLowDateTime;
            DateTime timeStamp2  = new DateTime(DateTime.FromFileTimeUtc(fileTime).Ticks, DateTimeKind.Local);
            PDH_FMT_COUNTERVALUE_DOUBLE doubleFormattedCounter;
            uint returnCode = Apis.PdhGetFormattedCounterValue(counterHandle, PdhFormat.PDH_FMT_NOCAP100 + PdhFormat.PDH_FMT_DOUBLE, out counterType, out doubleFormattedCounter);

            //vista and above, any non-valid result is returned like this
            if ((!_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA)) ||
                //below vista, return data for no_data and invalid_data, otherwise throw
                (_isPreVista && (returnCode == PdhResults.PDH_INVALID_DATA || returnCode == PdhResults.PDH_NO_DATA)))
            {
                return(new PerformanceCounterSample(name, this._consumerPathToHandleAndInstanceMap[name].InstanceName,
                                                    0.0, (ulong)rawCounter.FirstValue, (ulong)rawCounter.SecondValue, rawCounter.MultiCount,
                                                    //TODO: not sure if its useful to stuff a bad returnCode in for status, as VerifySamples will throw when status isn't 0... not sure that's useful
                                                    //TODO: original code just uses pdh_raw_counter.CStatus when _isPreVista
                                                    (PerformanceCounterType)info.Type, info.DefaultScale, info.TimeBase, timeStamp2, (ulong)fileTime, (doubleFormattedCounter.CStatus == 0) ? returnCode : rawCounter.CStatus));
            }
            else if (_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA))
            {
                throw BuildException(returnCode);
            }

            return(new PerformanceCounterSample(name, this._consumerPathToHandleAndInstanceMap[name].InstanceName,
                                                doubleFormattedCounter.doubleValue, (ulong)rawCounter.FirstValue, (ulong)rawCounter.SecondValue, rawCounter.MultiCount,
                                                (PerformanceCounterType)counterType.ToInt32(), info.DefaultScale, info.TimeBase, timeStamp2, (ulong)fileTime, doubleFormattedCounter.CStatus));
        }
예제 #3
0
        private RawCounterSample GetRawCounterSample(IntPtr counterHandle, string key, CounterInfo info, DateTime?now)
        {
            IntPtr          counterType = new IntPtr(0);
            PDH_RAW_COUNTER rawCounter;
            uint            returnCode = Apis.PdhGetRawCounterValue(counterHandle, out counterType, out rawCounter);

            //vista and above, any non-valid result is returned like this
            if ((!_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA)) ||
                //below vista, return data for no_data and invalid_data, otherwise throw
                (_isPreVista && (returnCode == PdhResults.PDH_INVALID_DATA || returnCode == PdhResults.PDH_NO_DATA)))
            {
                DateTime timeStamp = this._isPreVista ? DateTime.Now : now.Value;
                return(new RawCounterSample()
                {
                    PerformanceCounterSample = new PerformanceCounterSample(key, this._consumerPathToHandleAndInstanceMap[key].InstanceName,
                                                                            0.0, 0L, 0L, 0,
                                                                            //TODO: original code just uses pdh_raw_counter.CStatus when _isPreVista
                                                                            //TODO: not sure if its useful to stuff a bad returnCode in for status, as VerifySamples will throw when status isn't 0... not sure that's useful
                                                                            PerformanceCounterType.RawBase, info.DefaultScale, info.TimeBase, timeStamp, (ulong)timeStamp.ToFileTime(), (rawCounter.CStatus == 0) ? returnCode : rawCounter.CStatus)
                });
            }
            else if (_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA))
            {
                throw BuildException(returnCode);
            }

            //this is only used when return code is 0 -- PdhResults.PDH_CSTATUS_VALID_DATA
            return(new RawCounterSample()
            {
                RawCounter = rawCounter
            });
        }
예제 #4
0
        private RawCounterSample GetRawCounterSample(IntPtr counterHandle, string key, CounterInfo info, DateTime? now)
        {
            IntPtr counterType = new IntPtr(0);
            PDH_RAW_COUNTER rawCounter;
            uint returnCode = Apis.PdhGetRawCounterValue(counterHandle, out counterType, out rawCounter);
            //vista and above, any non-valid result is returned like this
            if ((!_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA)) ||
                //below vista, return data for no_data and invalid_data, otherwise throw
                (_isPreVista && (returnCode == PdhResults.PDH_INVALID_DATA || returnCode == PdhResults.PDH_NO_DATA)))
            {
                DateTime timeStamp = this._isPreVista ? DateTime.Now : now.Value;
                return new RawCounterSample()
                {
                    PerformanceCounterSample = new PerformanceCounterSample(key, this._consumerPathToHandleAndInstanceMap[key].InstanceName,
                    0.0, 0L, 0L, 0,
                        //TODO: original code just uses pdh_raw_counter.CStatus when _isPreVista
                        //TODO: not sure if its useful to stuff a bad returnCode in for status, as VerifySamples will throw when status isn't 0... not sure that's useful
                    PerformanceCounterType.RawBase, info.DefaultScale, info.TimeBase, timeStamp, (ulong)timeStamp.ToFileTime(), (rawCounter.CStatus == 0) ? returnCode : rawCounter.CStatus)
                };
            }
            else if (_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA))
            {
                throw BuildException(returnCode);
            }

            //this is only used when return code is 0 -- PdhResults.PDH_CSTATUS_VALID_DATA
            return new RawCounterSample() { RawCounter = rawCounter };
        }
예제 #5
0
        private PerformanceCounterSample GetFormattedCounterSample(IntPtr counterHandle, string name, CounterInfo info, PDH_RAW_COUNTER rawCounter)
        {
            IntPtr counterType = new IntPtr(0);
            long fileTime = (((long)rawCounter.TimeStamp.dwHighDateTime) << 0x20) + rawCounter.TimeStamp.dwLowDateTime;
            DateTime timeStamp2 = new DateTime(DateTime.FromFileTimeUtc(fileTime).Ticks, DateTimeKind.Local);
            PDH_FMT_COUNTERVALUE_DOUBLE doubleFormattedCounter;
            uint returnCode = Apis.PdhGetFormattedCounterValue(counterHandle, PdhFormat.PDH_FMT_NOCAP100 + PdhFormat.PDH_FMT_DOUBLE, out counterType, out doubleFormattedCounter);

            //vista and above, any non-valid result is returned like this
            if ((!_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA)) ||
                //below vista, return data for no_data and invalid_data, otherwise throw
                (_isPreVista && (returnCode == PdhResults.PDH_INVALID_DATA || returnCode == PdhResults.PDH_NO_DATA)))
            {
                return new PerformanceCounterSample(name, this._consumerPathToHandleAndInstanceMap[name].InstanceName,
                    0.0, (ulong)rawCounter.FirstValue, (ulong)rawCounter.SecondValue, rawCounter.MultiCount,
                    //TODO: not sure if its useful to stuff a bad returnCode in for status, as VerifySamples will throw when status isn't 0... not sure that's useful
                    //TODO: original code just uses pdh_raw_counter.CStatus when _isPreVista
                    (PerformanceCounterType)info.Type, info.DefaultScale, info.TimeBase, timeStamp2, (ulong)fileTime, (doubleFormattedCounter.CStatus == 0) ? returnCode : rawCounter.CStatus);
            }
            else if (_isPreVista && (returnCode != PdhResults.PDH_CSTATUS_VALID_DATA))
            {
                throw BuildException(returnCode);
            }

            return new PerformanceCounterSample(name, this._consumerPathToHandleAndInstanceMap[name].InstanceName,
                doubleFormattedCounter.doubleValue, (ulong)rawCounter.FirstValue, (ulong)rawCounter.SecondValue, rawCounter.MultiCount,
                (PerformanceCounterType)counterType.ToInt32(), info.DefaultScale, info.TimeBase, timeStamp2, (ulong)fileTime, doubleFormattedCounter.CStatus);
        }
예제 #6
0
        private static CounterInfo GetCounterInfo(IntPtr counterHandle)
        {
            CounterInfo info = new CounterInfo();

            IntPtr counterBufferSize = new IntPtr(0);
            uint returnCode = Apis.PdhGetCounterInfo(counterHandle, false, ref counterBufferSize, IntPtr.Zero);

            if (returnCode != PdhResults.PDH_MORE_DATA)
            {
                return info;
            }

            IntPtr bufferPointer = Marshal.AllocHGlobal(counterBufferSize.ToInt32());
            try
            {
                if ((Apis.PdhGetCounterInfo(counterHandle, false, ref counterBufferSize, bufferPointer) == PdhResults.PDH_CSTATUS_VALID_DATA) && (bufferPointer != IntPtr.Zero))
                {
                    info.Type = (uint)Marshal.ReadInt32(bufferPointer, 4);
                    info.DefaultScale = (uint)Marshal.ReadInt32(bufferPointer, 20);
                }
            }
            finally
            {
                Marshal.FreeHGlobal(bufferPointer);
            }

            ulong timeBase;
            Apis.PdhGetCounterTimeBase(counterHandle, out timeBase);
            info.TimeBase = timeBase;

            return info;
        }