外部からdotnet-counterモニターを利用してアプリケーションの監視を開始することができますが、プロセス内で監視指標の収集や表示を行うことも可能です。プロセス内監視の利点として、監視とサービスの分離を完成させるために複数のサービスを起動する必要がなく、アプリケーションが起動するだけで監視指標も生成され、密接な関係にあります。
class Program
{
static void Main()
{
Demo01.Run();
}
}
public class Demo01
{
public static void Run()
{
Console.WriteLine("監視開始");
var listener = new MyEventListener();
listener.WriteEvent += Listener_WriteEvent;
Console.ReadLine();
}
private static void Listener_WriteEvent(string key, string value)
{
Console.WriteLine($"{key}:{value}");
}
}
public delegate void WriteContent(string key, string value);
public class MyEventListener : EventListener
{
protected readonly string[] _countersName = new string[]
{
"System.Runtime"
};
public event WriteContent WriteEvent;
protected override void OnEventSourceCreated(EventSource source)
{
if (_countersName.Contains(source.Name))
{
EnableEvents(source, EventLevel.Verbose, EventKeywords.All, new Dictionary<string, string>()
{
["EventCounterIntervalSec"] = "1"
});
}
}
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
if (!eventData.EventName.Equals("EventCounters"))
{
return;
}
for (int i = 0; i < eventData.Payload.Count; ++i)
{
if (eventData.Payload[i] is IDictionary<string, object> eventPayload)
{
var counterName = "";
var counterValue = "";
if (eventPayload.TryGetValue("DisplayName", out object displayValue))
{
counterName = displayValue.ToString();
}
if (eventPayload.TryGetValue("Mean", out object value) ||
eventPayload.TryGetValue("Increment", out value))
{
counterValue = value.ToString();
}
WriteEvent(counterName, counterValue);
}
}
}
}
イベント監視のサブクラスを使用して、アプリケーション内で監視した指標を収集することができます。_countersNameには監視したいプロバイダーを配置します。《dotnet内のカウンター説明一》、《dotnet内のカウンター説明二》、《dotnet内のカウンター説明三》では、その説明があります。コードの20行目では、指標をコンソールに出力しているだけですが、ここではESに収集させて表示したり、この部分を時系列データベースに書き込んでGrafanaで表示することも可能です。表示については別の話題であり、ここでは詳しく述べません。
(Translated by GPT)