क्या व्यापार तर्क के बाहर लॉगिंग कोड को पूरी तरह से रखना संभव है?


12

AOP की मदद से, मैं अपने व्यावसायिक तर्क से लॉगिंग कोड को हटा सकता हूं। लेकिन मुझे लगता है कि इसका उपयोग केवल साधारण चीजों को लॉग करने के लिए किया जा सकता है (अर्थात लॉगिंग विधि प्रविष्टि / निकास और पैरामीटर मान)।

हालाँकि, क्या होगा अगर मुझे अपने व्यावसायिक तर्क में कुछ लॉग इन करने की आवश्यकता है? जैसे

public void SomeDomainMethod(string id)
{
   //Get user by Id
   User user = Users.Get(id);
   if (user == null)
   {
      Log.Warn("user is not existed");        //<----------------- Log A
      throw new InvalidOperationException("user is not existed");
   }

   //Step 1 
   while(true)
   {
       //do something
   }
   Log.Info("Step 1 is completed");            //<----------------- Log B

   //Step 2
   while(true)
   {
       //do something
   }
   Log.Info("Step 2 is completed");            //<----------------- Log C

}

उपरोक्त नमूना विधि पर्याप्त स्पष्ट नहीं हो सकती है, जो मैं यहां दिखाना चाहता हूं वह यह है कि इस पद्धति को डोमेन के दृष्टिकोण से सबसे छोटी इकाई माना जाना चाहिए। इसे छोटे टुकड़ों में विभाजित नहीं किया जाना चाहिए।

क्या विधि से 3 लॉगिंग कोड से ऊपर जाना संभव है? ऐसी स्थिति के लिए सबसे अच्छा अभ्यास क्या है?


मुझे पूरा यकीन है कि आपका उदाहरण "स्टेप 1" और "स्टेप 2" लॉग एक बिजनेस लॉजिक ऑडिट ट्रेल और पहले एक तकनीकी लॉगिंग का हिस्सा होना चाहिए। मैं पहली बार इसे सॉर्ट
करूंगा

जवाबों:


1

ज़रूर!

लेकिन मेरे अनुभव में, दो सामान्य प्रकार के उपयोगी लॉगिंग हैं:

सब कुछ लॉग: प्रोफाइलिंग एपीआई के माध्यम से निर्मित लॉग । प्रदर्शन के मुद्दों की पहचान करने और अपवादों की रिपोर्टिंग के लिए अच्छा है। बहुत शोर भरा।

व्यापार घटना लॉग: व्यापार तर्क में लॉग किए गए लॉग । व्यवसाय में किसी भी चीज़ की परवाह हो सकती है। न्यूनतम शोर। बस उल्लेखनीय, तार्किक, "व्यावसायिक" घटनाएं। ऑडिटिंग और KPI के लिए अच्छा ...

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

और, मैं आम तौर पर AOP को या तो 2 लॉगिंग के लिए नहीं सुझाता । मेरे अनुभव में, आप या तो सब कुछ चाहते हैं , जिसका अर्थ है कि आप एक प्रोफाइलर का उपयोग कर रहे हैं, या आप तार्किक / व्यावसायिक कार्यक्रम चाहते हैं। और बाद के मामले में, मुझे लगता है कि व्यापार तर्क में केवल लकड़हारा को आमंत्रित करना अधिक सरल है


1. लेकिन गंभीरता से, अपने आप को प्रयास में हजारों घंटे बचाएं और बस एक मौजूदा प्रोफाइलर उपकरण का उपयोग करें ...

2. बेशक, यह मानता है कि आप मेरी राय साझा करते हैं कि व्यावसायिक नियमों को छिपाने के लिए एक पहलू एक महान जगह नहीं है!


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

10

ज़रूर, आप आसानी से इसके लिए एओपी का उपयोग कर सकते हैं। बस भागों को रिफलेक्टर करें

  • आईडी द्वारा उपयोगकर्ता प्राप्त करें
  • चरण 1
  • चरण 2

में अलग तरीकों (आप या तो किया जाना चाहिए के रूप में अपने कोड क्लीनर बनाने के लिए)। अब आप अपनी पसंद के विधि कॉल को लॉग करने के लिए अपने AOP ढांचे को आसानी से कॉन्फ़िगर कर सकते हैं ( जैसे यहाँ दिखाया गया है )। अपवाद को कॉलर द्वारा सीधे लॉग किया जा सकता है, इसे व्यावसायिक तर्क से बाहर निकालने के लिए एओपी का उपयोग करने की कोई आवश्यकता नहीं है।

