37 पॉइंट द्वारा GN⁺ 2025-12-22 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • आधुनिक distributed systems में पारंपरिक logging तरीकों की ऐसी संरचनात्मक सीमाएँ हैं कि वे सच्चाई नहीं बता पाते
  • logs अब भी 2005-स्टाइल single-server environment को मानकर डिज़ाइन किए गए हैं, इसलिए कई services, databases और cache से गुजरने वाले request का context खो जाता है
  • साधारण string search structure, relation, correlation को नहीं समझती, जिससे समस्या की जड़ तक पहुँचना मुश्किल हो जाता है
  • इसका समाधान है कि हर request के लिए सभी context वाला एक single ‘Wide Event(या Canonical Log Line)’ छोड़ा जाए
  • इससे logs सिर्फ text नहीं रहते, बल्कि analyzable data asset में बदल जाते हैं

लॉगिंग की मूल समस्या

  • मौजूदा logs monolithic server युग को ध्यान में रखकर बनाए गए थे, इसलिए वे आज की distributed service architecture को reflect नहीं करते
    • एक request कई services, DB, cache और queue से होकर गुजरता है, लेकिन logs अब भी single server के हिसाब से लिखे जाते हैं
  • उदाहरण logs में एक request पर 13 lines बनती हैं, इसलिए 10,000 concurrent users पर प्रति सेकंड 130,000 lines निकलती हैं, लेकिन इनमें से अधिकतर अर्थहीन जानकारी होती है
  • समस्या आने पर सबसे ज़रूरी चीज़ context होती है, लेकिन मौजूदा logs में वही नहीं होता

string search की सीमाएँ

  • जब कोई user रिपोर्ट करता है कि “payment नहीं हो रहा”, तब email या user_id से logs खोजने पर भी कोई consistent structure न होने के कारण उपयोगी नतीजे मिलना मुश्किल होता है
    • एक ही user ID user-123, user_id=user-123, {"userId":"user-123"} जैसी दर्जनों अलग forms में रिकॉर्ड हो सकती है
  • services के बीच log format अलग-अलग होने से related events को trace करना असंभव हो जाता है
  • मूल समस्या यह है कि logs को write के लिए डिज़ाइन किया गया है, query के लिए optimize नहीं किया गया

मुख्य अवधारणाओं की परिभाषा

  • Structured Logging: strings की जगह key-value (JSON) format में रिकॉर्ड करने का तरीका
  • Cardinality: किसी field के unique values की संख्या; उदाहरण के लिए user_id बहुत high होता है
  • Dimensionality: किसी log event में fields की संख्या; जितनी अधिक होगी, analysis की संभावना उतनी अधिक होगी
  • Wide Event / Canonical Log Line: प्रति request एक context-rich single log event
  • अधिकांश logging systems high-cardinality data को cost कारणों से सीमित करते हैं, जबकि वास्तव में debugging के लिए वही सबसे उपयोगी होता है

OpenTelemetry की सीमाएँ

  • OpenTelemetry(OTel) एक protocol और SDKs का set है, जो सिर्फ data collection और transport का standard देता है
  • लेकिन OTel यह काम नहीं करता
    1. क्या log करना है, यह तय नहीं करता
    2. business context (जैसे subscription tier, cart amount आदि) अपने आप नहीं जोड़ता
    3. developer की logging mindset नहीं बदलता
  • एक ही library इस्तेमाल करने पर भी, जानबूझकर context जोड़कर की गई instrumentation और साधारण instrumentation के debugging experience में बहुत बड़ा फर्क होता है
  • OTel सिर्फ plumbing है; उसमें क्या बहाना है, यह developer को तय करना होता है

