{"id":1041,"date":"2014-01-06T13:00:43","date_gmt":"2014-01-06T13:00:43","guid":{"rendered":"http:\/\/writeasync.net\/?p=1041"},"modified":"2013-12-30T16:20:53","modified_gmt":"2013-12-30T16:20:53","slug":"using-pla-dll-to-create-alerts","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=1041","title":{"rendered":"Using PLA.dll to create alerts"},"content":{"rendered":"<p>In previous posts I&#8217;ve covered how to collect <a href=\"http:\/\/writeasync.net\/?p=711\">perf counters<\/a> and <a href=\"http:\/\/writeasync.net\/?p=891\">ETW trace logs<\/a> using PLA.dll. Today I will discuss the &#8220;A&#8221; of PLA &#8212; performance counter <strong>alerts<\/strong>. What are alerts good for? Well, quoting from <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/cc722414.aspx\">MSDN<\/a>, &#8220;You can create a custom Data Collector Set containing performance counters and configure alert activities based on the performance counters exceeding or dropping below limits you define.&#8221;<\/p>\n<p>I had to add a few new types to the sample to support creating alerts. (As always, you can go to the <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/tree\/master\/projects\/PlaSample\">PlaSample project on GitHub<\/a> to get the code.)<\/p>\n<p>First, we need the notion of an alert threshold based on a performance counter value, specifically whether a named counter has risen above or fallen below a target value. Hence, <code>CounterThreshold<\/code> and <code>ThresholdCondition<\/code> (<code>CounterName<\/code> was already conveniently present from the previous code to create perf counter logs.)<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic enum ThresholdCondition\r\n{\r\n    Above = 0,\r\n    Below = 1\r\n}\r\n\r\npublic class CounterThreshold\r\n{\r\n    public CounterThreshold()\r\n    {\r\n    }\r\n\r\n    public CounterName Name { get; set; }\r\n\r\n    public ThresholdCondition Condition { get; set; }\r\n\r\n    public double Value { get; set; }\r\n\r\n    public override string ToString()\r\n    {\r\n        string condition = null;\r\n        switch (this.Condition)\r\n        {\r\n            case ThresholdCondition.Above:\r\n                condition = &quot;&gt;&quot;;\r\n                break;\r\n            case ThresholdCondition.Below:\r\n                condition = &quot;&lt;&quot;;\r\n                break;\r\n        }\r\n\r\n        return this.Name + condition + this.Value;\r\n    }\r\n}\r\n<\/pre>\n<p>PLA requires the threshold text in a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa371892(v=vs.85).aspx\">very specific format<\/a> which is provided by the <code>ToString()<\/code> method above.<\/p>\n<p>And now the <code>CounterAlertInfo<\/code> class which defines a few properties for the alert in question:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class CounterAlertInfo\r\n{\r\n    public CounterAlertInfo(string name)\r\n    {\r\n        this.Name = name;\r\n        this.Thresholds = new List&lt;CounterThreshold&gt;();\r\n    }\r\n\r\n    public string Name { get; private set; }\r\n\r\n    public IList&lt;CounterThreshold&gt; Thresholds { get; private set; }\r\n\r\n    public TimeSpan? SampleInterval { get; set; }\r\n}\r\n<\/pre>\n<p>Note that an alert will be fired for every threshold in the list which is reached. The main reason to group many under a single alert collector is so you can execute the same action for a set of thresholds. In this sample, I simply set the alert to write an event log entry. Here is the code to set it all up:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic ICollectorSet Create()\r\n{\r\n    \/\/ Data collector set is the core abstraction for collecting diagnostic data.\r\n    DataCollectorSet dcs = new DataCollectorSet();\r\n\r\n    \/\/ Create a data collector for a perf counter alert.\r\n    IAlertDataCollector dc = (IAlertDataCollector)dcs.DataCollectors.CreateDataCollector(DataCollectorType.plaAlert);\r\n    dc.name = this.Name + &quot;_DC&quot;;\r\n    dcs.DataCollectors.Add(dc);\r\n\r\n    \/\/ Set sample interval, if present.\r\n    if (this.SampleInterval.HasValue)\r\n    {\r\n        dc.SampleInterval = (uint)this.SampleInterval.Value.TotalSeconds;\r\n    }\r\n\r\n    \/\/ Set collector to create an event log entry when threshold is reached.\r\n    dc.EventLog = true;\r\n\r\n    \/\/ Build up the list of alert thresholds.\r\n    string&#x5B;] alertThresholds = new string&#x5B;this.Thresholds.Count];\r\n    for (int i = 0; i &lt; this.Thresholds.Count; ++i)\r\n    {\r\n        alertThresholds&#x5B;i] = this.Thresholds&#x5B;i].ToString();\r\n    }\r\n\r\n    dc.AlertThresholds = alertThresholds;\r\n\r\n    \/\/ Now actually create (or modify existing) the set.\r\n    dcs.Commit(this.Name, null, CommitMode.plaCreateOrModify);\r\n\r\n    \/\/ Return an opaque wrapper with which the user can control the session.\r\n    return new CollectorSetWrapper(dcs);\r\n}\r\n<\/pre>\n<p>Finally, some application code to create an alert that fires whenever the CPU utilization of Notepad falls below five percent for an interval of two seconds:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nCounterAlertInfo info = new CounterAlertInfo(&quot;MyAlert&quot;);\r\n\r\ninfo.SampleInterval = TimeSpan.FromSeconds(2.0d);\r\n\r\nCounterName counterName = new CounterName() { Category = &quot;Process&quot;, Counter = &quot;% Processor Time&quot;, Instance = &quot;notepad&quot; };\r\ninfo.Thresholds.Add(new CounterThreshold() { Name = counterName, Condition = ThresholdCondition.Below, Value = 5.0d });\r\n\r\nICollectorSet collector = info.Create();\r\ncollector.Start();\r\n\r\nThread.Sleep(5000);\r\n\r\ncollector.Stop();\r\n\r\ncollector.Delete();\r\n<\/pre>\n<p>When the alert fires, it will write event 2031 to the <strong>Microsoft\/Windows\/Diagnosis-PLA<\/strong> Operational log containing the details. You can see the information in <a href=\"http:\/\/windows.microsoft.com\/en-us\/windows\/open-event-viewer\">Event Viewer<\/a>. The above alert would produce event details similar to the following:<\/p>\n<blockquote><p>Performance counter \\Process(notepad)\\% Processor Time has tripped its alert threshold. The counter value of 0.000000 is under the limit value of 5.000000. 5.000000 is the alert threshold value.<\/p><\/blockquote>\n<p>In a later post, I will discuss some practical uses of performance counter alerts in automated testing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In previous posts I&#8217;ve covered how to collect perf counters and ETW trace logs using PLA.dll. Today I will discuss the &#8220;A&#8221; of PLA &#8212; performance counter alerts. What are alerts good for? Well, quoting from MSDN, &#8220;You can create&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[],"class_list":["post-1041","post","type-post","status-publish","format-standard","hentry","category-diagnostics"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/1041","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1041"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/1041\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1041"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1041"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}