6

के लिए संबंधित w3wp प्रक्रिया की पहचान करें मैं एक Azure सेवा के प्रदर्शन की निगरानी पर काम कर रहा हूं।वेब भूमिका उदाहरण

वर्तमान में दो वेब भूमिका उदाहरणों (एक ही वेबसाइट के लिए) चल रहे हैं - प्रत्येक के साथ अपने स्वयं के W3WP.exe (w3wp और w3wp # 1)

मैं कैसे पता कर सकते हैं जो w3wp प्रक्रिया जो भूमिका उदाहरण के अंतर्गत आता है ?

इस जानकारी के साथ मैं कुछ प्रदर्शन काउंटरों - अर्थात् प्रक्रिया (w3wp) \ ProcessorTime (%) और थ्रेड गणना के साथ azure.diagnostics.monitor को फ़ीड करना चाहता हूं। लेकिन किसी भी सार्थक डेटा प्राप्त करने के लिए मुझे प्रदर्शन काउंटर (उदाहरण के लिए प्रक्रिया (w3wp_PID) \ processorTime (%)) में w3wp प्रक्रिया की प्रक्रिया आईडी संलग्न करना है - यह नहीं पता कि वाक्यविन्यास सही है, लेकिन एक तरीका है पीआईडी ​​संलग्न करने के लिए)

तो AzureStorage तालिका WADPerformanceCounters में अंतिम परिणाम ही तरह प्रविष्टियां हैं:

WebRoleInstance_n_0 | process(w3wp_1033)\processorTime (%) | 12.4 
WebRoleInstance_n_1 | process(w3wp_1055)\processorTime (%) | 48.4 

एटीएम अपनी तरह

WebRoleInstance_n_0 | process(w3wp)\processorTime (%) | 12.4 
WebRoleInstance_n_1 | process(w3wp)\processorTime (%) | 12.4 

मैंने सोचा: अगर मैं प्रत्येक के लिए एक DiagnosticsMonitor शुरू कर दिया भूमिका, कि मॉनीटर शुरू करने वाले रोलइंस्टेंस से संबंधित मॉनिटर सही प्रक्रिया का उपयोग करेगा। लेकिन वास्तव में यह काम नहीं करता है - या मुझे लगता है कि यह काम नहीं करता है - कम से कम परिणामस्वरूप मूल्यों को देखने के बाद।

// अद्यतन: प्रबंधन.विंडोज़ज़र पोर्टल पर आप प्रदर्शन निगरानी के लिए कस्टम मीट्रिक परिभाषित कर सकते हैं। वेबरोल इंस्टेंस को विशेष रूप से निगरानी रखने के लिए यहां चुना जा सकता है। यही वह है जो मैं करना चाहता हूं। इस पृष्ठ पर वास्तव में क्या करता है इस पर अंतर्दृष्टि भी मदद कर सकती है।

तुलना के लिए

: http://puu.sh/1xp7q

वे केवल बेवकूफ रास्ता मैं यह जानकारी प्राप्त करने के बारे में सोच सकता है: पहले और बाद में प्रत्येक w3wp शुरू कर दिया है सभी प्रक्रियाओं की एक सूची प्राप्त करने के लिए - पहचान जो एक जोड़ा गया था और उसके बाद कोड आधार संदर्भ के अनुसार निर्णय लें कि किस भूमिका का उदाहरण अभी शुरू हुआ था।

उत्तर

0

मुझे यह काम मिल गया - हालांकि यह वास्तव में सीधे आगे नहीं था।

सबसे पहले मुझे अपने पिछले बयान में कुछ सुधार करना है - बस एक ही स्तर पर होना।

क्लाउड सेवा में कई वर्चुअल मशीनें हैं, प्रत्येक होस्टिंग या तो वेबरोल इंस्टेंस या वर्कर रोल इंस्टेंस। इस प्रकार एक एकल वीएम पर केवल एक ही w3wp रन या कोई w3wp बिल्कुल नहीं बल्कि एक Waworkerhost प्रक्रिया।

मेरे विशेष मामले में एक ही वीएम पर दो w3wp चलने की संभावना है। इसलिए मुझे उन दोनों के बीच अंतर करने की आवश्यकता थी - इस प्रकार मुझे कुछ प्रकार की प्रक्रिया-इंस्टेंस एसोसिएशन बनाने की आवश्यकता थी।

जो मैं लॉग करना चाहता था वह था: एक एकल वीएम का कुल सीपीयू लोड, वीएम (w3wp, waworkerhost) पर चल रहे इंस्टेंस प्रक्रिया का सीपीयू लोड।

