লগ করা সম্পর্কে বুঝুন

এই নিবন্ধে লগ করার প্রসেস সম্পর্কে বলা হয়েছে, যার মধ্যে লগ স্ট্যান্ডার্ড, লেভেল নির্দেশিকা, ক্লাস, উদ্দেশ্য এবং মাল্টিস্ট্যাক অ্যাপ্রক্সিমেশন অন্তর্ভুক্ত।

লগ স্ট্যান্ডার্ড

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 - বিভাগ ৬.২.১.

অ্যাপ লগিং

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 কার্নেল 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 লেভেল ১:১ ম্যাচ করে না:

java.util.Logging.Level android.util.Log
গুরুতর Log.wtf
গুরুতর Log.e

ছবি ৯: স্ট্যান্ডার্ড Java লগিং বনাম Android লগিংয়ে সমস্যার লেভেল।

এই ধরনের ক্ষেত্রে, কোন লেভেল প্রয়োগ করতে হবে তা নির্ধারণ করতে ব্যক্তিগত স্ট্যান্ডার্ড ব্যবহার করুন।

একাধিক স্ট্যাক লেভেল কম্পোনেন্ট সহ সিস্টেম ডেভেলপমেন্টের সময়, কোন কম্পোনেন্টের জন্য কোন স্ট্যান্ডার্ড ব্যবহার করতে হবে তা নির্ধারণ করতে ছবি ১ অনুসরণ করুন। টিয়ার মেসেজিংয়ের আনুমানিক নির্দেশিকার জন্য, ছবি ২ দেখুন।

নিরাপত্তা ও গোপনীয়তা

ব্যক্তিগতভাবে শনাক্তকরণযোগ্য তথ্য (PII) লগ করবেন না। এর মধ্যে এই ধরনের বিবরণ অন্তর্ভুক্ত:

  • ইমেল আইডি
  • ফোন নম্বর
  • নাম

একইভাবে, কিছু বিবরণ সংবেদনশীল বলে বিবেচিত হয়, এমনকি যদি তা স্পষ্টভাবে ব্যক্তিগতভাবে শনাক্তকরণযোগ্য নাও হয়।

যেমন, টাইমজোন সংক্রান্ত তথ্য ব্যক্তিগতভাবে শনাক্তকরণযোগ্য হিসেবে বিবেচিত না হলেও, এটি ব্যবহারকারীর আনুমানিক লোকেশন সম্পর্কে ইঙ্গিত দেয়।

রিলিজ করার আগে নিরাপত্তা ও গোপনীয়তা পর্যালোচনার অংশ হিসেবে লগ নীতি ও গ্রহণযোগ্য বিবরণ ম্যানেজ করতে হবে।

ডিভাইস লগ

android.permission.READ_LOGS ব্যবহার করা সহ সব ডিভাইস লগে অ্যাক্সেস সীমাবদ্ধ করা হয়েছে:

  • ব্যাকগ্রাউন্ডে থাকা কোনও অ্যাপ সব ডিভাইস লগে অ্যাক্সেসের জন্য অনুরোধ করলে, সেই অনুরোধ অটোমেটিক বাতিল করা হয়, যদি না অ্যাপটি:
    • সিস্টেম UID শেয়ার করে।
    • নেটিভ সিস্টেম প্রসেস (UID < APP_UID) ব্যবহার করে।
    • DropBoxManager ব্যবহার করে।
    • শুধুমাত্র ইভেন্ট লগ বাফার অ্যাক্সেস করে।
    • EventLog API ব্যবহার করে।
    • ইনস্ট্রুমেন্টেড টেস্ট ব্যবহার করে।
  • READ_LOGS সহ কোনও অ্যাপ ফোরগ্রাউন্ডে ডিভাইস লগে অ্যাক্সেসের অনুরোধ করলে, সিস্টেম ব্যবহারকারীকে অ্যাক্সেসের অনুরোধ অনুমোদন বা বাতিল করার জন্য প্রম্পট করে।