PerformanceCounterCategory 클래스
namespace System.Diagnostics
{
public sealed class PerformanceCounterCategory
{
public PerformanceCounterCategory();
public PerformanceCounterCategory(string categoryName);
public PerformanceCounterCategory(string categoryName, string machineName);
public string CategoryHelp { get; }
public string CategoryName { get; set; }
public PerformanceCounterCategoryType CategoryType { get; }
public string MachineName { get; set; }
public static PerformanceCounterCategory[] GetCategories();
public static PerformanceCounterCategory[] GetCategories(string machineName);
// public static PerformanceCounterCategory Create(string categoryName, string categoryHelp, string counterName, string counterHelp);
public static PerformanceCounterCategory Create(string categoryName, string categoryHelp, PerformanceCounterCategoryType categoryType, string counterName, string counterHelp);
// public static PerformanceCounterCategory Create(string categoryName, string categoryHelp, CounterCreationDataCollection counterData);
public static PerformanceCounterCategory Create(string categoryName, string categoryHelp, PerformanceCounterCategoryType categoryType, CounterCreationDataCollection counterData);
public static void Delete(string categoryName);
public static bool Exists(string categoryName, string machineName);
public static bool Exists(string categoryName);
public static bool CounterExists(string counterName, string categoryName);
public static bool CounterExists(string counterName, string categoryName, string machineName);
public static bool InstanceExists(string instanceName, string categoryName);
public static bool InstanceExists(string instanceName, string categoryName, string machineName);
public bool CounterExists(string counterName);
public bool InstanceExists(string instanceName);
public PerformanceCounter[] GetCounters();
public PerformanceCounter[] GetCounters(string instanceName);
public string[] GetInstanceNames();
public InstanceDataCollectionCollection ReadCategory();
}
}
namespace System.Diagnostics
{
public enum PerformanceCounterCategoryType
{
Unknown = -1,
SingleInstance = 0,
MultiInstance = 1
}
}
PerformanceCounter 클래스
namespace System.Diagnostics
{
public sealed class PerformanceCounter : Component, ISupportInitialize
{
// public static int DefaultFileMappingSize;
public PerformanceCounter();
public PerformanceCounter(string categoryName, string counterName);
public PerformanceCounter(string categoryName, string counterName, string instanceName);
public PerformanceCounter(string categoryName, string counterName, bool readOnly);
public PerformanceCounter(string categoryName, string counterName, string instanceName, string machineName);
public PerformanceCounter(string categoryName, string counterName, string instanceName, bool readOnly);
public bool ReadOnly { get; set; }
public string MachineName { get; set; }
public string CategoryName { get; set; }
public string InstanceName { get; set; }
public PerformanceCounterInstanceLifetime InstanceLifetime { get; set; }
public string CounterName { get; set; }
public PerformanceCounterType CounterType { get; }
public string CounterHelp { get; }
public long RawValue { get; set; }
public long Increment();
public long IncrementBy(long value);
public long Decrement();
public float NextValue();
public CounterSample NextSample();
public void BeginInit();
public void EndInit();
public void Close();
public static void CloseSharedResources();
protected override void Dispose(bool disposing);
}
}
namespace System.Diagnostics
{
public enum PerformanceCounterInstanceLifetime
{
Global = 0,
Process = 1
}
}
namespace System.Diagnostics
{
public enum PerformanceCounterType
{
NumberOfItemsHEX32 = 0,
NumberOfItemsHEX64 = 256,
NumberOfItems32 = 65536,
NumberOfItems64 = 65792,
CounterDelta32 = 4195328,
CounterDelta64 = 4195584,
SampleCounter = 4260864,
CountPerTimeInterval32 = 4523008,
CountPerTimeInterval64 = 4523264,
RateOfCountsPerSecond32 = 272696320,
RateOfCountsPerSecond64 = 272696576,
RawFraction = 537003008,
CounterTimer = 541132032,
Timer100Ns = 542180608,
SampleFraction = 549585920,
CounterTimerInverse = 557909248,
Timer100NsInverse = 558957824,
CounterMultiTimer = 574686464,
CounterMultiTimer100Ns = 575735040,
CounterMultiTimerInverse = 591463680,
CounterMultiTimer100NsInverse = 592512256,
AverageTimer32 = 805438464,
ElapsedTime = 807666944,
AverageCount64 = 1073874176,
SampleBase = 1073939457,
AverageBase = 1073939458,
RawBase = 1073939459,
CounterMultiBase = 1107494144
}
}
CounterCreationDataCollection 클래스
namespace System.Diagnostics
{
public class CounterCreationDataCollection : CollectionBase
{
public CounterCreationDataCollection();
public CounterCreationDataCollection(CounterCreationDataCollection value);
public CounterCreationDataCollection(CounterCreationData[] value);
public CounterCreationData this[int index] { get; set; }
public int IndexOf(CounterCreationData value);
public bool Contains(CounterCreationData value);
public int Add(CounterCreationData value);
public void AddRange(CounterCreationData[] value);
public void AddRange(CounterCreationDataCollection value);
public void Insert(int index, CounterCreationData value);
public virtual void Remove(CounterCreationData value);
public void CopyTo(CounterCreationData[] array, int index);
protected override void OnValidate(object value);
}
}
CounterCreationData 클래스
namespace System.Diagnostics
{
public class CounterCreationData
{
public CounterCreationData();
public CounterCreationData(string counterName, string counterHelp, PerformanceCounterType counterType);
public PerformanceCounterType CounterType { get; set; }
public string CounterName { get; set; }
public string CounterHelp { get; set; }
}
}
InstanceDataCollectionCollection 클래스
namespace System.Diagnostics
{
public class InstanceDataCollectionCollection : DictionaryBase
{
// public InstanceDataCollectionCollection();
public InstanceDataCollection this[string counterName] { get; }
public ICollection Keys { get; }
public ICollection Values { get; }
public bool Contains(string counterName);
public void CopyTo(InstanceDataCollection[] counters, int index);
}
}
InstanceDataCollection 클래스
namespace System.Diagnostics
{
public class InstanceDataCollection : DictionaryBase
{
// public InstanceDataCollection(string counterName);
public InstanceData this[string instanceName] { get; }
public string CounterName { get; }
public ICollection Keys { get; }
public ICollection Values { get; }
public bool Contains(string instanceName);
public void CopyTo(InstanceData[] instances, int index);
}
}
InstanceData 클래스
namespace System.Diagnostics
{
public class InstanceData
{
public InstanceData(string instanceName, CounterSample sample);
public string InstanceName { get; }
public CounterSample Sample { get; }
public long RawValue { get; }
}
}
CounterSample 클래스
namespace System.Diagnostics
{
public struct CounterSample
{
public static CounterSample Empty;
public CounterSample(long rawValue, long baseValue, long counterFrequency, long systemFrequency, long timeStamp, longtimeStamp100nSec, PerformanceCounterType counterType);
public CounterSample(long rawValue, long baseValue, long counterFrequency, long systemFrequency, long timeStamp, longtimeStamp100nSec, PerformanceCounterType counterType, long counterTimeStamp);
public long TimeStamp { get; }
public long TimeStamp100nSec { get; }
public long CounterTimeStamp { get; }
public long CounterFrequency { get; }
public long SystemFrequency { get; }
public long BaseValue { get; }
public long RawValue { get; }
public PerformanceCounterType CounterType { get; }
public static float Calculate(CounterSample counterSample);
public static float Calculate(CounterSample counterSample, CounterSample nextCounterSample);
public bool Equals(CounterSample sample);
public override bool Equals(object o);
public override int GetHashCode();
public static bool operator ==(CounterSample a, CounterSample b);
public static bool operator !=(CounterSample a, CounterSample b);
}
}
성능 카운터
- 응용 프로그램, 시스템의 현재 상태를 파악하기 위한 실시간적인 접근 방식
* 응용 프로그램의 성능 카운터(Performance Counter)
* 카운터를 실시간으로 감시하는 MS 관리 콘솔(Microsoft Management Console, MMC) 스냅인들
- 성능 카운터는 여러가지 범주(성능 개체, Performance Object)로 나뉘어져 있음
* System
* Processor
* .NET CLR 메모리
- 하나의 범주 안에 여러개의 인스턴스가 존재 할 수 있음
사용 가능한 성능 카운터 열거
namespace Practice
{
class Program
{
public static void Main(string[] arg)
{
PerformanceCounterCategory[] pcca = PerformanceCounterCategory.GetCategories();
// 각 범주(카테고리)별로 열거
foreach (PerformanceCounterCategory pcc in pcca)
{
Console.WriteLine("범주: " + pcc.CategoryName);
string[] pccInstances = pcc.GetInstanceNames();
// 인스턴스가 하나도 없는 경우
// 범주 자체에 대한 카운터들을 표시
if (pccInstances.Length == 0)
{
foreach (PerformanceCounter pc in pcc.GetCounters())
{
Console.WriteLine(" 카운터: " + pc.CounterName);
}
}
// 인스턴스가 하나 이상인 경우
else
{
// 각 인스턴스별로 열거
foreach (string pccInstance in pccInstances)
{
Console.WriteLine(" 인스턴스: " + pccInstance);
// 인스턴스가 실제 존재하는지 확인해야함
// 이름은 존재하는데, 실제 내용이 없는 경우가 있음
if (pcc.InstanceExists(pccInstance))
{
foreach (PerformanceCounter pc in pcc.GetCounters(pccInstance))
{
Console.WriteLine(" 카운터: " + pc.CounterName);
}
}
}
}
}
}
}
}
- 현재 컴퓨터의 모든 성능 카운터를 열거
- 위 예제는 엄청나게 긴 출력 결과를 포함, InstaceExists의 구현이 효율적이지 않아 오랜 시간이 걸림
- 실제 시스템에서 카운터들에 관한 자세한 정보는 꼭 필요할 때에만 조회해야 함
성능 카운터 자료 읽기
- PerformanceCounter 객체를 생성
* 생성자 - 범주 이름, 카운터 이름, 인스턴스 지정
- NextValue: float
- NextSample: ConuterSample (좀 더 자세한 정보)
using (PerformanceCounter mpc = new PerformanceCounter("Processor", "% Processor Time", "_Total"))
{
Console.WriteLine($"{mpc.CategoryName} - {mpc.InstanceName} - {mpc.CounterName} : {mpc.NextValue()}");
}
string processName = Process.GetCurrentProcess().ProcessName;
using (PerformanceCounter mpc = new PerformanceCounter("Process", "Private Bytes", processName))
{
Console.WriteLine($"{mpc.CategoryName} - {mpc.InstanceName} - {mpc.CounterName} : {mpc.NextValue().ToString("F0")}");
}
- 성능 카운터가 변했을 때 통지를 받고 싶다면 폴링(Polling), 주기적으로 값을 점검해야 함
namespace Practice
{
class Program
{
public static void Main(string[] arg)
{
EventWaitHandle stopper = new ManualResetEvent(false);
new Thread(() => Monitor("Processor", "% Processor Time", "_Total", stopper)).Start();
new Thread(() => Monitor("LogicalDisk", "% Idle Time", "C:", stopper)).Start();
var defaultColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Monitoring... Press any key to exit...");
Console.ForegroundColor = defaultColor;
Console.ReadKey(true);
stopper.Set();
}
static void Monitor (string category, string counter, string instance, EventWaitHandle stopper)
{
// 카테고리 체크
if (!PerformanceCounterCategory.Exists (category))
{
throw new InvalidOperationException("해당 범주 없음");
}
// 카운터 체크
if (!PerformanceCounterCategory.CounterExists(counter, category))
{
throw new InvalidOperationException("해당 카운터 없음");
}
// 인스턴스 체크
if (instance == null)
{
instance = "";
}
if (instance != "" && !PerformanceCounterCategory.InstanceExists(instance, category))
{
throw new InvalidOperationException("해당 인스턴스 없음");
}
// 비교할 기존 값
float lastValue = 0f;
// 체크 반복 딜레이
const int delay = 5000;
using (PerformanceCounter pc = new PerformanceCounter(category, counter, instance))
{
// 딜레이 간격으로 실행
while (!stopper.WaitOne (delay, false))
{
float value = pc.NextValue();
string labelString = $"{pc.CategoryName.PadLeft(15)} - {pc.InstanceName.PadLeft(10)} - {pc.CounterName.PadLeft(10)}";
// 기존 값과 측정 값이 서로 다르다면 출력
if (value != lastValue)
{
Console.WriteLine($"{labelString}: {value}");
lastValue = value;
}
}
}
}
}
}
커스텀 성능 카운터 작성 및 성능 기록
- 생성 : CounterCreationDataCollection 통해 카운터들을 기록, 한번에 범주로 만듬
PerformanceCounterCategory.Create 통해 추가
- 수정: 기존 범주를 삭제하고 수정해서 한번에 다시 올려야 함
- 삭제: PerformanceCounterCategory.Delete
- 기록: 인스턴스화, Readonly 속성을 false로 바꾸고 RawValue를 수정
string category = "Custom Performance Counter";
string counterOne = "Counter One";
string counterTwo = "Counter Two";
// 추가
if (!PerformanceCounterCategory.Exists(category))
{
CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
ccdc.Add(new CounterCreationData(counterOne, "첫번째 커스텀 카운터", PerformanceCounterType.NumberOfItems32));
ccdc.Add(new CounterCreationData(counterTwo, "두번째 커스텀 카운터", PerformanceCounterType.NumberOfItems32));
PerformanceCounterCategory.Create(category, "커스텀 퍼포먼스 카운터", PerformanceCounterCategoryType.SingleInstance, ccdc);
}
// 갱신
using (PerformanceCounter pc = new PerformanceCounter(category, counterOne))
{
pc.ReadOnly = false;
pc.RawValue = 1000; // 1000
pc.Increment(); // 1001
pc.IncrementBy(10); // 1011
pc.Decrement(); // 1010
Console.WriteLine(pc.NextValue());
}
// 삭제
if (PerformanceCounterCategory.Exists(category))
{
PerformanceCounterCategory.Delete(category);
}
'C#' 카테고리의 다른 글
[C#] Stream (0) | 2023.11.17 |
---|---|
[C#] Task (0) | 2023.11.06 |
[C#] Thread (0) | 2023.11.01 |
[C#] Stopwatch (0) | 2023.10.30 |
[C#] EventLog (Windows 이벤트 로그) (0) | 2023.10.26 |
[C#] StackTrace, StackFrame (0) | 2023.10.24 |
[C#] Debugger (0) | 2023.10.22 |
[C#] Contract, Code Contracts(코드 계약) (0) | 2023.10.20 |