विश्व स्तर पर अद्वितीय संदेश आईडी का उपयोग करके कोड को खोजने योग्य बनाना


39

बग का पता लगाने का एक सामान्य पैटर्न इस स्क्रिप्ट का अनुसरण करता है:

  1. उदाहरण के लिए, कोई आउटपुट या एक लटका हुआ कार्यक्रम, अजीबता का निरीक्षण करें।
  2. लॉग या प्रोग्राम आउटपुट में प्रासंगिक संदेश का पता लगाएँ, उदाहरण के लिए, "फू नहीं मिल सका"। (निम्नलिखित केवल तभी प्रासंगिक है यदि यह बग का पता लगाने के लिए लिया गया मार्ग है। यदि स्टैक ट्रेस या अन्य डीबगिंग जानकारी आसानी से उपलब्ध है, तो यह एक और कहानी है।)
  3. संदेश मुद्रित किया जाता है, जहां कोड का पता लगाएँ।
  4. पहली जगह फू के बीच कोड को डीबग करें (या दर्ज करना चाहिए) चित्र और जहां संदेश मुद्रित होता है।

वह तीसरा चरण वह है जहां डिबगिंग प्रक्रिया अक्सर रुक जाती है क्योंकि कोड में कई जगह हैं जहां "फू नहीं मिल सका" (या एक टेम्पर्ड स्ट्रिंग Could not find {name}) मुद्रित किया जाता है। वास्तव में, कई बार एक वर्तनी की गलती से मुझे वास्तविक स्थान को खोजने में बहुत तेजी से मदद मिली, अन्यथा मैं - यह संदेश पूरे सिस्टम में और अक्सर दुनिया भर में अद्वितीय बना देता था, जिसके परिणामस्वरूप एक प्रासंगिक खोज इंजन तुरंत हिट हो गया।

इससे स्पष्ट निष्कर्ष यह है कि हमें कोड में विश्व स्तर पर अद्वितीय संदेश आईडी का उपयोग करना चाहिए, इसे संदेश स्ट्रिंग के भाग के रूप में हार्ड कोडिंग करना चाहिए, और संभवतः यह सत्यापित करना होगा कि कोड आधार में प्रत्येक आईडी की केवल एक घटना है। स्थिरता के संदर्भ में, इस समुदाय को लगता है कि इस दृष्टिकोण के सबसे महत्वपूर्ण पेशेवरों और विपक्ष हैं, और आप इसे कैसे लागू करेंगे या अन्यथा यह सुनिश्चित करेंगे कि इसे लागू करना कभी भी आवश्यक नहीं होगा (यह मानते हुए कि सॉफ़्टवेयर में हमेशा कीड़े होंगे)।


54
इसके बजाय अपने स्टैक के निशान का उपयोग करें। स्टैक ट्रेस आपको न केवल ठीक से बताएगा कि त्रुटि कहां हुई, बल्कि प्रत्येक फ़ंक्शन जो इसे कहा जाता है, प्रत्येक फ़ंक्शन को कॉल करता है। यदि आवश्यक हो तो अपवाद होने पर संपूर्ण ट्रेस लॉग करें। यदि आप ऐसी भाषा में काम कर रहे हैं जिसमें अपवाद नहीं हैं, जैसे C, तो यह एक अलग कहानी है।
रॉबर्ट हार्वे

6
@ l0b0 शब्दांकन पर एक छोटी सलाह। "इस समुदाय को क्या लगता है ... पेशेवरों और विपक्ष" ऐसे वाक्यांश हैं जिन्हें बहुत व्यापक रूप में देखा जा सकता है। यह एक ऐसी साइट है जो "अच्छे व्यक्तिपरक" प्रश्नों के लिए अनुमति देती है, और इस प्रकार के प्रश्नों की अनुमति देने के बदले में, ओपी से अपेक्षा की जाएगी कि वे एक सार्थक सहमति की ओर टिप्पणियों और उत्तरों को "शेफर्ड" करने का काम करें।
रवांग

@rwong धन्यवाद! मुझे लगता है कि प्रश्न पहले से ही एक बहुत अच्छा और बिंदु प्रतिक्रिया पर प्राप्त हुआ है, हालांकि यह बेहतर तरीके से एक मंच में पूछा जा सकता है। मैंने जॉनवेव की स्पष्ट प्रतिक्रिया को पढ़ने के बाद रॉबर्टहर्वे की टिप्पणी पर अपनी प्रतिक्रिया वापस ले ली, इस मामले में कि आप क्या कर रहे हैं। यदि नहीं, तो क्या आपके पास कोई विशिष्ट चरवाहा सुझाव है?
l0b0

