2013-04-10 6 views
14

के साथ असंगत है ठीक है, तो मैं मूल रूप से स्थापित प्रदर्शन काउंटर श्रेणियों की एक सूची बनाने की कोशिश कर रहा हूं, जैसा कि आप PerfMon में प्राप्त करते हैं। इसके लिए मैंPerformanceCounterCategory.GetCategories Perfmon

System.Diagnostics.PerformanceCounterCategory.GetCategories() 

जो लगता है जैसे कि यह, काम करता है जब तक आप सूची का निरीक्षण किया, और पता है कि कुछ याद कर रहे हैं का उपयोग कर रहा हूँ। पहली बार मैंने लापता देखा था रेडीबॉस्ट कैश था। ऐसा इसलिए था क्योंकि परियोजना "x86" पर संकलित करने के लिए सेट की गई थी। इसे "किसी भी CPU" में बदलना जो उस समस्या को हल करता है।

हालांकि कुछ ऐसे हैं जो अभी भी गायब हैं, उदाहरण के लिए, परीक्षण मशीनों में से एक में "प्राधिकरण प्रबंधक अनुप्रयोग" श्रेणी है (मेरा नहीं है, और कोई भी नहीं जानता कि क्यों, या यह कहां से आता है) हालांकि, उस मशीन पर, प्रदर्शन काउंटर श्रेणी PerfMon में दिखाई देती है, लेकिन सी # से GetCategories() विधि का आविष्कार करते समय नहीं।

क्या किसी को पता है क्यों? PerformanceCounterCategories पाने के लिए कोई और विश्वसनीय तरीका है? क्या ऐसा इसलिए है क्योंकि मैं नेट का उपयोग कर रहा हूँ? क्या वहां कुछ मूल एपीआई है जिसका मैं उपयोग कर सकता हूं?

संपादित

मैं माफी चाहता हूँ, मैं अभी भी यह नहीं मिलता है। मैंने इस कोड को शायद बेहतर ढंग से समझाया है:

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(); 
     } 
    } 
} 

यह अब मुझे 3236 परिणाम देता है। क्योंकि यह सिस्टम में सभी प्रदर्शन काउंटर प्राप्त करता है। तो मुझे लगता है कि मुझे बस इतना करना है कि उन लोगों को फ़िल्टर करें जो वास्तव में प्रदर्शन काउंटर हैं, मुझे केवल श्रेणियों के साथ छोड़कर। हालांकि प्रदर्शन काउंटर के लिए एक कन्स्ट्रक्टर प्रतीत नहीं होता है जो सिर्फ नाम लेता है (क्योंकि यह अद्वितीय नहीं है), और न ही ऐसा लगता है जो सूचकांक मान लेता है। मैंने प्रदर्शन डेटा हेल्पर नामक एक Win32 एपीआई खोज ली है, लेकिन ऐसा लगता है कि यह कार्यक्षमता नहीं है जो मैं चाहता हूं। इसलिए। यदि मेरे पास एक प्रदर्शन काउंटर इंडेक्स है, तो मैं उस सूचकांक के लिए C# में PerformanceCounterCategory कैसे प्राप्त करूं? PerfMon यह करता है, तो यह संभव होना चाहिए। क्या यह पता लगाने के लिए इंडेक्स "मैजिक नंबर" को पार्स करने का कोई तरीका है?

संपादित 2

ठीक है। तो यह सुझाव दिया कोड तीन अलग अलग तरीकों का उपयोग (नेट/रजिस्ट्री/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(); 
     } 
    } 
} 

मेरी मशीन पर मैं द्वारा नेट ढांचे, 117 का उपयोग कर 138 मिलता है रजिस्ट्री को पार्स करना, और 157 PowerShell का उपयोग करके (जो सही उत्तर है)।

हालांकि पावरशेल/विंडोज एसडीके स्थापित करने वाले उपयोगकर्ता के आधार पर वास्तव में एक विकल्प नहीं है।

किसी के पास कोई विचार है? क्या रजिस्ट्री में कहीं और छुपा कुछ शीर्ष गुप्त संस्करण 3 प्रदर्शन काउंटर श्रेणियां हैं, जिन्हें मुझे ट्रैक करने की आवश्यकता है? मैंने कोशिश करने के लिए केवल विचारों से बाहर नहीं किया है, मैं भी कोशिश करने के लिए बुरे विचारों से बाहर चला गया है। क्या सभी श्रेणियों को सूचीबद्ध करने के लिए, क्या कोई गुप्त कमांड लाइन स्विच मैं परफॉर्म पर उपयोग कर सकता हूं?

