डेटा इकट्ठा करने की सुविधा को समझना

इस लेख में लॉगिंग की प्रोसेस के बारे में बताया गया है. इसमें लॉग के स्टैंडर्ड, लेवल के दिशा-निर्देश, क्लास, मकसद, और मल्टीस्टैक अनुमान शामिल हैं.

लॉग के स्टैंडर्ड

Android में लॉग इन करना मुश्किल है, क्योंकि इसमें इस्तेमाल किए गए स्टैंडर्ड को logcat में मिला दिया जाता है. इस्तेमाल किए गए मुख्य मानकों के बारे में यहां बताया गया है:

Source उदाहरण स्टैक लेवल के लिए दिशा-निर्देश
RFC 5424 (syslog स्टैंडर्ड) Linux कर्नेल, कई Unix ऐप्लिकेशन कर्नेल, सिस्टम डेमॉन
android.util.Log Android फ़्रेमवर्क + ऐप्लिकेशन लॉगिंग Android फ़्रेमवर्क और सिस्टम ऐप्लिकेशन
java.util.logging.Level Java में लॉग इन करने की सामान्य जानकारी सिस्टम ऐप्लिकेशन नहीं है

पहली इमेज: लॉग लेवल के स्टैंडर्ड.

हालांकि, इन सभी स्टैंडर्ड में एक ही तरह का लेवल कंस्ट्रक्शन होता है, लेकिन ये ग्रेन्यूलैरिटी के हिसाब से अलग-अलग होते हैं. अलग-अलग स्टैंडर्ड के हिसाब से, अनुमानित तौर पर ये स्कोर मिलते हैं:

RFC 5424 लेवल RFC 5424 के हिसाब से गंभीरता RFC 5424 का ब्यौरा android.util.Log java.util.logging.Level
0 आपातकालीन कॉल सिस्टम का इस्तेमाल नहीं किया जा सकता Log.e / Log.wtf SEVERE
1 सूचना तुरंत कार्रवाई करना ज़रूरी है Log.e / Log.wtf SEVERE
2 सबसे अहम गंभीर स्थितियां Log.e / Log.wtf SEVERE
3 कोई गड़बड़ी हुई गड़बड़ी की स्थितियां Log.e SEVERE
4 चेतावनी चेतावनी की शर्तें Log.w WARNING
5 सूचना सामान्य, लेकिन अहम Log.w WARNING
6 जानकारी जानकारी देने वाले मैसेज Log.i INFO
7 डीबग डीबग-लेवल के मैसेज Log.d CONFIG, FINE
- - ज़्यादा जानकारी वाले मैसेज Log.v FINER / FINEST

दूसरी इमेज: syslog, Android, और Java के लॉगिंग लेवल.

लॉग लेवल से जुड़े दिशा-निर्देश

हर लॉग स्टैंडर्ड के लिए, मौजूदा दिशा-निर्देश दिए गए हैं. चुना गया लॉग लेवल, इस्तेमाल किए जा रहे सही स्टैंडर्ड के मुताबिक होना चाहिए. जैसे, कर्नल डेवलपमेंट के लिए syslog स्टैंडर्ड का इस्तेमाल करना.

नीचे दी गई तीन इमेज में, लॉग लेवल के ऑर्डर दिखाए गए हैं. इनमें सबसे कम से लेकर सबसे ज़्यादा तक के ऑर्डर शामिल हैं:

ERROR इन लॉग को हमेशा सेव किया जाता है.
WARN इन लॉग को हमेशा सेव किया जाता है.
INFO इन लॉग को हमेशा सेव किया जाता है.
DEBUG इन लॉग को कंपाइल किया जाता है, लेकिन रनटाइम के दौरान हटा दिया जाता है.
VERBOSE इन लॉग को ऐप्लिकेशन में कभी कंपाइल नहीं किया जाता. हालांकि, इन्हें ऐप्लिकेशन बनाने के दौरान कंपाइल किया जा सकता है.

तीसरी इमेज: android.util.Log

CONFIG स्टैटिक कॉन्फ़िगरेशन मैसेज के लिए मैसेज लेवल
FINE ट्रेसिंग की जानकारी देने वाला मैसेज लेवल
FINER इससे पता चलता है कि ट्रेसिंग मैसेज में काफ़ी जानकारी दी गई है
FINEST यह ज़्यादा जानकारी वाला ट्रेसिंग मैसेज दिखाता है
INFO जानकारी देने वाले मैसेज के लिए मैसेज लेवल
SEVERE मैसेज लेवल, जो गंभीर गड़बड़ी के बारे में बताता है
WARNING मैसेज लेवल पर संभावित समस्या की जानकारी देने वाला मैसेज

चौथी इमेज: java.util.Logging.Level.

