2013-04-10 42 views
14

Được rồi, Vì vậy, về cơ bản tôi đang cố gắng tạo danh sách các Danh mục truy cập hiệu suất đã cài đặt, giống như danh sách bạn nhận được trong PerfMon. Đối với điều này, tôi đang sử dụngPerformanceCounterCategory.GetCategories không phù hợp với Perfmon

System.Diagnostics.PerformanceCounterCategory.GetCategories() 

có vẻ như nó hoạt động, cho đến khi bạn kiểm tra danh sách và tìm ra rằng một số bị thiếu. Cái đầu tiên tôi phát hiện bị thiếu là ReadyBoost Cache. Điều này là do dự án được thiết lập để biên dịch trên "x86". Thay đổi điều này thành "Bất kỳ CPU" đã khắc phục sự cố đó.

Tuy nhiên, vẫn còn một số mất tích, ví dụ, một trong các máy thử nghiệm có Danh mục "Ứng dụng quản lý ủy quyền" (không, và không ai biết tại sao hoặc ở đâu) Tuy nhiên, trên máy đó, Category Counter Performance hiển thị trong PerfMon, nhưng không phải khi gọi phương thức GetCategories() từ C#.

Có ai biết tại sao không? Có cách nào đáng tin cậy hơn để nhận được PerformanceCounterCategories không? Đây có phải là vì tôi đang sử dụng .Net? Có một số API gốc tôi có thể sử dụng thay thế không?

EDIT

Tôi xin lỗi, tôi vẫn không nhận được nó. Tôi đã viết mã này để có thể minh họa tốt hơn cho nó:

using System; 
using System.Diagnostics; 
using System.Linq; 
using System.Text.RegularExpressions; 
using Microsoft.Win32; 

namespace PccHack 
{ 
    class Program 
    { 
     private static readonly Regex Numeric = new Regex(@"^\d+$"); 
     static void Main(string[] args) 
     { 
      var pcc1 = PerformanceCounterCategory.GetCategories(); 
      Console.Out.WriteLine("Getting automatically from the microsoft framework gave {0} results.", pcc1.Count()); 
      string[] counters; 
      using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009")) 
      { 
       counters = regKey.GetValue("Counter") as string[]; 
      } 
      var pcc2 = counters.Where(counter => !Numeric.IsMatch(counter)).ToList(); 
      pcc2.Sort(); 
      Console.Out.WriteLine("Getting manually from the registry gave {0} results.", pcc2.Count()); 
      Console.In.ReadLine(); 
     } 
    } 
} 

Điều này giờ đây mang lại cho tôi 3236 kết quả. Bởi vì nó nhận được tất cả các bộ đếm hiệu suất trong hệ thống. Vì vậy, tôi hình tất cả những gì tôi cần làm là lọc ra những người thực sự là quầy hiệu suất, để lại cho tôi chỉ với các loại. Tuy nhiên có vẻ như không phải là một nhà xây dựng cho PerformanceCounter mà chỉ mất tên (vì đây không phải là duy nhất), cũng không có vẻ như là một trong đó có giá trị chỉ số. Tôi đã phát hiện ra một API Win32 có tên Performance Data Helper, nhưng điều này dường như không có chức năng mà tôi muốn. Vì thế. Nếu tôi có một chỉ số hiệu suất truy cập, làm thế nào để tôi, trong C# có được PerformanceCounterCategory, cho chỉ mục đó? PerfMon làm điều đó, vì vậy nó phải có thể. Có cách nào để phân tích Index "Magic Number" để tìm ra cái nào?

EDIT 2

Được rồi. Vì vậy, đây đang làm đầu tôi trong Phiên bản mới nhất của mã bằng cách sử dụng ba cách tiếp cận khác nhau đề nghị (Net/Registry/PowerShell):.

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Reflection; 
using Microsoft.Win32; 
using System.Management.Automation; 