+2

मुझे यह पावरशेल स्निपेट 'गेट-काउंटर -लिस्टसेट * मिला। चयन-ऑब्जेक्ट-एक्सपैंडप्रॉपर्टी पथ '(स्रोत: http://blogs.msdn.com/b/powershell/archive/2009/04/21/v2-quick-tip-monitoring-performance-counters-with-powershell.aspx) । –

+0

धन्यवाद। लेकिन मुझे इसे प्रोग्रामेटिक रूप से करने की ज़रूरत है। सबसे महत्वपूर्ण बात यह है कि मैं PowerShell इंस्टॉल किए गए अंतिम उपयोगकर्ता पर भरोसा नहीं कर सकता। मेरे पास PowerShell इंस्टॉल नहीं है। :) –

उत्तर

1

प्रदर्शन काउंटर (और श्रेणियां) प्रति लोकेल पंजीकृत हैं। यही है, आप भाषा के आधार पर उनके लिए अलग-अलग नाम रख सकते हैं।

सभी उपलब्ध प्रदर्शन श्रेणियां और उनके काउंटर विंडोज रजिस्ट्री में HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib के तहत पंजीकृत हैं। आपको प्रत्येक उपलब्ध भाषा के लिए उप-कुंजी मिल जाएगी (उदा।अंग्रेजी के लिए 009)।

PerformanceCounterCategory.GetCategories() विधि आंतरिक रूप से काम करता है सबसे पहले "invariant संस्कृति" श्रेणियों की जांच करना है। यदि यह कोई पाता है तो यह इस सेट को वापस कर देगा। इसलिए, अगर कुछ त्रुटि या विक्रेता की निगरानी के कारण एक श्रेणी केवल एक भाषा के साथ उपलब्ध है, तो आप इसे अपनी वर्तमान भाषा सेटिंग (या तो ओएस या एप्लिकेशन या दोनों) के आधार पर नहीं प्राप्त करेंगे।

मैं पहले HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\<langcode>\Counter कुंजी की सामग्री की जांच करता हूं और देख सकता हूं कि गायब श्रेणी केवल उनमें से एक में है या नहीं। एक संबंधित समस्या this (Google search) हो सकती है, लेकिन मैंने आगे की जांच नहीं की है।

स्पष्ट रूप से, मुझे उपलब्ध काउंटरों की सूची प्राप्त करने के लिए किसी भी "बेहतर" तरीके से नहीं पता है। यदि आपकी समस्या उपर्युक्त वर्णित है (या संबंधित), तो मैं स्थिति को ठीक करने के लिए देखने की कोशिश करता हूं।

+0

इससे कम परिणाम भी मिलते हैं। प्रश्न में संपादन देखें। –

2

मुझे लगता है कि आप उस पर चल रहे हैं जो मैं पर्फिब v2 काउंटर द्वारा प्रेरित .NET Framework बग के रूप में अर्हता प्राप्त करूंगा।

दृश्यों के पीछे, PerformanceCounterCategory वर्तमान में प्रदर्शन उपप्रणाली के साथ पंजीकृत श्रेणियों (उर्फ ऑब्जेक्ट्स), उदाहरणों और काउंटरों के बारे में जानकारी प्राप्त करने के लिए Registry Functions का उपयोग करता है। आप ILSpy के साथ PerformanceCounterCategory के लिए कोड देख कर इसे सत्यापित कर सकते हैं।

काउंटर दो प्रकार के प्रदाताओं के माध्यम से पंजीकृत हो सकते हैं: "कोर" -प्रोवाइडर्स और "एक्स्टेंसिबिलिटी" -प्रोवाइडर। बेहतर विकल्प की कमी के कारण इन नामों का आविष्कार किया गया था।

कोर-प्रदाताओं को विंडोज़ में गहराई से बनाया गया है और प्रोसेस, सिस्टम इत्यादि जैसे काउंटर प्रदान करने के लिए प्रदर्शन उपप्रणाली के साथ इंटरफ़ेस बनाया गया है। यदि आप इस तरह के काउंटर PerformanceCounterCategory के माध्यम से नहीं देख पा रहे हैं, तो यह बहुत संभावना है आपके इवेंट लॉग में आपके विंडोज इंस्टॉलेशन और कम से कम these errors में कुछ गहरी समस्या है। मुझे लगता है कि यह तुम्हारा मामला नहीं है।

अन्य सभी काउंटर प्रदान करने के लिए प्रलेखन Perflib interface के माध्यम से प्रदर्शन उपप्रणाली के साथ विस्तारशीलता-प्रदाता इंटरफ़ेस। यह ध्यान रखना महत्वपूर्ण है कि कुछ विंडोज़ सुविधाओं के लिए काउंटर एक्स्टेंसिबिलिटी-प्रदाताओं के माध्यम से पंजीकृत हैं, जैसे कि प्रमुख एमएस उत्पादों जैसे कि SQL सर्वर, .NET Framework, आदि के लिए काउंटर हैं। इसलिए यह नहीं है कि कोर-प्रदाता एमएस और एक्स्टेंसिबिलिटी द्वारा बनाई गई सभी चीज़ों के लिए हैं तीसरे पक्ष के लिए प्रदाता।

यदि आप Perflib के माध्यम से पंजीकृत PerformanceCounterCategory काउंटर के माध्यम से देखने में सक्षम नहीं हैं, तो पहले यह हो सकता है कि उनका प्रदाता सिस्टम में गलत तरीके से कॉन्फ़िगर किया गया हो या कॉन्फ़िगरेशन टूटा हुआ हो। इस मामले में आपको these docs से प्रदर्शन काउंटर लोडिंग या प्रदर्शन लाइब्रेरी उपलब्धता अनुभागों में परिभाषित त्रुटियों में से कुछ त्रुटियों में लॉग इन होना चाहिए। मुझे लगता है कि यह तुम्हारा मामला नहीं है।

दूसरा कारण यह है कि पर्फ्लिब प्रदाता दृश्यों के पीछे कैसे काम करते हैं। उनके काउंटर पंजीकृत होने के लिए दो प्रमुख कदमों की आवश्यकता है। पहला कदम LodCtr.exe का उपयोग कर रजिस्ट्री में प्रदाताओं के लिए कॉन्फ़िगरेशन लिखना है। मुझे लगता है कि यह आपके लिए पूर्ण रूप से काउंटर के इंस्टॉलर द्वारा आपके लिए किया गया है, और यह कि कॉन्फ़िगरेशन सही है, खासकर जब से इस कॉन्फ़िगरेशन में कोई समस्या हो, तो आपको ईवेंट में उपर्युक्त त्रुटियों में से कुछ की संभावना होगी लॉग ऑन करें। दूसरा चरण वास्तव में प्रदर्शन उपप्रणाली के साथ पर्फ्लिब प्रदाता को पंजीकृत करना है।

अब हम समस्या के करीब आ रहे हैं। Perflib v1 और v2 प्रदाताओं के लिए पंजीकरण बहुत अलग किया जाता है। V1 के लिए प्रदाताओं के लिए कोड डीएलएल में लिखा गया है जो चरण एक पर लिखी गई रजिस्ट्री कॉन्फ़िगरेशन से संदर्भित है और सिस्टम द्वारा लोड किया गया है।इस प्रकार, Perflib v1 प्रदाता पंजीकरण स्वचालित रूप से होता है क्योंकि सिस्टम रजिस्ट्री से कॉन्फ़िगरेशन जानकारी पढ़ता है और DLL लोड करता है। Perflib v2 प्रदाताओं के लिए चीजें अलग हैं। प्रदाताओं के लिए कोड अब सिस्टम द्वारा सीधे निष्पादित नहीं किया गया है, लेकिन प्रदाताओं से जुड़े एक आवेदन/सेवा द्वारा। इसलिए यदि आप एक ऐप लिखते हैं जो Perflib v2 का उपयोग कर कस्टम प्रदाताओं/काउंटर बनाता है तो आपका ऐप इन प्रदाताओं के लिए डेटा एकत्र करने के लिए कोड भी चलाएगा और यह दस्तावेज तरीके से प्रदर्शन उपप्रणाली के साथ इंटरफेस करेगा। समस्या यह है कि सिस्टम के साथ परफ्लिब v2 प्रदाताओं के पंजीकरण करने वाला कोड अब प्रदाता कोड को होस्ट करने वाले ऐप द्वारा ट्रिगर किया जाना चाहिए (जैसा कि सिस्टम द्वारा स्वचालित रूप से Perflib v1 के रूप में ट्रिगर किया जा रहा है)। इसलिए, उदाहरण के लिए, यदि ऐप एक विंडोज सेवा है और सेवा अभी तक शुरू नहीं हुई है, तो प्रदाता प्रदर्शन उपप्रणाली के साथ पंजीकृत नहीं होंगे और उनके काउंटर रजिस्ट्री फ़ंक्शंस/PerformanceCounterCategory के माध्यम से दिखाई नहीं देंगे (अभी तक)।

Here दस्तावेज़ की प्रासंगिकता का Perflib वी 2 प्रदाताओं के लिए यह आत्म पंजीकरण का वर्णन है:

