JSON ट्रेस प्रोफ़ाइल

JSON ट्रेस प्रोफ़ाइल, यह समझने में काफ़ी मददगार साबित हो सकती है कि Bazel ने किसी कार्रवाई के दौरान कितना समय लिया.

डिफ़ॉल्ट रूप से, Bazel, बिल्ड जैसे सभी कमांड और क्वेरी के लिए, आउटपुट बेस में command-$INVOCATION_ID.profile.gz नाम की एक प्रोफ़ाइल लिखता है. यहां $INVOCATION_ID कमांड का आइडेंटिफ़ायर होता है. Bazel, आउटपुट बेस में command.profile.gz नाम का एक सिंबॉलिक लिंक भी बनाता है. यह लिंक, सबसे नए कमांड की प्रोफ़ाइल की ओर इशारा करता है. यह कॉन्फ़िगर किया जा सकता है कि --generate_json_trace_profile फ़्लैग के साथ कोई प्रोफ़ाइल लिखी जाए या नहीं. साथ ही, --profile फ़्लैग की मदद से, यह भी कॉन्फ़िगर किया जा सकता है कि प्रोफ़ाइल किस जगह लिखी जाए. .gz से खत्म होने वाली जगहों को GZIP से कंप्रेस किया जाता है. Bazel, पोस्ट-बिल्ड विश्लेषण के लिए, डिफ़ॉल्ट रूप से आउटपुट बेस में पिछली पांच प्रोफ़ाइलें सेव रखता है. --profiles_to_retain, प्रोफ़ाइल का पाथ, --profile के साथ साफ़ तौर पर पास करने पर, गार्बेज कलेक्शन की प्रोसेस अपने-आप नहीं होती.

टूल

इस प्रोफ़ाइल को chrome://tracing में लोड किया जा सकता है. इसके अलावा, इसे अन्य टूल की मदद से ऐनलाइज़ और पोस्ट-प्रोसेस किया जा सकता है.

chrome://tracing

प्रोफ़ाइल को विज़ुअलाइज़ करने के लिए, Chrome ब्राउज़र के किसी टैब में chrome://tracing खोलें. इसके बाद, "लोड करें" पर क्लिक करें और (कंप्रेस की गई) प्रोफ़ाइल फ़ाइल चुनें. ज़्यादा जानकारी वाले नतीजे पाने के लिए, नीचे बाईं ओर मौजूद बॉक्स पर क्लिक करें.

प्रोफ़ाइल का उदाहरण:

प्रोफ़ाइल का उदाहरण

पहली इमेज. प्रोफ़ाइल का उदाहरण.

नेविगेट करने के लिए, कीबोर्ड के इन कंट्रोल का इस्तेमाल किया जा सकता है:

  • "चुनें" मोड के लिए, 1 दबाएं. इस मोड में, इवेंट की जानकारी देखने के लिए, खास बॉक्स चुने जा सकते हैं. ज़्यादा जानकारी के लिए, नीचे बाईं ओर देखें. खास जानकारी और एग्रीगेट किए गए आंकड़े पाने के लिए, एक से ज़्यादा इवेंट चुनें.
  • "पैन" मोड के लिए, 2 दबाएं. इसके बाद, व्यू को एक जगह से दूसरी जगह ले जाने के लिए, माउस को खींचें और छोड़ें. बाएं/दाएं जाने के लिए, a/d का भी इस्तेमाल किया जा सकता है.
  • "ज़ूम" मोड के लिए, 3 दबाएं. इसके बाद, ज़ूम करने के लिए, माउस को खींचें और छोड़ें. ज़ूम इन/आउट करने के लिए, w/s का भी इस्तेमाल किया जा सकता है.
  • "टाइमिंग" मोड के लिए, 4 दबाएं. इस मोड में, दो इवेंट के बीच की दूरी मेज़र की जा सकती है.
  • सभी कंट्रोल के बारे में जानने के लिए, ? दबाएं.

Bazel Invocation Analyzer

ओपन-सोर्स Bazel Invocation Analyzer प्रोफ़ाइल फ़ॉर्मैट का इस्तेमाल करता है. साथ ही, यह सुझाव देता है कि बिल्ड की परफ़ॉर्मेंस को कैसे बेहतर बनाया जाए. यह विश्लेषण, इसके सीएलआई का इस्तेमाल करके या https://analyzer.engflow.com पर किया जा सकता है.

jq

jq, JSON डेटा के लिए sed की तरह काम करता है. लोकल ऐक्शन के एक्ज़ीक्यूशन में, सैंडबॉक्स बनाने के चरण की सभी अवधियां निकालने के लिए, jq के इस्तेमाल का उदाहरण:

$ zcat $(../bazel-6.0.0rc1-linux-x86_64 info output_base)/command.profile.gz | jq '.traceEvents | .[] | select(.name == "sandbox.createFileSystem") | .dur'
6378
7247
11850
13756
6555
7445
8487
15520
[...]

प्रोफ़ाइल की जानकारी

प्रोफ़ाइल में कई लाइनें होती हैं. आम तौर पर, ज़्यादातर लाइनों में Bazel के थ्रेड और उनसे जुड़े इवेंट की जानकारी होती है. हालांकि, इसमें कुछ खास लाइनें भी शामिल होती हैं.

शामिल की गई खास लाइनें, प्रोफ़ाइल बनाते समय इस्तेमाल किए गए Bazel के वर्शन पर निर्भर करती हैं. साथ ही, इन्हें अलग-अलग फ़्लैग की मदद से पसंद के मुताबिक बनाया जा सकता है.