namespace PccHack 
{ 
    internal class Program 
    { 
     private static void Main() 
     { 
      var counterMap = new Dictionary<string, string>(); 
      using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009")) 
      { 
       var counter = regKey.GetValue("Counter") as string[]; 
       for (var i = 0; i < counter.Count() - 1; i += 2) 
       { 
        counterMap.Add(counter[i], counter[i + 1]); 
       } 
      } 

      var pcc1 = PerformanceCounterCategory.GetCategories().Select(o => o.CategoryName).ToList(); 
      var pcc2 = new List<string>(); 
      // Get v1 providers 
      using (var regKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\services")) 
      { 
       foreach (var subKeyName in regKey.GetSubKeyNames()) 
       { 
        using (var subKey = regKey.OpenSubKey(subKeyName)) 
        { 
         if (!subKey.GetSubKeyNames().Contains("Performance")) continue; 
         using (var perfKey = subKey.OpenSubKey("Performance")) 
         { 
          var blah = (string) perfKey.GetValue("Object List"); 
          if (blah != null) 
          { 
           pcc2.AddRange(blah.Split(' ').Select(b => counterMap[b])); 
          } 
         } 
        } 
       } 
      } 
      // Get v2 providers 
      using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\_V2Providers")) 
      { 
       foreach (var subKeyName in regKey.GetSubKeyNames()) 
       { 
        using (var subKey = regKey.OpenSubKey(subKeyName)) 
        { 
         foreach (var perfKeyName in subKey.GetSubKeyNames()) 
         { 
          using (var perfKey = subKey.OpenSubKey(perfKeyName)) 
          { 
           var blah = (string) perfKey.GetValue("NeutralName"); 
           if (blah != null) 
           { 
            pcc2.Add(blah); 
           } 
          } 
         } 
        } 
       } 
      } 
      var ps = PowerShell.Create(); 

      ps.AddCommand("Get-Counter").AddParameter("listSet", "*"); 
      var pcc3 = ps.Invoke().Select(result => result.Members["CounterSetName"].Value.ToString()).ToList(); 

      pcc1.Sort(); 
      pcc2.Sort(); 
      pcc3.Sort(); 
      Console.Out.WriteLine("Getting automatically from the microsoft framework gave {0} results.", pcc1.Count()); 
      Console.Out.WriteLine("Getting manually from the registry gave {0} results.", pcc2.Count()); 
      Console.Out.WriteLine("Getting from PowerShell gave {0} results.", pcc3.Count()); 
      Console.In.ReadLine(); 
     } 
    } 
} 

Trên máy tính của tôi tôi nhận được 138 bằng cách sử dụng .Net framework, 117 bởi phân tích sổ đăng ký và 157 bằng cách sử dụng PowerShell (đó là câu trả lời đúng).

Tuy nhiên tùy thuộc vào người dùng đã cài đặt PowerShell/Windows SDK không thực sự là một tùy chọn.

Bất kỳ ai cũng có ý tưởng nào? Có một số loại phiên bản truy cập hiệu suất 3 bí mật hàng đầu, ẩn ở một nơi khác trong sổ đăng ký, mà tôi cần theo dõi không? Tôi đã không chỉ chạy ra khỏi ý tưởng để thử, tôi đã chạy ra khỏi những ý tưởng xấu để thử là tốt. Có bất kỳ thiết bị chuyển mạch dòng lệnh bí mật nào tôi có thể sử dụng trên perfmon, để có được danh sách tất cả các Danh mục không?

+2

Tôi tìm thấy đoạn mã PowerShell này 'Get-Counter –listSet * | Chọn-Object -ExpandProperty Paths' (nguồn: http://blogs.msdn.com/b/powershell/archive/2009/04/21/v2-quick-tip-monitoring-performance-counters-with-powershell.aspx) . –

+0

Cảm ơn. Nhưng tôi cần phải làm điều này theo chương trình. Quan trọng hơn là tôi không thể dựa vào người dùng cuối có cài đặt PowerShell. Tôi chưa cài đặt PowerShell. :) –

Trả lời

1

Bộ đếm hiệu suất (và danh mục) được đăng ký cho mỗi khu vực. Nghĩa là, bạn có thể có các tên khác nhau cho chúng tùy thuộc vào ngôn ngữ.

Tất cả các danh mục hiệu suất có sẵn và bộ đếm của chúng được đăng ký trong Windows Registry dưới HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib. Bạn sẽ tìm thấy khóa phụ cho từng ngôn ngữ có sẵn (ví dụ:009 cho tiếng Anh).

Phương pháp PerformanceCounterCategory.GetCategories() hoạt động nội bộ trước hết là kiểm tra danh mục "văn hóa bất biến". Nếu nó tìm thấy bất kỳ nó sẽ trả lại bộ này. Vì vậy, nếu do một số lỗi hoặc giám sát của nhà cung cấp, một danh mục chỉ có sẵn với một ngôn ngữ, bạn sẽ không nhận được tùy thuộc vào cài đặt ngôn ngữ hiện tại của bạn (cả hệ điều hành hoặc ứng dụng hoặc cả hai).

Trước tiên tôi sẽ kiểm tra nội dung của các phím HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\<langcode>\Counter và xem liệu danh mục bị thiếu có chỉ thuộc một trong số chúng hay không. Một vấn đề liên quan có thể là this (Google search), nhưng tôi chưa kiểm tra thêm.

Thẳng thắn, tôi không biết cách nào "tốt hơn" để có danh sách các quầy sẵn có. Nếu vấn đề của bạn là vấn đề được mô tả ở trên (hoặc có liên quan), tôi thà cố gắng xem xét để khắc phục tình huống.

+0

Điều này cho kết quả thậm chí ít hơn. Xem chỉnh sửa được đề cập. –

2

Tôi nghĩ rằng bạn đang chạy vào những gì tôi sẽ đủ điều kiện dưới dạng lỗi .NET Framework do bộ đếm Perflib v2 gây ra.

Phía sau hậu trường, PerformanceCounterCategory sử dụng Registry Functions để nhận thông tin về các danh mục (còn gọi là đối tượng), trường hợp và quầy hiện được đăng ký với Hệ thống con hiệu suất. Bạn có thể xác minh điều này bằng cách xem mã cho PerformanceCounterCategory với ILSpy.

Bộ đếm có thể được đăng ký thông qua hai loại nhà cung cấp: nhà cung cấp "lõi" và nhà cung cấp "khả năng mở rộng". Những tên này được phát minh bởi tôi vì thiếu một lựa chọn tốt hơn.

Các nhà cung cấp chính được xây dựng sâu vào Windows và giao tiếp với hệ thống con hiệu suất để cung cấp các quầy như Quy trình, Hệ thống, v.v. Nếu bạn không thể xem loại quầy này qua PerformanceCounterCategory, rất có khả năng bạn có một số vấn đề sâu với cài đặt Windows và ít nhất một số trong số these errors trong Nhật ký sự kiện của bạn. Tôi cho rằng đây không phải là trường hợp của bạn.

Giao diện nhà cung cấp có thể mở rộng với Hệ thống con hiệu suất qua tài liệu Perflib interface để cung cấp tất cả các bộ đếm khác. Điều quan trọng cần lưu ý là các bộ đếm cho một số tính năng của Windows được đăng ký thông qua các nhà cung cấp mở rộng, cũng như các bộ đếm cho các sản phẩm MS chính như SQL Server, .NET Framework, v.v. -các nhà cung cấp cho bên thứ ba.

Nếu bạn không thể nhìn thấy thông qua PerformanceCounterCategory quầy được đăng ký thông qua Perflib, đầu tiên có thể nhà cung cấp của họ được định cấu hình không chính xác trong hệ thống hoặc cấu hình đã bị hỏng. Trong trường hợp này, bạn nên có trong Nhật ký sự kiện của bạn một số lỗi được xác định trong phần Tính năng tải xuống hiệu năng hoặc tính khả dụng của Thư viện hiệu suất từ ​​these docs. Tôi cho rằng đây không phải là trường hợp của bạn.

Lý do thứ hai liên quan đến cách nhà cung cấp Perflib hoạt động sau hậu trường. Cần có hai bước chính để đăng ký quầy. Bước đầu tiên là viết cấu hình cho các nhà cung cấp trong Registry bằng cách sử dụng LodCtr.exe. Tôi cho rằng điều này đã được thực hiện tự động cho bạn bởi các trình cài đặt của các quầy mà bạn đang xen vào và cấu hình là chính xác, đặc biệt vì nếu có sự cố với cấu hình này, bạn có thể gặp phải một số lỗi đã nêu ở trên Đăng nhập. Bước thứ hai là thực sự đăng ký nhà cung cấp Perflib với hệ thống con Hiệu suất.

Bây giờ chúng tôi đang gặp vấn đề. Việc đăng ký được thực hiện rất khác nhau đối với các nhà cung cấp Perflib v1 và v2. Đối với v1 mã cho các nhà cung cấp được viết bằng DLL được tham chiếu từ cấu hình Registry được viết ở bước một và được tải bởi chính hệ thống.Do đó, đăng ký nhà cung cấp Perflib v1 sẽ tự động xảy ra khi hệ thống đọc thông tin cấu hình từ Registry và tải các tệp DLL. Đối với các nhà cung cấp Perflib v2, mọi thứ khác nhau. Mã cho các nhà cung cấp không còn được thực thi trực tiếp bởi hệ thống mà bởi một ứng dụng/dịch vụ liên kết với các nhà cung cấp. Vì vậy, nếu bạn viết một ứng dụng tạo các nhà cung cấp/bộ đếm tùy chỉnh bằng Perflib v2, ứng dụng của bạn cũng sẽ chạy mã để thu thập dữ liệu cho các nhà cung cấp này và nó sẽ giao tiếp với hệ thống con Hiệu suất theo cách được ghi nhận. Vấn đề là, mã thực hiện đăng ký của các nhà cung cấp Perflib v2 với hệ thống hiện phải được kích hoạt bởi ứng dụng lưu trữ mã nhà cung cấp (trái ngược với việc được kích hoạt tự động bởi hệ thống như đối với Perflib v1). Vì vậy, ví dụ, nếu ứng dụng là một dịch vụ Windows và dịch vụ chưa bắt đầu, các nhà cung cấp sẽ không được đăng ký với hệ thống con Hiệu suất và các quầy của họ sẽ không hiển thị (chưa) thông qua các Chức năng Đăng ký/PerformanceCounterCategory.

Here là phần có liên quan của doc mô tả này tự đăng ký cho các nhà cung cấp Perflib v2:

cung cấp dịch vụ của quý vị phải gọi các chức năng CounterInitialize và CounterCleanup. CounterInitialize gọi hàm PerfStartProvider để đăng ký nhà cung cấp và cũng gọi hàm PerfSetCounterSetInfo để khởi tạo bộ đếm. CounterCleanup gọi hàm PerfStopProvider để xóa đăng ký của nhà cung cấp.

Trong kết luận, có hai cách khác nhau để liệt kê danh mục, trường hợp và quầy. Một là để truy vấn các chức năng đăng ký và liệt kê tất cả các mục được đăng ký tại thời điểm truy vấn. Cách khác là xem thông tin cấu hình được viết trong các nhà cung cấp mô tả Registry bất kể chúng có được đăng ký với hệ thống con Hiệu suất tại thời điểm truy vấn hay không. Trong thực tế, bạn sẽ cần phải sử dụng kết hợp hai cách vì bạn chỉ có thể lấy các thể hiện bằng cách truy vấn các chức năng đăng ký và bạn chỉ có thể nhận được danh mục và quầy cho các nhà cung cấp chưa được đăng ký bằng cách truy vấn cấu hình. Quay lại đầu trang được viết trong Registry.

Thật không may, PerformanceCounterCategory chỉ truy vấn chức năng đăng ký và do đó không thể cung cấp cho bạn thông tin về nhà cung cấp Perflib v2 chưa được đăng ký. Bạn có thể thấy các nhà cung cấp này thông qua các phương tiện khác, ví dụ thông qua Performance Monitor MMC (đằng sau hậu trường sử dụng PDH API, có thể hiển thị kết hợp các quầy đã đăng ký và chưa đăng ký) hoặc typeperf.exe -qx.

Bạn có thể kiểm tra các điều trên áp dụng cho bạn với danh mục BranchCache. Ví dụ dưới đây đã được thử nghiệm trên Win 7.

  1. Đảm bảo các dịch vụ Windows với tên hiển thị BranchCache được bắt đầu và sau đó chạy mã này C#:

    Debug.WriteLine((new PerformanceCounterCategory("BranchCache")).ReadCategory().Keys.Count); 
    

    Bạn sẽ nhận được không có lỗi và 21 ghi vào gỡ lỗi đầu ra.

  2. Bây giờ, dừng dịch vụ BranchCache và chạy lại mã C#. Bạn sẽ nhận được một ngoại lệ vì danh mục không còn được đăng ký với hệ thống con Hiệu suất và do đó, PerformanceCounterCategory không tìm thấy nó.

Để đảm bảo những gì tôi mô tả áp dụng cho các quầy bạn đang bỏ lỡ qua PerformanceCounterCategory.GetCategories(), kiểm tra các quầy mất tích được trình bày bởi typeperf -qx trên thư mục với tên gắn liền với các nhà cung cấp cấu hình trong Registry ở đâu đó dưới HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\_V2Providers.

Giải pháp là viết trình bao bọc C# cho số PDH API và nhận thông tin của bạn theo cách đó. Điều này là không tầm thường, đặc biệt nếu bạn không quen với việc xử lý các tương tác gốc. WMI cũng có vẻ là một lựa chọn hợp lệ (tôi đã thử liệt kê nhanh các đối tượng hiệu suất thông qua PowerShell và có vẻ như các quầy cho tất cả các nhà cung cấp được trả về), nhưng trong khi bạn không cần biết cách giao diện với mã gốc bạn cần biết WMI, đó cũng không tầm thường.

Các vấn đề liên quan