आपका प्रदाता CounterInitialize और CounterCleanup कार्यों कॉल करना होगा। CounterInitialize प्रदाता को पंजीकृत करने के लिए PerfStartProvider फ़ंक्शन को कॉल करता है और काउंटर सेट को प्रारंभ करने के लिए PerfSetCounterSetInfo फ़ंक्शन को भी कॉल करता है। काउंटर क्लेनअप प्रदाता के पंजीकरण को हटाने के लिए PerfStopProvider फ़ंक्शन को कॉल करता है।

निष्कर्ष में, वहाँ लिस्टिंग श्रेणियों, उदाहरणों और काउंटर के दो अलग-अलग तरीके हैं। एक रजिस्ट्री फ़ंक्शन से पूछताछ करना और क्वेरी समय पर पंजीकृत सभी आइटम सूचीबद्ध करना है। दूसरा रजिस्ट्री में लिखित कॉन्फ़िगरेशन जानकारी को देखना है, भले ही वे क्वेरी समय पर प्रदर्शन उपप्रणाली के साथ पंजीकृत हों या नहीं, भले ही प्रदाताओं का वर्णन करें।

प्रैक्टिस में आपको दो तरीकों से कॉम्बो का उपयोग करना होगा क्योंकि आप केवल रजिस्ट्री फ़ंक्शंस से पूछताछ करके श्रेणियों के लिए उदाहरण प्राप्त कर सकते हैं और आप केवल उन प्रदाताओं के लिए श्रेणियां और काउंटर प्राप्त कर सकते हैं जो अभी तक कॉन्फ़िगरेशन से पूछताछ नहीं कर चुके हैं रजिस्ट्री में लिखा है।

दुर्भाग्य से, PerformanceCounterCategory केवल रजिस्ट्री फ़ंक्शंस से पूछताछ करता है और इसलिए आपको अभी तक पंजीकृत नहीं किया गया है जो Perflib v2 प्रदाताओं के बारे में जानकारी प्राप्त करने में सक्षम नहीं है। आप इन प्रदाताओं को अन्य माध्यमों के माध्यम से देख सकते हैं, उदाहरण के लिए प्रदर्शन मॉनिटर एमएमसी (जो दृश्यों के पीछे पीडीएच एपीआई का उपयोग करता है, जो पंजीकृत और अभी तक पंजीकृत काउंटरों का कॉम्बो दिखाने में सक्षम है) या typeperf.exe -qx

आप ऊपर दिए गए परीक्षणों को BranchCache श्रेणी के साथ लागू कर सकते हैं। उदाहरण नीचे विन 7.

  1. पर परीक्षण किया गया था के साथ प्रदर्शन नाम BranchCache शुरू कर दिया है Windows सेवा सुनिश्चित करें और फिर इस सी # कोड चलाएँ:

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

    आप कोई त्रुटि और 21 को पत्र लिखा मिलना चाहिए डीबग आउटपुट।

  2. अब BranchCache सेवा को रोकें और फिर से C# कोड चलाएं। आपको अपवाद मिलेगा क्योंकि श्रेणी अब प्रदर्शन उपप्रणाली के साथ पंजीकृत नहीं है और इसलिए PerformanceCounterCategory इसे ढूंढने में विफल रहता है।

मैं क्या वर्णित सुनिश्चित करने के लिए काउंटरों आप PerformanceCounterCategory.GetCategories() के माध्यम से वंचित हो रहे हैं पर लागू होता है, जाँच करें कि लापता काउंटरों कहीं HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\_V2Providers के तहत रजिस्ट्री में विन्यस्त प्रदाताओं के साथ जुड़े नाम के साथ श्रेणियों पर typeperf -qx द्वारा दिखाए जाते हैं।

समाधान PDH API के लिए एक सी # रैपर लिखना है और अपनी जानकारी इस तरह प्राप्त करें। यह गैर-तुच्छ है, खासकर अगर आप देशी बातचीत को संभालने के लिए उपयोग नहीं करते हैं। WMI भी एक वैध विकल्प प्रतीत होता है (मैंने PowerShell के माध्यम से प्रदर्शन ऑब्जेक्ट्स की त्वरित सूची की कोशिश की और ऐसा लगता है कि सभी प्रदाताओं के लिए काउंटर लौटाए जाते हैं) लेकिन जब आपको मूल कोड के साथ इंटरफ़ेस कैसे करना है, तो आपको WMI जानने की आवश्यकता नहीं है, जो भी गैर-तुच्छ है।

संबंधित मुद्दे