通过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,《dotnet中的counters说明一》,《dotnet中的counters说明二》,《dotnet中的counters说明三》里有说明。
代码20行处,只是把指标输出到控制台上了,这里可以让ES进行收集,进行展示;也可以把这里换成,写入到时序数据库中,用Grafana进行展示,并于展示是另一个话题,这里就行进行展开说明了。