Log Level — ταξινόμηση των μηνυμάτων καταγραφής κατά βαθμό κρισιμότητας, επιτρέποντας στους προγραμματιστές να ελέγχουν τον όγκο των πληροφοριών εξόδου σε διαφορετικά στάδια λειτουργίας της εφαρμογής. Σύμφωνα με δεδομένα των Google Android Developers, 2024, η σωστή επιλογή επιπέδου καταγραφής μειώνει τον όγκο των αρχείων καταγραφής στην παραγωγή κατά 85–95% και επιταχύνει τη διάγνωση σφαλμάτων. Κάθε επίπεδο λύνει τη δική του εργασία — από τον εντοπισμό σφαλμάτων στο στάδιο ανάπτυξης έως την παρακολούθηση κρίσιμων βλαβών στην παραγωγή.
Κύρια σημεία
Log Level — είναι ένα χαρακτηριστικό κάθε μηνύματος καταγραφής που καθορίζει τη σημασία και τον επείγοντα χαρακτήρα επεξεργασίας του. Οι σύγχρονες πλατφόρμες iOS και Android υποστηρίζουν μια ενοποιημένη κλίμακα 6–7 επιπέδων: από το μέγιστα λεπτομερές (Verbose/Trace) έως το κρίσιμο (Error/Assert). Η επιλογή επιπέδου καθορίζει εάν το μήνυμα θα καταγραφεί στο αρχείο καταγραφής με την τρέχουσα διαμόρφωση της εφαρμογής.
Η έννοια του Log Level βασίζεται στην αρχή της πυραμίδας κρισιμότητας: όσο υψηλότερο είναι το επίπεδο, τόσο λιγότερα μηνύματα εμφανίζονται σε αυτό. Σύμφωνα με δεδομένα της Semaphore CI, 2024, σε μια εφαρμογή παραγωγής η κατανομή έχει ως εξής: Info — 60% μηνύματα, Warn — 25%, Error — 10%, Debug — 5%. Τα μηνύματα Verbose πρέπει να είναι πλήρως απενεργοποιημένα στην παραγωγή.
Κάθε πλατφόρμα υλοποιεί το Log Level μέσω του δικού της API. Το Android χρησιμοποιεί το android.util.Log με μεθόδους v(), d(), i(), w(), e(). Η Apple — το OSLog με επίπεδα default, info, debug, error, fault. Βιβλιοθήκες όπως το Timber και το CocoaLumberjack προσθέτουν επιπλέον λειτουργικότητα πάνω από αυτά τα τυπικά API.
Σύμφωνα με δεδομένα του Google I/O 2023, η λανθασμένη επιλογή Log Level είναι η αιτία του 40% των προβλημάτων απόδοσης στην παραγωγή. Οι προγραμματιστές αφήνουν τα Debug αρχεία καταγραφής στην έκδοση release, οδηγώντας σε υπερβολική εγγραφή στον δίσκο και επιταχυνόμενη αποφόρτιση της μπαταρίας.
Verbose (TRACE) — το πιο λεπτομερές επίπεδο, που προορίζεται αποκλειστικά για ανάπτυξη. Σε αυτό το επίπεδο εμφανίζονται όλοι οι ενδιάμεσοι υπολογισμοί, οι επαναλήψεις βρόχων, τα αποτελέσματα κάθε βήματος του αλγορίθμου. Στο Android αυτό το επίπεδο αντιστοιχεί στο Log.v(), στο iOS — OSLog με τύπο debug (πριν από το iOS 14 χρησιμοποιούνταν το os_trace).
Debug — μηνύματα εντοπισμού σφαλμάτων, χρήσιμα κατά την ανάπτυξη και δοκιμή. Περιέχουν πληροφορίες σχετικά με την κατάσταση βασικών αντικειμένων, αποτελέσματα SQL ερωτημάτων, παραμέτρους κλήσεων API. Σε αντίθεση με το Verbose, τα Debug μηνύματα είναι δομημένα και σημασιολογικά σημαντικά. Στο iOS αυτό το επίπεδο αντιστοιχεί στο OSLogType.debug.
Info — ενημερωτικά μηνύματα σχετικά με κανονικά γεγονότα της εφαρμογής: αρχικοποίηση SDK, επιτυχής εξουσιοδότηση, άνοιγμα οθόνης, λήψη δεδομένων από τον διακομιστή. Τα Info μηνύματα δεν πρέπει να περιέχουν προσωπικά δεδομένα χρηστών και πρέπει να είναι ασφαλή για ανάλυση στην παραγωγή. Στο iOS χρησιμοποιείται το OSLogType.info, στο Android — το Log.i().
Warn — προειδοποιήσεις για πιθανά προβλήματα. Η εφαρμογή συνεχίζει να λειτουργεί, αλλά η κατάσταση απαιτεί προσοχή: μέγεθος προσωρινής μνήμης κοντά στο όριο, παλιά έκδοση API, αργή απόκριση δικτύου, εκ νέου προσπάθεια σύνδεσης. Στο Android — Log.w(), στο iOS — OSLogType.default (για προειδοποιήσεις).
Error — κρίσιμα σφάλματα όπου η εφαρμογή δεν μπορεί να εκτελέσει την αιτούμενη λειτουργία, αλλά συνεχίζει να λειτουργεί: αποτυχημένο αίτημα προς API, απώλεια σύνδεσης, σφάλμα εγγραφής στη βάση δεδομένων, έλλειψη δικαιωμάτων. Στο iOS για σφάλματα χρησιμοποιείται το OSLogType.error, στο Android — το Log.e().
Assert (WTF) — το υψηλότερο επίπεδο, που υποδηλώνει μια κατάσταση “αυτό δεν μπορεί να συμβεί”. Χρησιμοποιείται για την καταγραφή σφαλμάτων που παραβιάζουν θεμελιώδεις αμετάβλητες ιδιότητες του συστήματος. Στο Android τα μηνύματα Assert δεν εμφανίζονται στις εκδόσεις release από προεπιλογή. Στο iOS το WTF (What a Terrible Failure) υποβάλλεται σε επεξεργασία μέσω του OSLogType.fault.
Android Log API — ο ενσωματωμένος μηχανισμός καταγραφής από το πακέτο android.util.Log. Παρέχει 6 στατικές μεθόδους: Log.v(), Log.d(), Log.i(), Log.w(), Log.e() και Log.wtf(). Κάθε μέθοδος δέχεται ένα tag (συμβολοσειρά αναγνώρισης πηγής) και msg (κείμενο μηνύματος).
class UserRepository {
companion object {
private val TAG = "UserRepo"
}
suspend fun loadUser(id: String): User {
Log.d(TAG, "Φόρτωση χρήστη με id: $id")
return try {
val response = api.fetchUser(id)
Log.i(TAG, "Ο χρήστης φορτώθηκε επιτυχώς")
response.toUser()
} catch (e: Exception) {
Log.e(TAG, "Αποτυχία φόρτωσης χρήστη: ${e.message}")
throw e
}
}
}
Φιλτράρισμα ανά επίπεδο στο Android Logcat πραγματοποιείται μέσω ADB: adb logcat *:E θα εμφανίσει μόνο μηνύματα Error. Στις εκδόσεις παραγωγής, όλες οι κλήσεις Log.v() και Log.d() αφαιρούνται από το ProGuard/R8 όταν είναι ενεργοποιημένη η σμίκρυνση. Οι Log.i(), Log.w() και Log.e() παραμένουν, επομένως είναι σημαντικό να μην εξάγονται ευαίσθητα δεδομένα μέσω αυτών των μεθόδων.
Για προσαρμοσμένο φιλτράρισμα κατά τον χρόνο εκτέλεσης, το Android παρέχει τη Log.isLoggable(tag, level) — μια μέθοδο που ελέγχει εάν το καθορισμένο επίπεδο είναι ενεργοποιημένο για ένα συγκεκριμένο tag. Αυτό επιτρέπει τη δυναμική ενεργοποίηση λεπτομερούς καταγραφής για μια συγκεκριμένη μονάδα χωρίς εκ νέου δημιουργία της εφαρμογής.
OSLog — το ενοποιημένο σύστημα καταγραφής της Apple, το οποίο αντικατέστησε το ξεπερασμένο NSLog. Το OSLog παρέχει 5 επίπεδα: debug, info, default (notice), error και fault. Το κύριο πλεονέκτημα είναι η δομημένη καταγραφή με υποστήριξη για μορφοποιημένες συμβολοσειρές και δυναμικό φιλτράρισμα μέσω κονσόλας.
import OSLog
let logger = Logger(
subsystem: "com.example.app",
category: "network"
)
func fetchData(from url: URL) {
logger.debug("Starting request to \(url.absoluteString)")
do {
let data = try Data(contentsOf: url)
logger.info("Received \(data.count) bytes")
} catch {
logger.error("Request failed: \(error.localizedDescription)")
}
}
Σύστημα φιλτραρίσματος του OSLog λειτουργεί σε επίπεδο λειτουργικού συστήματος. Τα Debug μηνύματα καταγράφονται μόνο όταν είναι συνδεδεμένος ο εντοπιστής σφαλμάτων ή όταν είναι ενεργοποιημένο το όρισμα -com.apple.CoreData.Logging.debug 1. Τα Info μηνύματα συλλέγονται στη μνήμη της συσκευής (έως 512 KB) και είναι προσβάσιμα μέσω του Console.app. Τα Error και fault καταγράφονται συνεχώς και είναι διαθέσιμα για συλλογή μέσω συστημάτων αναφοράς σφαλμάτων.
Ένα σημαντικό χαρακτηριστικό του OSLog: μορφοποιημένες συμβολοσειρές με placeholders. Αντί της παρεμβολής συμβολοσειρών Swift (που υπολογίζεται πάντα, ανεξάρτητα από το επίπεδο), το OSLog χρησιμοποιεί μορφή os_log με %{public}@ και %{private}@ για τη διάκριση ευαίσθητων δεδομένων. Οι ιδιωτικές παράμετροι καλύπτονται με μάσκα στα αρχεία καταγραφής παραγωγής.
Βασικός κανόνας — ελάχιστο σύνολο επιπέδων στην παραγωγή: Info, Warn, Error, Assert. Τα Debug και Verbose πρέπει να είναι απενεργοποιημένα. Ο λόγος δεν είναι τόσο η ασφάλεια όσο η απόδοση: κάθε κλήση καταγραφής καταναλώνει χρόνο CPU για τη μορφοποίηση της συμβολοσειράς, ακόμα κι αν το μήνυμα δεν εμφανίζεται.
Κρίσιμη βελτιστοποίηση — μην χρησιμοποιείτε ποτέ παρεμβολή συμβολοσειρών σε κλήσεις καταγραφής. Εάν η συμβολοσειρά σχηματίζεται πριν από την κλήση log(), ο χρόνος CPU σπαταλιέται ακόμα κι όταν το επίπεδο είναι απενεργοποιημένο. Χρησιμοποιήστε τεμπέλικη μορφοποίηση μέσω λάμδα ή συνθηκών φύλαξης.
Στο Android, η μέθοδος Log.isLoggable() εξυπηρετεί αυτόν τον σκοπό, στο OSLog — η εγγενής υποστήριξη για μορφοποιημένες συμβολοσειρές με placeholders. Το Timber για Android λύνει το πρόβλημα μέσω του timber.log.Tree με έλεγχο επιπέδου εντός του δέντρου.
Remote Log Level — πρακτική όπου το επίπεδο καταγραφής ελέγχεται από τον διακομιστή μέσω του Firebase Remote Config ή παρόμοιας υπηρεσίας. Εάν εμφανιστεί ένα σύνθετο σφάλμα στην παραγωγή, ο προγραμματιστής μπορεί να ενεργοποιήσει εξ αποστάσεως την καταγραφή Debug για μια συγκεκριμένη μονάδα σε συσκευές μιας επιλεγμένης ομάδας χρηστών.
Σύμφωνα με δεδομένα της Firebase, 2024, αυτή η πρακτική μειώνει τον χρόνο διάγνωσης σπάνιων σφαλμάτων κατά 60% και επιτρέπει την απόκτηση μιας πλήρους εικόνας του προβλήματος χωρίς εγκατάσταση έκδοσης debug. Ο κύριος περιορισμός — τα αρχεία καταγραφής ενεργοποιούνται μόνο κατά την επόμενη εκκίνηση της εφαρμογής μετά τη λήψη της διαμόρφωσης.
BuildConfig.DEBUG στο Android και #if DEBUG στη Swift — τυπικοί μηχανισμοί υπό όρους μεταγλώττισης που απενεργοποιούν τα επίπεδα εντοπισμού σφαλμάτων στις εκδόσεις release. Για καθαρή αρχιτεκτονική, συνιστάται η μεταφορά της επιλογής Log Level σε ένα δοχείο DI ή εργοστάσιο καταγραφέων, ώστε να μην επιβαρύνεται η επιχειρηματική λογική με οδηγίες υπό όρους.
Πρώτος κανόνας — κάθε κλήση καταγραφής πρέπει να απαντά στην ερώτηση “ποιος, τι, πότε”. Ποιος — στοιχείο ή μονάδα (tag στο Android, category στο iOS). Τι — συγκεκριμένο γεγονός ή αλλαγή κατάστασης. Πότε — χρονική σήμανση, που ορίζεται αυτόματα από το σύστημα καταγραφής.
Δεύτερος κανόνας — μην καταγράφετε ευαίσθητα δεδομένα μέσω Info και άνω. Κωδικοί πρόσβασης, διακριτικά, email, αριθμοί τηλεφώνου, ακριβείς γεωγραφικές συντεταγμένες — απαγορεύονται αυστηρά σε οποιοδήποτε αρχείο καταγραφής που καταλήγει στην παραγωγή. Εάν είναι απαραίτητο, χρησιμοποιήστε συγκάλυψη: “email: us***@example.com”.
Τρίτος κανόνας — το επίπεδο Warn είναι ζώνη ευθύνης του προγραμματιστή, το Error — της ομάδας. Warn σημαίνει “εδώ υπάρχει πιθανό πρόβλημα, παρακολούθησε”. Error — “εδώ υπάρχει πρόβλημα, διόρθωσέ το”. Μην χρησιμοποιείτε το Error για καταστάσεις που είναι αναμενόμενες και διαχειρίσιμες (για παράδειγμα, σφάλμα API 404).
Τέταρτος κανόνας — συνέπεια. Ολόκληρο το έργο πρέπει να χρησιμοποιεί ενιαίες συμβάσεις ονομασίας για tag και κατηγορίες. Συνιστάται το ClassName.methodName για tag Android και το module.subsystem για κατηγορίες iOS. Αυτό επιτρέπει γρήγορο φιλτράρισμα των αρχείων καταγραφής ανά στοιχείο.
Πέμπτος κανόνας — δοκιμάστε τα αρχεία καταγραφής. Στις δοκιμές μονάδας, ελέγξτε ότι σε συγκεκριμένα σενάρια καλείται το σωστό Log Level. Για αυτόν τον σκοπό, υπάρχουν βιβλιοθήκες mock καταγραφής: Mockito για Android, Cuckoo για iOS. Ο έλεγχος επιπέδων στις δοκιμές αποτρέπει τη διαρροή μηνυμάτων εντοπισμού σφαλμάτων στην παραγωγή.
Συχνές ερωτήσεις
Επιταχυνόμενη αποφόρτιση μπαταρίας και υπερβολική εγγραφή στον δίσκο. Κάθε Debug καταγραφή μορφοποιεί τη συμβολοσειρά και γράφει δεδομένα στο buffer. Σε συσκευές με μνήμη Flash, αυτό επιταχύνει τη φθορά του αποθηκευτικού μέσου. Επιπλέον, τα Debug αρχεία καταγραφής μπορεί να περιέχουν ευαίσθητα δεδομένα μη διαθέσιμα για προβολή στην παραγωγή.
Debug — για το σώμα του αιτήματος και της απόκρισης, κεφαλίδες και κωδικό κατάστασης. Info — για το γεγονός εκτέλεσης του αιτήματος (URL, μέθοδος, διάρκεια). Error — για αποτυχημένα αιτήματα με κωδικό 4xx/5xx. Μην χρησιμοποιείτε ποτέ Verbose για αρχεία καταγραφής δικτύου στην παραγωγή.
OSLogType.default (επίπεδο notice) — μηνύματα μέσης σημασίας, αποθηκεύονται στο αρχείο καταγραφής συστήματος και είναι ορατά στο Console.app. OSLogType.info — τεχνικά μηνύματα, δεν αποθηκεύονται μόνιμα, διαθέσιμα μόνο κατά την ενεργή προφιλοποίηση μέσω του Instruments.
R8/ProGuard αφαιρεί τα Log.v() και Log.d() όταν είναι ενεργοποιημένη η σμίκρυνση στην έκδοση release. Τα Log.i(), Log.w(), Log.e() διατηρούνται. Για πλήρη αφαίρεση όλων των αρχείων καταγραφής απαιτείται προσαρμοσμένος κανόνας -assumenosideeffects class android.util.Log με αναφορά όλων των επιπέδων.
Όχι — η υπερβολική καταγραφή υποβαθμίζει την αναγνωσιμότητα και την απόδοση. Καταγράψτε την είσοδο μόνο σε σύνθετες ή ασύγχρονες μεθόδους. Για σύγχρονες μεθόδους, αρκεί μία καταγραφή στο σημείο επιστροφής ή σφάλματος. Χρησιμοποιήστε το επίπεδο Debug για την ανίχνευση κλήσεων.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης