В этой статье рассматривается процесс ведения журнала, включая стандарты журналирования, рекомендации по уровням, классы, цели и многостековые приближения.
Стандарты журналов
Вход в систему 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.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 |
Рисунок 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 Runtime (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
запрашивает доступ к журналам устройства, система предлагает пользователю утвердить или отклонить запрос на доступ.