आपके संपादन के लिए:

मैं यहां बताना चाहता हूं कि इस पद्धति को डोमेन के दृष्टिकोण से सबसे छोटी इकाई माना जाना चाहिए। इसे छोटे टुकड़ों में विभाजित नहीं किया जाना चाहिए

ऐसा क्यों नहीं होना चाहिए? यदि, "व्यावसायिक तर्क संदर्भ" में, आप "कुछ" लॉग करना चाहते हैं, जो लॉगिंग के लायक है, और यदि इस "कुछ" को एक समझदार नाम दिया जा सकता है, तो ज्यादातर मामलों में यह एक विधि पर कोड को फिर से भरने के लिए समझ में आएगा। अपना ही है। यदि आप AOP का उपयोग करना चाहते हैं, तो इसके लिए आपको अपने कोड को उस तरह से संरचित करना होगा, जिस पर आपको लॉगिंग की आवश्यकता की परवाह किए बिना इसे संरचित करना चाहिए। आप इसे एओपी के नुकसान के रूप में व्याख्या कर सकते हैं, या आप इसे एक लाभ के रूप में व्याख्या कर सकते हैं, क्योंकि यह आपको एक प्रतिक्रिया देता है जहां आपके कोड संरचना में सुधार किया जा सकता है।


यह मेरा बुरा है कि मेरा उदाहरण पर्याप्त रूप से स्पष्ट नहीं है। मैं वास्तव में उदाहरण में दिखाना चाहता हूं कि विधि डोमेन के दृष्टिकोण से सबसे छोटी इकाई है जिसे छोटे टुकड़ों में विभाजित नहीं किया जाना चाहिए।
चार्ली

@ चार्ली: उदाहरण पूरी तरह से स्पष्ट है। यहाँ आपकी गलतफहमी है कि शायद आपको लगता है कि कदमों की तुलना में बड़ी विधियाँ होना एक अच्छा विचार हो सकता है। और यह IMHO गलत है, यह एक अच्छा विचार नहीं है। लॉगिंग के विभिन्न चरणों का होना एक स्पष्ट संकेत है इन चरणों में एक अमूर्त, अपने आप में एक नाम होना चाहिए, इसलिए अपने आप पर एक विधि।
डॉक ब्राउन

@ शर्ली आपके यूनिट या काम द्वारा कहे जा रहे 3 निजी तरीके को करने से आपको कुछ भी नहीं रोकती है। बाहर से यह रास्ता वैसे ही रहा, लेकिन अब आपके पास अपने लॉगिंग के लिए आवश्यक अमूर्तता है।
रेमी

यह दृष्टिकोण ठीक है यदि आप चिंताओं को लॉग करके अपनी कोड संरचना को चलाना चाहते हैं। कभी-कभी आप इसे किसी और चीज़ से चलाना चाहते हैं, हालाँकि।
जॉन वू

@JohnWu: कोड संरचना को लॉगिंग आवश्यकता की परवाह किए बिना विभिन्न चिंताओं / चरणों को प्रतिबिंबित करना चाहिए। यही कोड संरचना को यहां चलाया जाता है। एक बार जब यह समस्या हल हो जाती है, तो एओपी द्वारा लॉगिंग की जा सकती है, यह कोड को बेहतर संरचना देने का "दुष्प्रभाव" अधिक है। इसलिए मुझे लगता है कि यह लॉगिंग चिंता का विषय नहीं है जो कोड संरचना को चलाता है, यह अधिक है कि लॉगिंग के लिए एओपी का उपयोग करने की आवश्यकता इसे अधिक पारदर्शी बनाती है कि कोड को कुछ संरचना याद आती है जो इसे या तो होनी चाहिए।
डॉक्टर ब्राउन

3

जब तक सामान जमा करना व्यावसायिक आवश्यकताओं का हिस्सा नहीं है, तब तक यह सबसे अच्छा है, जैसा कि आप कहते हैं, इसे अपने कोड से पूरी तरह से बाहर रखने के लिए।