1
मेरे संदेश ऐसे दिखते हैं जैसे "बार को कॉल करने के दौरान फू को ढूंढ नहीं पाए" ()। समस्या सुलझ गयी। श्रग। डाउनसाइड यह ग्राहकों द्वारा देखे जाने के लिए थोड़ा टपका हुआ है, लेकिन हम वैसे भी उनसे त्रुटि संदेशों के विस्तार को छिपाने के लिए करते हैं, यह केवल उन sysadmins के लिए उपलब्ध है जो एक बंदर को नहीं दे सकते हैं कि उन्हें कुछ फ़ंक्शन नाम देखने को मिलते हैं। असफल होना, हाँ, एक अच्छा सा अनोखा आईडी / कोड ट्रिक करेगा।
मोनिका

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

जवाबों:


12

कुल मिलाकर यह एक मान्य और मूल्यवान रणनीति है। यहाँ कुछ विचार हैं।

इस रणनीति को इस अर्थ में "टेलीमेट्री" के रूप में भी जाना जाता है कि जब इस तरह की सभी जानकारी संयुक्त होती है, तो वे निष्पादन ट्रेस को "ट्राइंगुलेट" करने में मदद करते हैं और एक समस्या निवारक को यह समझने की अनुमति देते हैं कि उपयोगकर्ता / आवेदन पूरा करने की कोशिश कर रहा है, और वास्तव में क्या हुआ है ।

डेटा के कुछ आवश्यक टुकड़े जिन्हें एकत्र किया जाना चाहिए (जो हम सभी जानते हैं) हैं:

  • कोड का स्थान, यानी कॉल स्टैक और कोड की अनुमानित रेखा
    • यदि फ़ंक्शन यथोचित रूप से छोटी इकाइयों में विघटित हो, तो "कोड की अनुमानित रेखा" की आवश्यकता नहीं है।
  • डेटा के किसी भी टुकड़े जो फ़ंक्शन की सफलता / विफलता के लिए प्रासंगिक हैं
  • एक उच्च-स्तरीय "कमांड" जो मानव उपयोगकर्ता / बाहरी एजेंट / एपीआई उपयोगकर्ता को पूरा करने के लिए प्रयास कर सकता है।
    • विचार यह है कि एक सॉफ्टवेयर स्वीकार करेगा और कहीं से आने वाले आदेशों को संसाधित करेगा।
    • इस प्रक्रिया के दौरान, दर्जनों से सैकड़ों से हजारों फ़ंक्शन कॉल हो सकते हैं।
    • हम चाहते हैं कि इस प्रक्रिया के दौरान उत्पन्न किसी भी टेलीमेट्री को उच्चतम-स्तरीय कमांड में वापस लाया जा सके जो इस प्रक्रिया को ट्रिगर करता है।
    • वेब-आधारित प्रणालियों के लिए, मूल HTTP अनुरोध और इसका डेटा ऐसी "उच्च-स्तरीय अनुरोध जानकारी" का एक उदाहरण होगा।
    • जीयूआई सिस्टम के लिए, कुछ पर क्लिक करने वाला उपयोगकर्ता इस विवरण को फिट करेगा।

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

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

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

यहां तक ​​कि उपयोगिता कार्यों को "ट्रेसर" तर्क को जोड़ने की आवश्यकता होगी, ताकि यदि यह विफल हो जाए, तो लॉग संदेश स्वयं को एक निश्चित उच्च-स्तरीय कमांड के साथ सहसंबद्ध होने की अनुमति देगा।

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

लॉग संदेश लिखने के संदर्भ में:

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

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

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

58

कल्पना कीजिए कि आपके पास एक तुच्छ उपयोगिता कार्य है जो आपके कोड में सैकड़ों स्थानों पर उपयोग किया जाता है:

decimal Inverse(decimal input)
{
    return 1 / input;
}

यदि हम सुझाव के अनुसार करें, तो हम लिख सकते हैं

decimal Inverse(decimal input)
{
    try 
    {
        return 1 / input;
    }
    catch(Exception ex)
    {
        log.Write("Error 27349262 occurred.");
    }
}

यदि इनपुट शून्य था, तो एक त्रुटि हो सकती है; इसका परिणाम शून्य अपवाद द्वारा विभाजित होगा।

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

मुझे लगता है कि यदि आप संदेश आईडी लॉगिंग को परेशान करने जा रहे हैं, तो आप स्टैक ट्रेस भी लॉग कर सकते हैं।

यदि स्टैक ट्रेस की वाचालता आपको परेशान करती है, तो आपको इसे स्ट्रिंग के रूप में डंप नहीं करना है, जिस तरह से रनटाइम आपको देता है। आप इसे कस्टमाइज़ कर सकते हैं। उदाहरण के लिए, यदि आप एक संक्षिप्त स्टैक ट्रेस चाहते हैं जो केवल nस्तरों पर जा रहा है, तो आप कुछ ऐसा लिख ​​सकते हैं (यदि आप c # का उपयोग करते हैं):

static class ExtensionMethods
{
    public static string LimitedStackTrace(this Exception input, int layers)
    {
        return string.Join
        (
            ">",
            new StackTrace(input)
                .GetFrames()
                .Take(layers)
                .Select
                (
                    f => f.GetMethod()
                )
                .Select
                (
                    m => string.Format
                    (
                        "{0}.{1}", 
                        m.DeclaringType, 
                        m.Name
                    )
                )
                .Reverse()
        );
    }
}

और इसे इस तरह से उपयोग करें:

public class Haystack
{
    public static void Needle()
    {
        throw new Exception("ZOMG WHERE DID I GO WRONG???!");
    }

    private static void Test()
    {
        Needle();
    }

    public static void Main()
    {
        try
        {
            Test();
        }
        catch(System.Exception e)
        {
            //Get 3 levels of stack trace
            Console.WriteLine
            (
                "Error '{0}' at {1}", 
                e.Message, 
                e.LimitedStackTrace(3)
            );  
        }
    }
}

आउटपुट:

Error 'ZOMG WHERE DID I GO WRONG???!' at Haystack.Main>Haystack.Test>Haystack.Needle

शायद संदेश आईडी बनाए रखने की तुलना में आसान है, और अधिक लचीला।

DotNetFiddle से मेरा कोड चोरी करें


32
हम्म मुझे लगता है कि मैं अपनी बात स्पष्ट रूप से पर्याप्त नहीं बना पाया। मुझे पता है कि वे अद्वितीय रॉबर्ट हैं - प्रति कोड स्थान। वे प्रति कोड पथ के लिए अद्वितीय नहीं हैं स्थान जानना अक्सर बेकार होता है, उदाहरण के लिए अगर सही समस्या यह है कि एक इनपुट ठीक से सेट नहीं किया गया था। मैंने जोर देने के लिए अपनी भाषा को थोड़ा संपादित किया है।
जॉन वू

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

12
यदि आप इनमें से इतने सारे प्राप्त कर रहे हैं कि आप अपने आई / ओ को बाढ़ने के बारे में चिंतित हैं, तो कुछ गंभीर रूप से गलत है। या आप सिर्फ कंजूस हो रहे हैं? वास्तविक प्रदर्शन हिट शायद ढेर खोलना है।
जॉन वू

9
स्टैक निशान को छोटा करने के लिए एक समाधान के साथ संपादित, यदि आप 3.5 फ्लॉपी में लॉग लिख रहे हैं;)
जॉन वू

7
@ जॉनव्हु और "IOException 'फ़ाइल नहीं मिली' पर [...] को मत भूलना" जो आपको कॉल स्टैक की पचास परतों के बारे में बताता है, लेकिन यह नहीं बताता कि क्या सटीक खूनी फ़ाइल नहीं मिली।
जोकर_विद

6

SAP NetWeaver दशकों से ऐसा कर रही है।

यह एक मूल्यवान उपकरण साबित हुआ है जब बड़े पैमाने पर कोड में त्रुटियों का निवारण किया जाता है जो कि विशिष्ट SAP ERP प्रणाली है।

त्रुटि संदेश एक केंद्रीय रिपॉजिटरी में प्रबंधित किए जाते हैं जहां प्रत्येक संदेश को उसके संदेश वर्ग और संदेश संख्या द्वारा पहचाना जाता है।

