ऐप में इलास्टिक एपीएम

मैंने लंबे समय तक और अब फिर से लेख प्रकाशित नहीं किए हैं ... यह लेख बहुत बड़ा नहीं था, लेकिन, उम्मीद है, उपयोगी है। एक बार जब हमने मैट्रिक्स इकट्ठा करने के लिए प्रोमेथियस का उपयोग करने का फैसला किया, लेकिन ... थोड़ी देर के बाद, हमने इलास्टिक एपीएम पर स्विच करने का फैसला किया, क्योंकि हमारे पास पहले से ही पूरा इलास्टिक स्टैक था और हमने इस स्टैक के भीतर मैट्रिक्स का समर्थन करने का फैसला किया।


तो, इलास्टिक एपीएम मैट्रिक्स के साथ काम करने के लिए एक उपकरण है, इसके लिए आवेदन विभिन्न भाषाओं के लिए मैट्रिक्स इकट्ठा करने के लिए लोचदार एपीएम एजेंट - एजेंटों का उपयोग करता है। हमने Elastic APM .NET Agent का इस्तेमाल किया। पैकेज 4.6.2 संस्करण के बाद से .NET फ्रेमवर्क द्वारा समर्थित है।


एजेंट सर्वर (इलास्टिक एपीएम सर्वर) को मैट्रिक्स भेजते हैं। सभी आवश्यक सेटिंग्स web.config में उन विशिष्ट कुंजियों के साथ लिखी जाती हैं, जिन्हें इलास्टिक एपीएम एजेंट उम्मीद करता है।
हमें Elastic APM Server के लिए कम से कम एक url कॉन्फ़िगर करने की आवश्यकता है। विभाजित करने के लिए, अनुप्रयोगों और वातावरणों द्वारा नियंत्रण रेखा में मीट्रिक प्रदर्शित करते समय, हमें निम्नलिखित मापदंडों की आवश्यकता होती है:


  • ElasticApm: ServiceName - सेवा का नाम, निम्न नियमों को पूरा करना चाहिए: ^ [a-zA-Z0-9 _-] + $।
  • ElasticApm: पर्यावरण - पर्यावरण का नाम आपको एप्लिकेशन में वैश्विक स्तर पर डेटा को फ़िल्टर करने की अनुमति देता है। केवल Kibana पर समर्थित है जो 7.2 संस्करण के साथ शुरू होता है।

वह समय निर्धारित करने के लिए जिसके बाद मैट्रिक्स भेजे जाएंगे, हमें निम्नलिखित पैरामीटर की आवश्यकता है:


  • ElasticApm: मेट्रिक्सइंटरवल - आपको वह समय निर्धारित करने की अनुमति देता है जिसके बाद मीट्रिक सर्वर पर भेजा जाएगा, डिफ़ॉल्ट रूप से - 5 s। यदि समय 0 पर सेट है, तो मीट्रिक सर्वर पर नहीं भेजी जाएगी। इस पैरामीटर के लिए सभी माप सेकंड में हैं।

आप लॉगिंग स्तर को भी कॉन्फ़िगर कर सकते हैं: ElasticApm: LogLevel।


Web.config भरने का एक उदाहरण:


<?xml version="1.0" encoding="utf-8"?> <!-- ... --> <configuration> <!-- ... --> <appSettings> <!-- ... --> <add key="ElasticApm:ServerUrls" value="https://my-apm-server:8200" /> <add key="ElasticApm:MetricsInterval" value="10" /> <add key="ElasticApm:Environment" value="Stage" /> <add key="ElasticApm:ServiceName" value="Web.Api" /> <!-- ... --> </appSettings> <!-- ... --> </configuration> 

लोचदार APM एजेंट पैकेज के काम की इकाई लेनदेन है - ITransaction प्रकार की वस्तुएं। लेन-देन का डेटा रिपोर्टर ऑब्जेक्ट के अंदर एकत्र किया जाता है और निर्दिष्ट समय पर एक बार सर्वर को भेजा जाता है। समय भेजने की सेटिंग्स ऊपर दी गई हैं।


लेन-देन की शुरुआत स्टार्टट्रांसलेशन विधि के लिए कॉल के साथ शुरू होती है, कॉल टू एंड () विधि से पूरी होती है। StartTransaction मेथड के अलावा, आप कैप्चरट्रैक्शन मेथड का भी उपयोग कर सकते हैं, लेकिन End () मेथड को इसके लिए नहीं कहा जाता है, आपकी जरूरत की हर चीज को मेथड के तौर पर पास किया जाता है। यदि अपवादों को पकड़ना आवश्यक नहीं है, तो इसके लिए कैप्चर अपवाद विधि है।


यह विधि उस ट्रांजेक्शन ऑब्जेक्ट को लिखेगी जिसमें इसमें पास किया गया अपवाद होगा। सभी अतिरिक्त जानकारी - मेटाडेटा - को ट्रांजेक्शन ऑब्जेक्ट के लेबल प्रॉपर्टी में भरकर ट्रांजैक्शन ऑब्जेक्ट को लिखा जाता है।


