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

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

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

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

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

पहली इमेज: लॉग लेवल के मानक.

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

आरएफ़सी 5424 लेवल आरएफ़सी 5424 के हिसाब से गंभीरता आरएफ़सी 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.

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

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

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."); }

R8 के ज़रिए, ProGuard के नियमों के ज़रिए हर 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 kernel 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 का इस्तेमाल करने वाले ऐप्लिकेशन में भी उपलब्ध है.

आठवां चित्र: लॉग की उच्च लेवल की लाइब्रेरी.

मल्टीस्टैक के अनुमान

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

java.util.Logging.Level android.util.Log
गंभीर Log.wtf
गंभीर Log.e

चित्र 9: स्टैंडर्ड Java लॉगिंग बनाम Android लॉगिंग में गड़बड़ी का लेवल.

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

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

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

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

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

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

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

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

डिवाइस लॉग से

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

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