जब आप किसी त्रुटि संदेश को छोड़ना चाहते हैं, तो आप केवल राज्य वर्ग, संख्या, गंभीरता और संदेश-विशिष्ट चर बनाते हैं। संदेश का पाठ प्रतिनिधित्व रनटाइम पर बनाया गया है। आप आमतौर पर संदेश वर्ग और संख्या को किसी भी संदर्भ में देखते हैं जहाँ संदेश दिखाई देते हैं। इसके कई साफ प्रभाव हैं:

  • आप स्वचालित रूप से ABAP कोडबेस में कोड की कोई भी रेखा पा सकते हैं जो एक विशिष्ट त्रुटि संदेश बनाता है।

  • आप डायनेमिक डीबगर ब्रेकपॉइंट सेट कर सकते हैं जो एक विशिष्ट त्रुटि संदेश उत्पन्न होने पर ट्रिगर होता है।

  • आप SAP नॉलेज बेस लेखों में त्रुटियों को देख सकते हैं और यदि आप "फू नहीं पा सके" की तुलना में अधिक प्रासंगिक खोज परिणाम प्राप्त कर सकते हैं।

  • संदेशों के पाठ निरूपण अनुवाद योग्य हैं। तो तार के बजाय संदेशों के उपयोग को प्रोत्साहित करने से आपको i18n क्षमताएं भी मिलती हैं।

संदेश संख्या के साथ त्रुटि पॉपअप का एक उदाहरण:

error1

त्रुटि रिपॉजिटरी में उस त्रुटि को देखना:

error2

इसे कोडबेस में खोजें:

error3

हालांकि, कमियां हैं। जैसा कि आप देख सकते हैं, कोड की ये लाइनें अब स्व-दस्तावेजीकरण नहीं हैं। जब आप sourcecode पढ़ते हैं और MESSAGEऊपर दिए गए स्क्रीनशॉट में उन जैसे एक बयान देखते हैं , तो आप केवल संदर्भ से अनुमान लगा सकते हैं कि इसका वास्तव में क्या मतलब है। इसके अलावा, कभी-कभी लोग कस्टम त्रुटि हैंडलर लागू करते हैं जो रनटाइम के दौरान संदेश वर्ग और संख्या प्राप्त करते हैं। उस स्थिति में त्रुटि स्वचालित रूप से नहीं मिल सकती है या उस स्थान पर नहीं मिल सकती है जहां त्रुटि वास्तव में हुई है। पहली समस्या के लिए समाधान यह है कि यह एक आदत है कि हमेशा सोर्सकोड में एक टिप्पणी जोड़ें जो पाठक को बताए कि संदेश का क्या मतलब है। स्वचालित संदेश लुकअप कार्यों को सुनिश्चित करने के लिए कुछ मृत कोड जोड़कर दूसरा हल किया जाता है। उदाहरण:

" Do not use special characters
my_custom_error_handler->post_error( class = 'EU' number = '271').
IF 1 = 2.
   MESSAGE e271(eu).
ENDIF.    

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


मैसेज कैटलॉग भी कुछ समय के लिए जीएनयू / लिनक्स - और यूनिक्स आमतौर पर पोसिक्स मानक के रूप में रहे हैं।
बिशप

@ बिशप मैं आमतौर पर POSIX सिस्टम के लिए विशेष रूप से प्रोग्रामिंग नहीं कर रहा हूं, इसलिए मैं इससे परिचित नहीं हूं। शायद आप एक और उत्तर पोस्ट कर सकते हैं जो पोसिक्स संदेश कैटलॉग बताते हैं और ओपी उनके कार्यान्वयन से क्या सीख सकता है।
फिलिप

3
मैं एक ऐसी परियोजना का हिस्सा था जिसने यह वापस आउटीज़ में किया। एक मुद्दा जो हमने चलाया था, वह था, बाकी सब चीजों के साथ, हमने डेटाबेस में "डेटाबेस से कनेक्ट नहीं कर सका" के लिए मानव संदेश डाल दिया।
जिमीजैम

5

उस दृष्टिकोण के साथ समस्या यह है कि यह कभी भी अधिक विस्तृत लॉगिंग की ओर जाता है। 99.9999% जिसमें से आप कभी नहीं देखेंगे।

इसके बजाय, मैं आपकी प्रक्रिया की शुरुआत और प्रक्रिया की सफलता / असफलता पर राज्य को पकड़ने की सलाह देता हूं।

यह आपको स्थानीय रूप से बग को पुन: पेश करने की अनुमति देता है, कोड के माध्यम से आगे बढ़ता है और आपके लॉगिंग को प्रति प्रक्रिया दो स्थानों तक सीमित करता है। जैसे।

OrderPlaced {id:xyz; ...order data..}
OrderPlaced {id:xyz; ...Fail, ErrorMessage..}