Wide Event / Canonical Log Line तरीका

  • पारंपरिक “code क्या कर रहा है” वाली logging से हटकर, “request के साथ क्या हुआ” यह रिकॉर्ड करना चाहिए
  • हर request के लिए service स्तर पर एक व्यापक event बनाया जाए
    • इसमें request, user, payment, error, environment आदि के 50 से अधिक fields शामिल हो सकते हैं
  • उदाहरण JSON में user_id, subscription_tier, service_version, error_code जैसे debugging के लिए ज़रूरी सभी context शामिल होते हैं
  • इससे एक ही search में “premium users की payment failure का कारण” जैसी चीज़ों का तुरंत analysis संभव हो जाता है

Wide Event की query में उपयोगिता

  • Wide Event को साधारण text search की तरह नहीं, बल्कि structured data query की तरह handle किया जाता है
  • high-cardinality और high-dimensional data के आधार पर real-time analysis स्तर की debugging संभव होती है
  • उदाहरण: “पिछले 1 घंटे में premium users की payment failure rate को error code के हिसाब से aggregate करो” जैसी query तुरंत चलाई जा सकती है

implementation pattern

  • पूरे request lifecycle के दौरान event तैयार किया जाए, और अंत में सिर्फ एक बार output किया जाए
    • middleware में request_id, timestamp, method, path जैसे base fields initialize करें
    • handler में user, cart, payment, error जानकारी को धीरे-धीरे जोड़ें
  • आखिर में logger.info(event) से एक single JSON event रिकॉर्ड करें

sampling से cost control

  • प्रति request 50 से अधिक fields रिकॉर्ड करने पर cost तेज़ी से बढ़ सकती है, इसलिए sampling ज़रूरी है
  • साधारण random sampling में errors छूट जाने का जोखिम रहता है
  • Tail Sampling strategy का सुझाव
    1. errors (जैसे 500) हमेशा store करें
    2. slow requests (p99 से ऊपर) हमेशा store करें
    3. VIP users या specific flag sessions हमेशा store करें
    4. बाकी में सिर्फ 1~5% को random sample करें
  • इससे cost reduction और critical events preservation दोनों साथ हासिल किए जा सकते हैं

आम गलतफहमियाँ

  • Structured Logging ≠ Wide Event: सिर्फ JSON format काफी नहीं है, context ही असली चीज़ है
  • OpenTelemetry का उपयोग ≠ complete observability: यह सिर्फ collection को standardize करता है, क्या रिकॉर्ड करना है यह developer पर निर्भर है
  • यह Tracing जैसा नहीं है: tracing services के बीच flow दिखाता है, जबकि Wide Event service के अंदर का context देता है
  • logs debugging के लिए, metrics dashboard के लिए जैसी विभाजन रेखा अनावश्यक है — Wide Event दोनों काम कर सकता है
  • high-cardinality data महँगा होता है वाली सोच पुरानी हो चुकी है; ClickHouse, BigQuery जैसे modern DBs इसे efficiently handle कर सकते हैं

Wide Event अपनाने का असर

  • debugging archaeology से analytics में बदल जाती है
  • “user payment failure” खोजने के लिए 50 services के logs पर grep चलाने के बजाय,
    “premium users की payment failure rate को error code के हिसाब से देखो” जैसे single-query based analysis पर शिफ्ट हो जाता है
  • नतीजतन logs झूठ बोलने वाले tool से, सच बताने वाले data asset में बदल जाते हैं

1 टिप्पणियां

 
GN⁺ 2025-12-22
Hacker News की राय
  • लेख पढ़ने में कठिन था और उसमें AI की मदद से लिखा गया सा एहसास था। फिर भी संदेश मूल्यवान था, बस यह थोड़ा और संक्षिप्त होता तो बेहतर रहता।
    हाल में मेरे मन में आए कुछ बिंदु ये हैं।

    • पूरे stack में authentication होने के कारण हमने हर log line में user id शामिल करना शुरू किया। इससे किसी उपयोगकर्ता के अनुभव को समग्र रूप से देखना आसान हो गया।
    • errors को request logs से अलग line में रिकॉर्ड करना झंझट भरा है। trace से filter किया जा सकता है, लेकिन “सिर्फ 5xx requests से जुड़े errors दिखाओ” जैसी query बनाना कठिन होता है।
    • सिर्फ ऐसा context जोड़ना काफ़ी नहीं है; साथियों को भी प्रशिक्षित करना पड़ता है कि नए fields जोड़े गए हैं। मैंने कई बार लोगों को यह जाने बिना खुद ही संघर्ष करते देखा है।
    • बेहतर tracing tools में निवेश करने से ऐसा debugging संभव होता है जो साधारण logs से संभव नहीं। इसे user id को trace के रूप में इस्तेमाल करने की अवधारणा का विस्तार मान सकते हैं।
    • अगर codebase में request ID की अवधारणा है, तो उससे भी उपयोगकर्ता की गतिविधि को और ठोस रूप से trace किया जा सकता है।
    • अगर पूरे service stack में TID अनिवार्य कर दिया जाए, तो कोई भी टीम सिर्फ एक TID से पूरे transaction को trace कर सकती है।
    • इस तरह की “AI जैसी गंध आती है” वाली टिप्पणियाँ जल्द ही आलोचना झेलने वाली संस्कृति बन सकती हैं।
  • इस विषय में Charity Majors का ज़िक्र किए बिना बात नहीं हो सकती। वह 10 साल से अधिक समय से “wide events” और “observability” की अवधारणाएँ फैलाती रही हैं, और Honeycomb.io को भी उसी दर्शन पर बनाया गया।
    आजकल कई तरह के tools से इस तरीके को लागू किया जा सकता है। structured logs या traces का उपयोग करके wide events capture करना, और time-series, histogram जैसी समृद्ध visualization वाले tools का उपयोग करना महत्वपूर्ण है।

    • हालाँकि “observability” शब्द खुद उन्होंने नहीं बनाया। यह कई क्षेत्रों में दशकों से इस्तेमाल होता आ रहा था। वह प्रभावशाली practitioner हैं, लेकिन इस शब्द की जनक नहीं हैं।
    • उनका blog और Honeycomb की पृष्ठभूमि की कहानी उद्योग में काम करने वालों के लिए ज़रूर पढ़ने लायक है। यह इस approach का मूल्य जल्दी पहचानने वाली शुरुआती teams में से एक थी।
    • लेख उनकी शैली से इतना मिलता-जुलता था कि अंत में Honeycomb का विज्ञापन आने की उम्मीद थी; ऐसा नहीं हुआ, यह देखकर आश्चर्य हुआ।
    • .NET ecosystem में Nick Blumhardt ने बहुत पहले से “structured logging” पर काम किया था, और SeqSerilog ने इसे support किया था।
    • उनका content अच्छा है, लेकिन “observability” को किसी एक व्यक्ति ने brand नहीं किया। सम्मान होना चाहिए, पर बढ़ा-चढ़ाकर दावे नहीं करने चाहिए।
  • मैं लेख के कुछ दावों से सहमत हूँ, लेकिन सिर्फ एक single wide event छोड़ने के तरीके में जोखिम है। अगर request के बीच में exception या timeout हो जाए, तो कुछ भी रिकॉर्ड नहीं बचेगा।
    भाषा के default logging framework या dependency logs भी छूट सकते हैं।
    इसलिए इसे मौजूदा logs के ऊपर चढ़ाई जाने वाली एक अतिरिक्त layer के रूप में इस्तेमाल करना बेहतर है। request/session स्तर का ID रखकर ClickHouse जैसी जगह में aggregation किया जा सकता है।

    • अगर बीच की layers की visibility समस्या है, तो इसका मतलब event काफ़ी wide नहीं हैlog.error(data) और wide_event.attach(error, data) मूल रूप से एक ही बात हैं।
    • “connection X:Y accepted at Z ns” और “closed at Z ns” जैसे logs धीमे systems को debug करने में बहुत उपयोगी हैं।
    • मैंने PHP framework में LoggerInterface बनाकर इसका समाधान किया। exceptions को global handler से पकड़कर DB में wide रूप में store किया। थोड़ा boilerplate है, लेकिन यह इतना अच्छा काम करता है कि अब इसके बिना असुविधा होती है।
  • presentation और interactive examples शानदार थे। लेकिन आखिरकार बात “logs में structured tags जोड़ो” तक सिमट जाती है।
    wide log में जटिलता और पठनीयता में गिरावट के मुकाबले फ़ायदा बहुत बड़ा नहीं लगा।
    जब साधारण grep "uid=user-123" application.log से काम चल जाता है, तो क्या सचमुच उपयोगकर्ता की delivery method जैसी चीज़ भी जोड़ने की ज़रूरत है?
    (वैसे Android Brave browser में checkbox काम नहीं कर रहे थे)

    • अगर logs JSON में हों, तो फिर भी grep '"uid": "user-123"' से खोजा जा सकता है। --context option से आसपास की lines भी देखी जा सकती हैं।
  • semiconductor manufacturing environment में मैंने ऐसा system संभाला है जिसमें हज़ारों message bus participants थे। प्रति घंटा 300~400MB logs निकलते थे, लेकिन सिर्फ grep और CLI tools से भी सब संभालना काफ़ी था
    logs बस events की time-series थे, और विस्तृत analysis Oracle queries से किया जाता था। logs का काम घटनाओं के कारण-परिणाम संबंध को समझने का साधन होना है।

    • logs timeline समझने के लिए होते हैं, request-response का सारा data भरने के लिए नहीं। बहुत ज़्यादा जानकारी डालने से उल्टा समझना कठिन हो जाता है।
      logs बताते हैं “कब, क्या हुआ”, जबकि “क्यों” का जवाब code, data और events के संयोजन से मिलता है।
      व्यक्तिगत रूप से मुझे ELK stack जैसे interfaces सहज exploration के लिए असुविधाजनक लगते हैं। logs को सहज रूप से आगे बढ़ते हुए पढ़ना महत्वपूर्ण है।
    • प्रति घंटा 400MB logs वास्तव में बहुत ज़्यादा नहीं हैं। इसलिए साधारण grep से भी यह पर्याप्त रूप से संभाला जा सकता है।
  • लेख के अंत में दिया गया “हर error, exception, और slow request को log करो” वाला सुझाव खतरनाक सोच है।
    उदाहरण के लिए, अगर कोई dependency धीमी हो जाए तो log volume 100 गुना तक बढ़ सकता है।
    outage के समय service को कम काम करना चाहिए ताकि recovery आसान हो, लेकिन logs का विस्फोट उल्टा श्रृंखलाबद्ध विफलता पैदा कर सकता है।

    • Cloudflare में adaptive sampling का उपयोग होता है। log batches को fields के आधार पर bucket किया जाता है, और हर bucket में input logs की संख्या का square root या log-value जितना ही रखा जाता है।
      log volume जितना बढ़ता है, sampling ratio अपने-आप समायोजित हो जाता है ताकि system overload न हो।
    • ऐसे magic thresholds जोखिम भरे होते हैं। P(99) जैसे मान dynamically update होने चाहिए। OTEL provider से समय-समय पर वास्तविक values ले ली जाएँ तो यह सुरक्षित रहता है।
    • production services को इस तरह design करना चाहिए कि log collection मांग के अनुसार scale हो सके। सिर्फ local disk buffering भी बहुत मदद कर सकती है।
    • high-traffic services में trace_id mod 100 == 0 जैसे तरीके से स्वस्थ requests का sampling किया जा सकता है।
    • अगर logs ही bottleneck बन जाएँ, तो system design में समस्या है। कुशल logging प्रति सेकंड सैकड़ों मिलियन events भी संभाल सकती है।
  • आधुनिक software में एक single log से “क्या हुआ” पूरी तरह समझाना मुश्किल है।
    इसलिए vertical correlation और horizontal correlation दोनों की ज़रूरत होती है।
    stack की ऊपर-नीचे वाली layers के बीच एक ही correlation value साझा होनी चाहिए, और systems के बीच communication में peers के बीच correlation चाहिए।
    API या protocol में ऐसी values जोड़ना कठिन है, लेकिन अगर transaction ID पहले से design कर लिया जाए तो end-to-end tracing संभव हो जाती है।

  • सिर्फ एक लेख के लिए अलग domain register करना मुझे टिकाऊ नहीं लगता।
    हर साल renewal fee देनी पड़ती है, इसलिए व्यक्तिगत blog या subdomain इस्तेमाल करना बेहतर लगता है।
    उदाहरण के लिए logging-sucks.boristane.com जैसा रूप अच्छा है।

    • दरअसल यह domain और लेख लेखक के observability SaaS के प्रचार के लिए हैं। Cloudflare account चाहिए, लेकिन वह मुफ़्त है, इसलिए यह दीर्घकालिक marketing strategy जैसा लगता है। फिर भी यह उपयोगी था, और मेरे पास भी CF account है इसलिए मैं इसे आज़माने का सोच रहा हूँ।
    • यह लेख Simon Willison के “Give people something to link to” के समान संदर्भ में है।
    • यह blog post से ज़्यादा digital marketing lead-generation page जैसा लगता है। सेवा का प्रचार काफ़ी स्पष्ट है।
  • “logs monolithic युग की विरासत हैं” वाले दावे पर मेरा मानना है कि local logs अब भी उपयोगी हैं
    उनका मूल काम local process की बातचीत को रिकॉर्ड करना है, और दूसरे servers की स्थिति समझने के लिए transaction tracing चाहिए।
    सही जगह के logs भर देखने से भी root cause तक पहुँचा जा सकता है।

    • हालाँकि logs सिर्फ root-cause analysis के लिए नहीं होते; वे कौन प्रभावित हुआ, performance और input के बीच संबंध, security vulnerability के प्रभाव जैसी business insights भी दे सकते हैं।
      समृद्ध context वाले logs analysis engine के साथ मिलकर product improvement में भी काम आ सकते हैं।
    • “एक request 15 services और 3 DBs से होकर गुजरती है” इस बात पर यह प्रतिक्रिया भी थी कि ऐसी जटिलता से बचना चाहिए।
    • मुझे APN/Kibana से भी log analysis के लिए पर्याप्त मदद मिलती है।
  • “code क्या कर रहा है” की बजाय “request के साथ क्या हुआ” इसे log करो — इस बात से मैं सहमत हूँ, लेकिन लेखक थोड़ा अनुभवहीन लगा।
    मैं इसे “bug parts logging” कहता हूँ, और मेरा मानना है कि इसमें processing path, count, time जैसी पूर्व-संकेत वाली बातें शामिल होनी चाहिए।
    logging, metrics या audit से अलग है। logging fail हो जाए तो processing जारी रहनी चाहिए, लेकिन audit fail होना गंभीर है।
    SCADA systems के “historian” concept की तरह, observables और evaluatives में अंतर करना चाहिए।
    उदाहरण के लिए fuel sensor के सूक्ष्म events diagnosis के लिए उपयोगी हो सकते हैं, लेकिन “क्या गंतव्य तक पहुँचा जा सकता है?” जैसे प्रश्न के लिए वे अनावश्यक हैं।
    आखिरकार महत्वपूर्ण बात यह स्पष्ट करना है कि क्या observe करना है, और क्या evaluate करना है

    • मैं “observability की unified theory” का समर्थक हूँ। logs, metrics, और audit — ये सब अंततः bit streams ही हैं, और बिना loss के एक-दूसरे में बदले जा सकते हैं।
      भले ही storage, transformation, और querying के तरीके अलग हों, consumption points और mechanisms को एक जैसा design किया जा सकता है।
      इससे system design सरल हो जाता है, और लंबे समय तक रखे गए logs को बाद में फिर से process भी किया जा सकता है।