В этой статье рассматривается процесс ведения журнала, включая стандарты ведения журнала, руководящие принципы уровней, классы, цели и многостековые приближения.
Стандарты бревен
Логирование в Android является сложным из-за смеси используемых стандартов, объединенных в logcat
. Основные используемые стандарты подробно описаны ниже:
Источник | Примеры | Руководство на уровне стека |
---|---|---|
RFC 5424 (стандарт syslog ) | Ядро Linux, множество приложений Unix | Ядро, системные демоны |
android.util.Log | Android-фреймворк + ведение журнала приложений | Android-фреймворк и системное приложение |
java.util.logging.Level | Общее ведение журнала в Java | несистемное приложение |
Рисунок 1: Стандарты уровня журнала.
Хотя каждый из этих стандартов имеет схожую конструкцию уровня, они различаются по детализации. Приблизительные эквиваленты по всем стандартам следующие:
Уровень RFC 5424 | RFC 5424 Серьезность | Описание RFC 5424 | android.util.Log | java.util.logging.Уровень |
---|---|---|---|---|
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 |
Рисунок 2: уровни ведения журнала syslog
, Android и Java.
Рекомендации по уровню журнала
Существуют существующие руководства для каждого стандарта журнала. Выбранный уровень журнала соответствует соответствующему используемому стандарту, например, стандарту syslog
для разработки ядра.
Порядки уровней журнала, от наименьшего к наибольшему, показаны на трех рисунках ниже:
ERROR | Эти журналы всегда сохраняются. |
WARN | Эти журналы всегда сохраняются. |
INFO | Эти журналы всегда сохраняются. |
DEBUG | Эти журналы компилируются, но удаляются во время выполнения. |
VERBOSE | Эти журналы никогда не компилируются в приложение, за исключением периода разработки. |
Рисунок 3: android.util.Log
CONFIG | Уровень сообщений для статических сообщений конфигурации |
FINE | Уровень сообщения, предоставляющий информацию для отслеживания |
FINER | Указывает на довольно подробное сообщение об отслеживании |
FINEST | Указывает на очень подробное сообщение об отслеживании. |
INFO | Уровень сообщения для информационных сообщений |
SEVERE | Уровень сообщения, указывающий на серьезную неисправность |
WARNING | Уровень сообщения, указывающий на потенциальную проблему |
Рисунок 4: java.util.Logging.Level
.
0 | Чрезвычайная ситуация | Система непригодна для использования |
1 | Тревога | Необходимо принять меры немедленно. |
2 | Критический | Критические состояния |
3 | Ошибка | Ошибочные состояния |
4 | Предупреждение | Предупреждающие условия |
5 | Уведомление | Нормальное, но значимое состояние |
6 | Информационный | Информационные сообщения |
7 | Отлаживать | Сообщения уровня отладки |
Рисунок 5: 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; |
---|
Логирование может быть удалено на основе APK через наборы правил ProGuard R8
во время компиляции. Следующий пример удаляет все ниже уровня логирования INFO
для android.util.Log
:
# 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 (ART)
Для системных приложений и служб доступно несколько классов:
Сорт | Цель |
---|---|
android.telephony.Rlog | Радиолог |
android.util.Log | Общая регистрация приложений |
android.util.EventLog | Регистрация диагностических событий системного интегратора |
android.util.Slog | Ведение журнала платформы |
Рисунок 6: Доступные классы и цели системного журнала.
Хотя android.util.Log
и android.util.Slog
используют одни и те же стандарты уровня журнала, Slog
— это класс @hide
, используемый только платформой. Уровни EventLog
сопоставляются с записями в файле event.logtags
в /system/etc/event-log-tags
.
Собственная регистрация
Ведение журнала в C/C++ следует стандарту syslog
, где syslog
(2) соответствует syslog
ядра Linux, который управляет буфером 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 |
Рисунок 7: оболочки liblog
.
В Android имеются интерфейсы более высокого уровня для ведения журнала, которые более предпочтительны, чем прямое использование liblog
, как показано ниже:
Библиотека | Использование |
---|---|
async_safe | Библиотека только для регистрации из сред, безопасных для асинхронных сигналов |
libbase | Библиотека журналирования, которая предоставляет потоковый интерфейс C++ для журналирования, аналогичный журналированию в стиле Google (glog). libbase можно использовать как во внешних проектах, так и в приложениях, использующих libbase_ndk . |
Рисунок 8: Библиотеки журналов более высокого уровня.
Многостековые приближения
Из-за различий в гранулярности и уровне намерения, нет четких или точных соответствий различных стандартов ведения журнала. Например, уровни java.util.logging.Level
и android.util.Log
для журналов ошибок не соответствуют 1:1:
java.util.Logging.Level | android.util.Log |
---|---|
СЕРЬЕЗНЫЙ | Log.wtf |
СЕРЬЕЗНЫЙ | Log.e |
Рисунок 9: Уровень ошибок при стандартном ведении журнала Java и ведении журнала Android.
В подобных случаях используйте индивидуальный стандарт, чтобы определить, какой уровень применять.
Во время разработки системы с несколькими компонентами уровня стека следуйте рисунку 1, чтобы определить, какой стандарт использовать для каждого компонента. Для приблизительного руководства по обмену сообщениями на уровне следуйте рисунку 2.
Безопасность и конфиденциальность
Не регистрируйте персонально идентифицируемую информацию (PII). Сюда входят такие данные, как:
- Адреса электронной почты
- Номера телефонов
- Имена
Аналогичным образом, некоторые данные считаются конфиденциальными, даже если они не позволяют явно идентифицировать личность.
Например, хотя информация о часовом поясе не считается персонально идентифицируемой, она дает представление о приблизительном местоположении пользователя.
Политика регистрации и приемлемые сведения должны рассматриваться в рамках проверки безопасности и конфиденциальности перед выпуском.
Журналы устройств
Доступ ко всем журналам устройства, в том числе с использованием android.permission.READ_LOGS
, ограничен:
- Если приложение в фоновом режиме запрашивает доступ ко всем журналам устройства, запрос автоматически отклоняется, если только приложение:
- Совместно использует системный UID.
- Использует собственный системный процесс (
UID
<APP_UID
). - Использует
DropBoxManager
. - Доступ только к буферу журнала событий.
- Использует API
EventLog
. - Использует инструментальные тесты.
- Если приложение на переднем плане с
READ_LOGS
запрашивает доступ к журналам устройства, система предлагает пользователю одобрить или отклонить запрос на доступ.