अब मैं अपने डीबग मशीन पर कोड के माध्यम से, अपने डिबगर में कोड के माध्यम से कदम और फिक्स की पुष्टि करने के लिए एक नया यूनिट टेस्ट लिखने के लिए सटीक राज्य का उपयोग कर सकता हूं।

इसके अलावा, यदि आवश्यक हो तो मैं केवल लॉग इन विफलताओं या राज्य को कहीं और रख कर (डेटाबेस? संदेश कतार) से अधिक लॉगिंग से बच सकता हूं?

जाहिर है हमें संवेदनशील डेटा लॉग करने के बारे में अतिरिक्त सावधानी बरतनी होगी। तो यह विशेष रूप से अच्छी तरह से काम करता है अगर आपका समाधान संदेश कतारों या इवेंट स्टोर पैटर्न का उपयोग कर रहा है। जैसा कि लॉग को केवल "संदेश xyz विफल" कहना चाहिए


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

यदि आपका सिस्टम कतारों या डीबी से चलता है तो डेटा पहले से ही है, और इसलिए सुरक्षा चाहिए। लॉगिंग बहुत खराब है क्योंकि लॉग आपके सुरक्षा नियंत्रण से बाहर हो जाता है।
इवान

सही है, लेकिन यह बात है। यह सलाह दी जाती है क्योंकि यह डेटा स्थायी रूप से और आमतौर पर पूरी तरह से स्पष्ट पाठ में रहता है। संवेदनशील डेटा के लिए, यह बेहतर है कि आप केवल जोखिम न लें और कम से कम जहां आप इसे अवधि के लिए जमा कर रहे हैं, और फिर बहुत जागरूक और बहुत सावधान रहें कि आप इसे कैसे संग्रहीत कर रहे हैं।
jpmc26

यह परंपरागत रूप से स्थायी है क्योंकि आप एक फाइल पर लिख रहे हैं। लेकिन एक त्रुटि कतार क्षणिक है।
इवान

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

1

मेरा सुझाव है कि लॉगिंग इस बारे में जाने का तरीका नहीं है, बल्कि यह है कि इस परिस्थिति को असाधारण माना जाता है (यह आपके प्रोग्राम को लॉक कर देता है) और एक अपवाद को फेंक दिया जाना चाहिए। कहो कि आपका कोड था:

public Foo GetFoo() {

     //Expecting that this should never by null.
     var aFoo = ....;

     if (aFoo == null) Log("Could not find Foo.");

     return aFoo;
}

ऐसा लगता है कि आप कॉलिंग कोड को इस तथ्य से निपटने के लिए सेट नहीं किया गया है कि फू मौजूद नहीं है और आपको संभावित रूप से होना चाहिए:

public Foo GetFooById(int id) {
     var aFoo = ....;

     if (aFoo == null) throw new ApplicationException("Could not find Foo for ID: " + id);

     return aFoo;
}

और यह एक स्टैक ट्रेस को अपवाद के साथ लौटाएगा जिसका उपयोग डीबगिंग में मदद करने के लिए किया जा सकता है।

वैकल्पिक रूप से, अगर हम उम्मीद करते हैं कि रिट होने पर फू शून्य हो सकता है और यह ठीक है, तो हमें कॉलिंग साइटों को ठीक करने की आवश्यकता है:

void DoSomeFoo(Foo aFoo) {

    //Guard checks on your input - complete with stack trace!
    if (aFoo == null) throw new ArgumentNullException(nameof(aFoo));

    ... operations on Foo...
}

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


0

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

उस ने कहा, यह वास्तव में इस बात पर निर्भर करता है कि आप अपनी आईडी क्या चाहते हैं:

  • आपके लॉग में उपयोगकर्ता को प्रदान किए गए सहसंबंधी त्रुटि संदेश?
  • संदेश उत्पन्न होने पर कौन सा कोड निष्पादित कर रहा था, इस पर संकेतन प्रदान करें।
  • मशीन के नाम और सेवा उदाहरण पर नज़र रखें?
  • थ्रेड आईडी का ध्यान रखें?

इन सभी चीजों को उचित लॉगिंग सॉफ़्टवेयर (यानी नहीं Console.WriteLine()या नहीं Debug.WriteLine()) के साथ बॉक्स से बाहर किया जा सकता है ।

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

हर संदेश के साथ बदलने वाली अपारदर्शी आईडी बहुत उपयोगी नहीं है। एक सुसंगत आईडी का उपयोग माइक्रोसर्विस के पूरे सूट के माध्यम से व्यवहार का पता लगाने के लिए किया गया ... बेहद उपयोगी।

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