तो क्या हुआ? सबसे पहले, एक मॉडल जोड़ें जिसमें हमारे लिए ITransaction ऑब्जेक्ट के लिए आवश्यक सेटिंग्स होंगी:


 public class MeasurementData { public static string ApmServerUrl => ConfigurationManager.AppSettings["ElasticApm:ServerUrls"] ?? "http://localhost:8200"; public static string MetricsInterval => ConfigurationManager.AppSettings["ElasticApm:MetricsInterval"] ?? "10"; public static string ApmEnvironment => ConfigurationManager.AppSettings["ElasticApm:Environment"] ?? "local"; public static string ServiceName => ConfigurationManager.AppSettings["ElasticApm:ServiceName"] ?? "Api"; public ITransaction MetricsObject { get; set; } //    public static ITransaction Create(string metricsName) { Environment.SetEnvironmentVariable(ConfigConsts.EnvVarNames.ServerUrls, ApmServerUrl); Environment.SetEnvironmentVariable(ConfigConsts.EnvVarNames.MetricsInterval, MetricsInterval); Environment.SetEnvironmentVariable(ConfigConsts.EnvVarNames.Environment, ApmEnvironment); Environment.SetEnvironmentVariable(ConfigConsts.EnvVarNames.ServiceName, ServiceName); return Agent.Tracer.StartTransaction(metricsName, ApiConstants.TypeRequest); } } 

अगला, हम एक बिल्डर बनाते हैं जिसमें हम एक लेनदेन ऑब्जेक्ट बनाएंगे, लेन-देन के लिए मेटाडेटा लिखेंगे, अपवाद को बचाने के लिए लेनदेन बनाएँ, लेन-देन पूरा करें:


 public class MetricsBuilder { private readonly MeasurementData _measurementData = new MeasurementData(); private string _metricName; public void BuildMetrics(string metricName) { //      ,   _metricName = string.IsNullOrEmpty(metricName) ? "api_payment_request_duration" : metricName; CheckAndCreateMetricsObjects(); } //      public void AddMetricsLabels(string key, string value) { CheckAndCreateMetricsObjects(); if (!_measurementData.MetricsObject.Labels.ContainsKey(key)) { _measurementData.MetricsObject.Labels.Add(key, value); return; } _measurementData.MetricsObject.Labels[key] = value; } //    public void CaptureMetricException(Exception exception) { CheckAndCreateMetricsObjects(); _measurementData.MetricsObject.CaptureException(exception); } public void Dispose() { CheckAndCreateMetricsObjects(); _measurementData.MetricsObject.End(); } // ,      , //   -  private void CheckAndCreateMetricsObjects() { if (_measurementData.MetricsObject == null) { _measurementData.MetricsObject = MeasurementData.Create(_metricName); Logger.Info($"{nameof(MetricsBuilder)}: CurrentTransaction: {JsonConvert.SerializeObject(Agent.Tracer.CurrentTransaction)} " + $"ServerUrls: {JsonConvert.SerializeObject(Agent.Config.ServerUrls)} " + $"MetricsIntervalInMilliseconds: {JsonConvert.SerializeObject(Agent.Config.MetricsIntervalInMilliseconds)}"); } } } public interface IMetricsService : IDisposable { void AddMetricsLabels(string key, string value); void CaptureMetricException(string message, Exception exception); } public class MetricsService : IMetricsService { private readonly MetricsBuilder _builder; public MetricsService(string metricName) { _builder = new MetricsBuilder(); Build(metricName); } public void AddMetricsLabels(string key, string value) { try { _builder.AddMetricsLabels(key, value); } catch (Exception exception) { CaptureMetricException("Can't write metrics labels", exception); } } public void CaptureMetricException(string message, Exception exception) { Logger.Error(message, exception); try { _builder.CaptureMetricException(exception); } catch (Exception exec) { Logger.Error("Can't write capture exception of metrics", exec); } } public void Dispose() { try { _builder.Dispose(); } catch (Exception exception) { CaptureMetricException($"Can't to do correct dispose of object: {typeof(MetricsService)}", exception); } } private void Build(string metricName) { try { _builder.BuildMetrics(metricName); } catch (Exception exception) { CaptureMetricException("Can't create metrics object", exception); } } } 

जिस कक्षा में मेट्रिक्स एकत्र करने हैं, उसके लिए हम एक डेकोरेटर बनाते हैं जिसमें हम अपने मेट्रिक्स सर्विस का उपयोग करेंगे। निर्भरता के सही कार्यान्वयन के लिए एक डेकोरेटर को पंजीकृत करने के बारे में मत भूलना।


 public class TestClientMetricsService : ITestObject { private readonly ITestObject _testObject; public GatewayClientMetricsService(ITestObject testObject) { _testObject = testObject; } public ProcessingResult TestMethod() { return WriteMetrics("Test_Method", () => _testObject.Test()); } private ProcessingResult WriteMetrics(string methodName, Func<Result> testMethod) { using (var metricsService = new MetricsService(methodName)) { try { metricsService.AddMetricsLabels("assemblyName", Assembly.GetCallingAssembly().FullName); var requestResult = testMethod(); metricsService.AddMetricsLabels("success", requestResult?.Success.ToString() ?? "false"); metricsService.AddMetricsLabels("resultCode", requestResult?.GetResultCode().ToString()); return requestResult; } catch (Exception exception) { metricsService.CaptureMetricException("Can't write metrics", exception); throw; } } } } 

मुझे उम्मीद है कि यह लेख उन लोगों के लिए मददगार रहा है, जो मैट्रिक्स इकट्ठा करने के लिए एक उपकरण के रूप में इलास्टिक एपीएम का उपयोग करना चाहते हैं।

Source: https://habr.com/ru/post/hi485996/


All Articles