कुल सीपीयू लोड के लिए PerformanceCounter आसान और प्रत्येक वी एम के लिए बराबर है: \ प्रोसेसर (_Total) \% webrole के लिए Processortime वीएम मैं सके बस \ प्रक्रिया (w3wp) का उपयोग \% processortime काउंटर क्योंकि मैं नहीं किया जा सकता मैं इस लगा जब से तुम WebRole.cs या WorkerRole.cs में प्रत्येक भूमिका उदाहरण onStart (के लिए एक प्रदर्शन काउंटर पर नजर रखने के) शुरू कर दिया है: यकीन है कि अगर उसके सही w3wp (ऊपर देखें)

अब यहाँ

मैं क्या किया है एकमात्र ऐसा स्थान है जहां मैं किसी भी तरह से आवश्यक जानकारी एकत्र कर सकता हूं।

WorkerRole.cs मैंने किया में:

int pc = Environment.ProcessorCount; 
     string instance = RoleEnvironment.CurrentRoleInstance.Id; 

     SomeOtherManagementClass.StartDiagnosticMonitorService(pc, instance, Process.GetCurrentProcess()); 

WebRole.cs CurrentProcess भी WaWorkerHost रिटर्न में, तो मैं WebRole की Global.asax में ऊपर codelines ले जाने के लिए किया था। यहां सही प्रक्रिया उपलब्ध है।

कुछ अन्य मैनेजमेंट क्लास में मैंने StartDiagnosticsMonitorService डाला, जिसे अब CurrentProcess प्राप्त होता है, जिससे StartDiagnosticsMonitorService को कॉल किया गया था। (workerrole.cs से यह WaWorkerHost प्रक्रिया और w3wp प्रक्रिया प्राप्त होगा WebRoles से - पीआईडी ​​सहित)

public static void StartDiagnosticMonitorService(int coreCount, string currentRole, Process process) 
    { 
     string processName = GetProcessInstanceName(process.Id); 
     SetCPUCoreData(coreCount, currentRole, processName, process.Id); 
     ... 
    instanceProcessLoadCounterName = String.Format(@"\Process({0})\% Processor Time", processName); 
    } 

GetProcessInstanceName (process.Id) अब प्रत्येक वी एम पर कहा जाता है और प्रदान की process.Id को processName हो जाता है - यह आपको एक ही वीएम पर एकाधिक w3wps के बीच एक भिन्नता बनाने की अनुमति देता है क्योंकि प्रस्तुति नाम वापस आने के लिए w3wp, w3wp # 1, w3wp # 2 इत्यादि हैं। GetCurrentProcess द्वारा प्रदान की गई नाम, जो हमेशा w3wp है। इस के लिए मैं एक codesample मैं यहाँ stackoverflow पर पाया कि संशोधित - आप इसे नीचे पा सकते हैं:

private static string GetProcessInstanceName(int pid) 
    { 
     PerformanceCounterCategory cat = new PerformanceCounterCategory("Process"); 

     string[] instances = cat.GetInstanceNames(); 
     foreach (string instance in instances) 
     { 
      try 
      { 
       using (PerformanceCounter cnt = new PerformanceCounter("Process", 
       "ID Process", instance, true)) 
       { 
        int val = (int)cnt.RawValue; 
        if (val == pid) 
        { 
         return instance; 
        } 
       } 
      } 
      catch (InvalidOperationException) 
      { 
       //this point is reached when a process terminates while iterating the processlist- this it cannot be found 
      } 
     } 
     return ""; 
    } 

इतना ही नहीं बल्कि: SetCPUCoreData (coreCount, currentRole, processName, process.Id) प्रक्रियाओं के सभी प्रासंगिक डेटा की बचत होती है नीला भंडारण के लिए तो यह हर जगह आवेदन में से उपलब्ध है:

private static void SetCPUCoreData(int count, string roleinstance, string processName, int processID) 
    { 
     string[] instances = roleinstance.Split('.'); 
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse(GetSettingValue("LoadMonitor.Connection.String")); 
     CloudTableClient cloudTableClient = storageAccount.CreateCloudTableClient(); 
     const string tableName = "PerformanceMonitorCoreCount"; 
     cloudTableClient.CreateTableIfNotExist(tableName); 
     TableServiceContext serviceContext = cloudTableClient.GetDataServiceContext(); 


     PerformanceCounterCPUCoreEntity ent = new PerformanceCounterCPUCoreEntity(count, instances[instances.Count() - 1],processName, processID); 
     serviceContext.AttachTo(tableName, ent); 
     serviceContext.UpdateObject(ent); 
     serviceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); 
    } 

PerformanceCounterCPUCoreEntity StorageTable के लिए एक खाका है - नीला भंडारण एपीआई पर गौर आप इस हिस्से के बारे में कोई प्रश्न हैं, या बस पूछो।