इसका मतलब है कि आप वास्तव में "चरण 1 पूर्ण" जैसे सामान को लॉग इन नहीं करना चाहते हैं। हालांकि यह शुरू में डिबगिंग के लिए उपयोगी हो सकता है, इसके उत्पादन में सिर्फ बकवास की गीगाबाइट उत्पन्न करने जा रहा है जिसे आप कभी नहीं देखेंगे।

यदि Step1Complete कुछ प्रकार की व्यावसायिक घटना है जिसे आगे की कार्रवाई की आवश्यकता होती है, तो यह एक अच्छे पुराने जमाने की घटना के माध्यम से उजागर किया जा सकता है, जिससे आप बिना किसी आईओगर या अपनी कक्षा में इंजेक्शन लगाए


वही तो में सोच रहा था। मैं एक डोमेन / व्यवसाय मॉडल POCO में प्रवेश करने के लिए एक उचित मामले के साथ नहीं आ सकता। लॉगिंग एक ऐसी चीज है जो स्वाभाविक रूप से कोर बिजनेस मॉडल, आईएमओ के बाहर फिट होती है।
jleach

2

कुछ सामान्य पैटर्न की सहायता से आप अपने व्यावसायिक तर्क से लॉगिंग कोड को बाहर निकाल सकते हैं। हालाँकि आपको ऐसा करने लायक नहीं मिल सकता है

उदाहरण के लिए, श्रोता (हैंडक्राफ्ट एक या इवेंट बस आदि का उपयोग करके), आपका कोड दिखेगा

public void SomeDomainMethod(string id)
{
   //Get user by Id
   User user = Users.Get(id);
   if (user == null)
   {
      listener.OnUserNotFound(userId);
      throw new InvalidOperationException("user is not existed");
   }

   //Step 1 
   while(true)
   {
       //do something
   }
   listener.OnStep1Finished(......);

   ...

}

श्रोता में लॉगिंग को लागू करने से, लॉजिक लॉजिक अब आपके व्यावसायिक तर्क में नहीं है।

हालाँकि आप पा सकते हैं कि यह हमेशा यथार्थवादी नहीं है क्योंकि आप हमेशा अपने तर्क की सार्थक घटना को परिभाषित करने में सक्षम नहीं हो सकते हैं।

