通过dotnet-counter moniter可以在应用外部启动监控应用,当然也可以在进程内来来进行监控指标的收集或展示。
进程内监控的好处是不用启用多个服务来完成监控和服务的分离,只要应用启动,监控指标也就产生,是紧密关系。
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秒中收集一次监控指标
["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 可以放置要监控的provider。
代码20行处,只是把指标输出到控制台上了,这里可以让ES进行收集,进行展示;也可以把这里换成,写入到时序数据库中,用Grafana进行展示,并于展示是另一个话题,这里就行进行展开说明了。