पहली इमेज में, Bazel के वर्शन 5.3.1 से बनाई गई प्रोफ़ाइल दिखाई गई है. इसमें ये लाइनें शामिल हैं:

  • action count: इससे पता चलता है कि एक साथ कितनी कार्रवाइयां हो रही थीं. असल वैल्यू देखने के लिए, इस पर क्लिक करें. क्लीन बिल्ड में, इसकी वैल्यू --jobs की वैल्यू के बराबर होनी चाहिए.
  • CPU usage (Bazel): इससे पता चलता है कि बिल्ड के हर सेकंड में, Bazel ने कितना सीपीयू इस्तेमाल किया. वैल्यू 1 का मतलब है कि एक कोर 100% व्यस्त है.
  • Critical Path: इससे, क्रिटिकल पाथ पर मौजूद हर कार्रवाई के लिए एक ब्लॉक दिखता है.
  • Main Thread: यह Bazel का मुख्य थ्रेड है. इससे यह समझने में मदद मिलती है कि Bazel क्या कर रहा है. जैसे, "Launch Blaze", "evaluateTargetPatterns" और "runAnalysisPhase".
  • Garbage Collector: इससे, गार्बेज कलेक्शन (जीसी) के दौरान होने वाले छोटे और बड़े पॉज़ दिखते हैं.

परफ़ॉर्मेंस से जुड़ी सामान्य समस्याएं

परफ़ॉर्मेंस प्रोफ़ाइल का विश्लेषण करते समय, इन चीज़ों पर ध्यान दें:

  • उम्मीद से ज़्यादा समय लेने वाला विश्लेषण फ़ेज़ (runAnalysisPhase), खास तौर पर इंक्रीमेंटल बिल्ड पर. यह खराब तरीके से लागू किए गए नियम का संकेत हो सकता है. जैसे, ऐसा नियम जो depsets को फ़्लैट करता है. ज़्यादा टारगेट, जटिल मैक्रो या रिकर्सिव ग्लोब की वजह से, पैकेज लोड होने में ज़्यादा समय लग सकता है.
  • धीरे-धीरे होने वाली कार्रवाइयां, खास तौर पर क्रिटिकल पाथ पर होने वाली कार्रवाइयां. बड़ी कार्रवाइयों को कई छोटी कार्रवाइयों में बांटा जा सकता है या (ट्रांज़िटिव) डिपेंडेंसी का सेट कम किया जा सकता है, ताकि उन्हें तेज़ी से किया जा सके. साथ ही, PROCESS_TIME के अलावा, किसी अन्य चीज़ के लिए असामान्य रूप से ज़्यादा समय लगने की समस्या भी देखें. जैसे, REMOTE_SETUP या FETCH.
  • बॉटलनेक. इसका मतलब है कि कुछ थ्रेड व्यस्त हैं, जबकि बाकी थ्रेड आइडल हैं या नतीजे का इंतज़ार कर रहे हैं. ज़्यादा जानकारी के लिए, पहली इमेज में 22वें और 29वें सेकंड के आस-पास देखें. इसे ऑप्टिमाइज़ करने के लिए, नियम लागू करने या Bazel में बदलाव करने की ज़रूरत पड़ सकती है, ताकि ज़्यादा पैरललिज़्म लाया जा सके. ऐसा तब भी हो सकता है, जब जीसी में असामान्य रूप से ज़्यादा समय लगता हो.

प्रोफ़ाइल फ़ाइल फ़ॉर्मैट

टॉप-लेवल ऑब्जेक्ट में, मेटाडेटा (otherData) और असल ट्रेसिंग डेटा (traceEvents) शामिल होता है. मेटाडेटा में अतिरिक्त जानकारी होती है. जैसे, Bazel के इस्तेमाल का आईडी और तारीख.

उदाहरण:

{
  "otherData": {
    "build_id": "101bff9a-7243-4c1a-8503-9dc6ae4c3b05",
    "date": "Wed Oct 26 08:22:35 CEST 2022",
    "profile_finish_ts": "1677666095162000",
    "output_base": "/usr/local/google/_bazel_johndoe/573d4be77eaa72b91a3dfaa497bf8cd0"
  },
  "traceEvents": [
    {"name":"thread_name","ph":"M","pid":1,"tid":0,"args":{"name":"Critical Path"}},
    ...
    {"cat":"build phase marker","name":"Launch Blaze","ph":"X","ts":-1306000,"dur":1306000,"pid":1,"tid":21},
    ...
    {"cat":"package creation","name":"foo","ph":"X","ts":2685358,"dur":784,"pid":1,"tid":246},
    ...
    {"name":"thread_name","ph":"M","pid":1,"tid":11,"args":{"name":"Garbage Collector"}},
    {"cat":"gc notification","name":"minor GC","ph":"X","ts":825986,"dur":11000,"pid":1,"tid":11},
    ...
    {"cat":"action processing","name":"Compiling foo/bar.c","ph":"X","ts":54413389,"dur":357594,"pid":1,"args":{"mnemonic":"CppCompile"},"tid":341},
 ]
}

ट्रेस इवेंट में, टाइमस्टैंप (ts) और अवधि (dur) माइक्रोसेकंड में दी जाती हैं. कैटगरी (cat), ProfilerTask की enum वैल्यू में से एक होती है. ध्यान दें कि कुछ इवेंट को एक साथ मर्ज कर दिया जाता है, अगर वे बहुत कम समय के लिए होते हैं और एक-दूसरे के आस-पास होते हैं . अगर आपको इवेंट मर्ज होने से रोकना है, तो --noslim_profile पास करें.

Chrome Trace Event Format Specification भी देखें.