एक और दृष्टिकोण है, सोलारिस में Dtrace जैसे तंत्र के माध्यम से जो आपको रनिंग प्रक्रियाओं में इंजेक्ट करने की अनुमति देता है (मेरा मानना ​​है कि C # में भी ऐसा ही करने का तरीका है!) इसलिए लॉगिंग और स्टेटिस्टिक सभाओं को रनटाइम पर परिभाषित किया जा सकता है। फिर भी अन्य कमियां हैं।


एक समस्या जिसे एओपी हल करने की कोशिश कर रहा है वह है गैर-व्यावसायिक कोड (जैसे लॉगिंग कॉल) के अपठनीय बनने की समस्या "व्यापार कोड" के साथ इंटरव्यू। एक "श्रोता" द्वारा "लकड़हारा" को बदलने से यह हल नहीं होता है, कोड की पठनीयता में बदलाव नहीं होता है,
डॉक ब्राउन

2

एक और तरीका है बिजनेस लॉगिंग और टेक्निकल लॉगिंग को अलग रखना। फिर हम व्यापार लॉगिंग को "ऑडिट" कह सकते हैं और व्यापार नियमों के एक विशिष्ट सेट को स्टोरेज टर्म और बिजनेस एक्टिविटी मॉनिटरिंग जैसे प्रसंस्करण नियमों को लागू कर सकते हैं।

दूसरी ओर, तकनीकी लॉगिंग, या बस "लॉगिंग", तकनीकी समस्या का एक निशान छोड़ने के लिए अंतिम उपाय का एक साधन है। लॉग संदेश को बनाए रखने में विफलता के लिए यह async, तेज, सहिष्णु होना चाहिए। इसके अलावा, लॉग संदेशों को समस्या के स्रोत के करीब होने के लिए संभव कम से कम प्रॉक्सी से गुजरना चाहिए।

लॉगिंग का तर्क काफी परिवर्तनशील है और इसे कार्यान्वयन के साथ कसकर जोड़ा जाता है, इसलिए क्या आपको वास्तव में इसे कोड से अलग करने की आवश्यकता है?

ऑडिट का तर्क एक डोमेन तर्क माना जाना चाहिए और तदनुसार संभाला जाना चाहिए।

उदाहरण के लिए, हेक्सागोनल वास्तुकला में ग्राहकों, भंडारण और एमक्यू (और, संभवतः, मैट्रिक्स और नियंत्रण) बंदरगाहों के साथ ऑडिट पोर्ट भी हो सकता है। यह द्वितीयक पोर्ट होगा, अर्थात इस पोर्ट पर गतिविधि को बाहरी प्रणालियों के बजाय व्यावसायिक कोर द्वारा ट्रिगर किया जाता है।


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

@Charlie हाँ, "द लॉगिंग" से मेरा मतलब तकनीकी लॉगिंग से है। प्रवेश / निकास / पैरामीटर मान लॉगिंग शुद्ध कार्यों के मामले में पर्याप्त है। तब, या बेशक, आप एक पहलू या लकड़हारा मोनाद का उपयोग कर सकते हैं। लेकिन शुद्ध कार्य महान हैं कि वे परीक्षण करने योग्य हैं। तो, मुद्दों, लकड़हारा ट्रेस करने के लिए माना जाता है, देव / डिबग के दौरान हल होने की संभावना है। अशुद्ध कार्यों के साथ, जहाँ टेक लॉगिंग का सबसे अधिक उपयोग होता है, आप हर पक्ष-प्रभावी कॉल परमेस / परिणाम, हर अपवाद को लॉग इन करना चाहते हैं।
iTollu

1

कक्षा या विधि में सीधे प्रवेश करने से बचने के तरीके:

  1. एक अपवाद को फेंक दें, और अपने लॉग इन को कॉल ट्री को आगे बढ़ाएं। यदि आपको लॉग स्तर पर कब्जा करने की आवश्यकता है, तो आप एक कस्टम अपवाद फेंक सकते हैं।

  2. लॉगिंग के लिए पहले से ही इंस्ट्रूमेंट किए गए तरीकों से कॉल करें।


1
क्या लॉगिंग किया जा रहा है जहां इसे एक समस्या के रूप में दिखाया गया है, और एक भी "फिक्सिंग" के लायक है?
whatsisname

1

क्या वास्तव में अपने व्यापार तर्क से अपनी लॉगिंग को अलग करना आवश्यक है? लॉग किया जा रहा है व्यापार तर्क के लिए लिखा पत्राचार में है और इसलिए एक ही कक्षा / समारोह में होने के लिए समझ में आता है। इससे भी महत्वपूर्ण बात, यह कोड की पठनीयता को आसान बनाता है।

हालाँकि, यदि आप वास्तव में अपने व्यावसायिक तर्क से लॉगिंग को अलग करना चाहते हैं, तो आपको कस्टम अपवादों को फेंकने और लॉगिंग के लिए उन अपवादों को सौंपने पर विचार करना चाहिए।


0

नहीं, सी # में नहीं

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

आप लॉगिंग के कुछ बिट्स को "एप्सेक्ट-आइज़" कर सकते हैं

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

वैसे भी लॉग लेखन एक पहलू नहीं है

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

दूसरे शब्दों में, लॉग लेखन और इस बारे में लिखे जा रहे सामान के बीच एक अटूट तार्किक निर्भरता है। आप इसे सामान्य नहीं कर सकते।

लेकिन ऑडिटिंग है

यदि आपके पास किसी प्रकार की कार्यात्मक लॉगिंग आवश्यकता है (जैसे किसी गैर-प्रतिदान की आवश्यकता के समर्थन में ऑडिट लॉगिंग ), तो कुछ तर्क देंगे (और मैं सहमत हूँ) कि यदि आप अपने आप को इन लॉग को निष्पादित करने की आवश्यकता पाते हैं तो एक विधि के बीच में लिखते हैं; आपने अपने कोड को उस तरीके से संरचित नहीं किया है जो पहलू-उन्मुख सोच के अनुरूप हो। यदि ऐसा होता है, तो आपको अलग-अलग तरीकों से कोड निकालना चाहिए जब तक कि आपको अपनी जरूरत के स्तर को प्राप्त नहीं हो जाता।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.