0 आपातकालीन कॉल सिस्टम का इस्तेमाल नहीं किया जा सकता
1 सूचना तुरंत कार्रवाई करना ज़रूरी है
2 सबसे अहम गंभीर स्थितियां
3 कोई गड़बड़ी हुई गड़बड़ी की स्थितियां
4 चेतावनी चेतावनी की शर्तें
5 सूचना सामान्य, लेकिन गंभीर स्थिति
6 सूचनात्मक जानकारी देने वाले मैसेज
7 डीबग डीबग-लेवल के मैसेज

पांचवी इमेज: RFC 5424 - सेक्शन 6.2.1.

ऐप्लिकेशन लॉगिंग

TAG की मदद से चुनिंदा लॉगिंग की जाती है. इसके लिए, android.util.Log क्लास Log#isLoggable का इस्तेमाल करती है. इसके बारे में यहां बताया गया है:

if (Log.isLoggable("FOO_TAG", Log.VERBOSE)) {
 Log.v("FOO_TAG", "Message for logging.");
}

नीचे दिए गए उदाहरण में दिखाया गया है कि रनटाइम के दौरान, लॉग को इस तरह से ट्यून किया जा सकता है कि सिर्फ़ चुनिंदा लेवल की लॉगिंग की जा सके:

adb shell setprop log.tag.FOO_TAG VERBOSE

रीबूट करने पर, log.tag.* प्रॉपर्टी रीसेट हो जाती हैं. ऐसे वैरिएंट भी होते हैं जो रीबूट करने के बाद भी बने रहते हैं. यहां देखें:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Log#isLoggable, ऐप्लिकेशन कोड में लॉग ट्रेस की जांच करता है. बूलियन DEBUG फ़्लैग, कंपाइलर ऑप्टिमाइज़ेशन का इस्तेमाल करके लॉग ट्रेस को बायपास करते हैं. इन्हें false पर सेट किया जाता है. जैसा कि यहां दिखाया गया है:

private final static boolean DEBUG = false;

… If (DEBUG) { Log.v("FOO_TAG", "Extra debug logging."); }

ProGuard के नियमों के सेट का इस्तेमाल करके, R8 कंपाइल करने के समय, हर APK के हिसाब से लॉगिंग को हटाया जा सकता है. यहां दिए गए उदाहरण में, android.util.Log के लिए INFO लेवल से नीचे की सभी लॉगिंग को हटाया गया है:

# This allows proguard to strip isLoggable() blocks containing only <=INFO log
# code from release builds.
-assumenosideeffects class android.util.Log {
  static *** i(...);
  static *** d(...);
  static *** v(...);
  static *** isLoggable(...);
}
-maximumremovedandroidloglevel 4

यह कई तरह के ऐप्लिकेशन बिल्ड टाइप (उदाहरण के लिए, डेवलपमेंट बिल्ड बनाम रिलीज़ बिल्ड) को मैनेज करने के लिए काम का है. इनमें बुनियादी कोड एक जैसा होता है, लेकिन लॉग लेवल अलग-अलग होते हैं. ऐप्लिकेशन (खास तौर पर सिस्टम ऐप्लिकेशन) के लिए, एक साफ़ तौर पर बताई गई नीति सेट की जानी चाहिए और उसका पालन किया जाना चाहिए. इससे यह तय किया जा सकेगा कि बिल्ड टाइप और रिलीज़ की उम्मीदें, लॉग आउटपुट पर कैसे असर डालती हैं.

Android Runtime (ART) में सिस्टम लॉगिंग

सिस्टम ऐप्लिकेशन और सेवाओं के लिए, कई क्लास उपलब्ध हैं:

क्लास मकसद
android.telephony.Rlog रेडियो लॉगिंग
android.util.Log ऐप्लिकेशन की सामान्य लॉगिंग
android.util.EventLog सिस्टम इंटिग्रेटर के डाइग्नोस्टिक इवेंट की लॉगिंग
android.util.Slog प्लैटफ़ॉर्म फ़्रेमवर्क लॉगिंग

छठी इमेज: सिस्टम लॉग की उपलब्ध क्लास और उनके मकसद.

android.util.Log और android.util.Slog, दोनों एक ही लॉग लेवल के स्टैंडर्ड का इस्तेमाल करते हैं. हालांकि, Slog एक @hide क्लास है, जिसका इस्तेमाल सिर्फ़ प्लैटफ़ॉर्म कर सकता है. EventLog लेवल, /system/etc/event-log-tags में मौजूद event.logtags फ़ाइल की एंट्री के साथ मैप किए जाते हैं.

नेटिव लॉगिंग

C/C++ में लॉग इन करने के लिए, syslog स्टैंडर्ड का पालन किया जाता है. इसमें syslog(2) Linux कर्नल syslog से मेल खाता है, जो printk बफ़र को कंट्रोल करता है. साथ ही, syslog(3) सामान्य सिस्टम लॉगर से मेल खाता है. Android, सामान्य सिस्टम लॉगिंग के लिए liblog लाइब्रेरी का इस्तेमाल करता है.

liblog, सबलॉग ग्रुप के लिए रैपर उपलब्ध कराता है. इसके लिए, इस मैक्रो फ़ॉर्म का इस्तेमाल किया जाता है:

[Sublog Buffer ID] LOG [Log Level ID]

उदाहरण के लिए, RLOGD, [Radio log buffer ID] LOG [Debug Level] से मेल खाता है. मुख्य liblog रैपर ये हैं:

रैपर क्लास फ़ंक्शन के उदाहरण
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

सातवीं इमेज: liblog रैपर.

Android में लॉगिंग के लिए, बेहतर लेवल के इंटरफ़ेस उपलब्ध हैं. इन्हें सीधे तौर पर liblog इस्तेमाल करने के बजाय प्राथमिकता दी जाती है. इनके बारे में यहां बताया गया है:

लाइब्रेरी इस्तेमाल
async_safe यह लाइब्रेरी सिर्फ़ ऐसे एनवायरमेंट से लॉग करने के लिए है जहां एसिंक्रोनस सिग्नल सुरक्षित हों
libbase यह एक लॉगिंग लाइब्रेरी है. यह लॉगिंग के लिए C++ स्ट्रीम इंटरफ़ेस उपलब्ध कराती है. यह Google-स्टाइल (glog) लॉगिंग की तरह ही काम करती है. libbase का इस्तेमाल बाहरी प्रोजेक्ट में किया जा सकता है. साथ ही, यह libbase_ndk का इस्तेमाल करने वाले ऐप्लिकेशन में उपलब्ध है.

आंकड़ा 8: ज़्यादा लेवल की लॉग लाइब्रेरी.

मल्टीस्टैक एप्रोक्सिमेशन

ग्रैन्युलैरिटी और लेवल इंटेंट में अंतर होने की वजह से, लॉगिंग के अलग-अलग स्टैंडर्ड के बीच कोई सटीक या पूरा मैच नहीं होता. उदाहरण के लिए, गड़बड़ी के लॉग के लिए java.util.logging.Level और android.util.Log लेवल, एक-दूसरे से पूरी तरह मेल नहीं खाते:

java.util.Logging.Level android.util.Log
SEVERE Log.wtf
SEVERE Log.e

नौवीं इमेज: स्टैंडर्ड Java लॉगिंग और Android लॉगिंग में गड़बड़ी का लेवल.

ऐसे मामलों में, यह तय करने के लिए कि कौनसे लेवल को लागू करना है, अलग-अलग स्टैंडर्ड का इस्तेमाल करें.

एक से ज़्यादा स्टैक लेवल कॉम्पोनेंट के साथ सिस्टम डेवलप करते समय, यह तय करने के लिए कि हर कॉम्पोनेंट के लिए किस स्टैंडर्ड का इस्तेमाल किया जाए, पहले फ़िगर में दिया गया तरीका अपनाएं. टियर के हिसाब से मैसेज भेजने के बारे में जानने के लिए, इमेज 2 देखें.

सुरक्षा और निजता

व्यक्तिगत पहचान से जुड़ी जानकारी (पीआईआई) को लॉग न करें. इसमें यह जानकारी शामिल है:

  • ईमेल पते
  • टेलीफ़ोन नंबर
  • नाम

इसी तरह, कुछ जानकारी को संवेदनशील माना जाता है. भले ही, वह साफ़ तौर पर व्यक्तिगत पहचान ज़ाहिर न करती हो.

उदाहरण के लिए, टाइमज़ोन की जानकारी को व्यक्तिगत पहचान से जुड़ी जानकारी नहीं माना जाता. हालांकि, इससे किसी व्यक्ति की जगह का अनुमान लगाया जा सकता है.

रिलीज़ करने से पहले, सुरक्षा और निजता की समीक्षा के दौरान, लॉग की नीति और स्वीकार्य जानकारी को मैनेज किया जाना चाहिए.

डिवाइस लॉग से

सभी डिवाइस लॉग का ऐक्सेस प्रतिबंधित है. इसमें android.permission.READ_LOGS का इस्तेमाल करना भी शामिल है:

  • अगर बैकग्राउंड में चल रहा कोई ऐप्लिकेशन, सभी डिवाइस लॉग का ऐक्सेस मांगता है, तो अनुरोध अपने-आप अस्वीकार हो जाता है. ऐसा तब तक होता है, जब तक ऐप्लिकेशन:
    • यह सिस्टम यूआईडी शेयर करता है.
    • नेटिव सिस्टम प्रोसेस (UID < APP_UID) का इस्तेमाल करता है.
    • DropBoxManager का इस्तेमाल करता है.
    • सिर्फ़ इवेंट लॉग बफ़र को ऐक्सेस करता है.
    • यह EventLog API का इस्तेमाल करता है.
    • इंस्ट्रुमेंटेड टेस्ट का इस्तेमाल करता हो.
  • अगर फ़ोरग्राउंड में मौजूद कोई ऐप्लिकेशन, डिवाइस के लॉग का ऐक्सेस मांगता है, तो सिस्टम उपयोगकर्ता को ऐक्सेस का अनुरोध स्वीकार या अस्वीकार करने के लिए कहता है.READ_LOGS