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)); }
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)); }
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 }); }
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 }; }
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); }
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; }