Записывать вывод в файл и системный журнал одновременно - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь диагностировать проблему в приложении, которое я написал.Эта проблема носит спорадический характер и возникает только в реальных условиях: в полевых условиях, вдали от моего ПК, и когда я нахожусь в какой-то ситуации, без ресурсов для немедленной отладки.Поэтому лучше всего собирать и анализировать данные журналов.

К сожалению, к тому времени, когда я осознаю, что проблема снова возникла, и приступил к ее отладке, все данные журналов уже вышли из журнала Android, когда ячасто одновременно запускаются другие болтливые приложения.Увеличение размера буфера журнала не помогло (либо Android не соблюдает его, либо другие приложения все еще слишком болтливы), поэтому я отказался от этого маршрута.

По этой причине я сейчас рассматриваю возможность ведения журнала приложений.в отдельный текстовый файл в дополнение к обычному журналу.

Теперь я мог легко удвоить каждый вызов, как

Log.i(TAG, "something happened");

, добавив еще один вызов, который записывает то же самое в файл журнала - но этомне не кажется очень элегантным.

Другой вариант - заменить все вызовы на Log оболочкой, которая записывает событие как в журнал Android, так и в файл журнала.

Вопрос: Предоставляет ли API Android встроенный механизм для этого, то есть Log для записи своих данных в журнал по умолчанию и в текстовый файл одновременно?Или мне нужно написать это самому?

Редактировать:

Допущения:

  • Я знаю, где в моем коде мне нужногенерировать вывод журнала (который может произойти где угодно, что может включать или не включать исключение) и что я хочу записать в журнал.
  • Получение данных журнала с устройства на мой ПК также не является проблемой (персональное шоу, я просто подключаю свой телефон к компьютеру и передаю файл журнала).

Если вы знаете, что в текущем API Android нет встроенного механизма для достижения того, чего я хочу, тогда ”нет, Android не поддерживает это », - вполне приемлемый ответ.В этом случае решение очевидно - я бы вернулся к функции оболочки.Я специально не ищу другой подход к проблеме.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

После дополнительных исследований кажется, что Android API не предоставляет стандартного способа сделать это .Существует два возможных обходных пути:

Зеркальный вывод на источнике

  • System.out и System.err, который записывается на консоль в настольных системах и записывается в журнал.Android.Эти два могут быть перенаправлены в любой PrintStream по вашему выбору, который даст вам весь вывод консоли Java.Вы можете создать подкласс PrintStream, чтобы дублировать его входные данные, передавая их в поток по умолчанию, а также в файл по вашему выбору.
  • Создайте класс, который предоставляет те же методы, что и android.util.Log.В каждом методе вызовите соответствующий метод android.util.Log и дополнительно запишите данные в файл.Если вы вызываете свой класс Log (но с другим именем пакета, например, org.example.Log), тогда все, что вам нужно сделать, это заменить импорт android.util.Log на импорт вашего класса, и любые вызовы метода Log будутперейти к вашему классу.

Предостережения: Это даст вам только данные, явно зарегистрированные вашим кодом (то есть, для которых у вас есть исходные файлы), а также все, что идетдо System.out или System.err.Он не будет включать вывод журнала из библиотек JAR (если вы не можете изменить их исходный код), а также вывод, сгенерированный системой (например, следы стека из обработчиков исключений по умолчанию) или другими процессами (некоторые из которых могут быть системными процессами и отчетами).условия, связанные с вашим процессом).

Чтение журналов из командной строки

В этой статье объясняется, как читать журналы из Android.В двух словах:

  • Android включает в себя утилиту командной строки с именем logcat на устройстве, которая будет непрерывно передавать сообщения журнала до остановки.(Попробуйте его, adb shell вставив на свое устройство и запустив его. У него есть несколько параметров командной строки для управления его поведением. Однако не уверен, присутствует ли он во всех дистрибутивах.)
  • Запустите этовведите команду Runtime.getRuntime().exec("logcat"), затем получите входной поток возвращаемого процесса.Это даст вам входной поток сообщений журнала.
  • Согласно статье, вашему приложению требуется разрешение android.permission.READ_LOGS для чтения журналов.

У меня есть заявления о том, что определенные версииAndroid (упомянуто 4.2), однако, не разрешайте предоставлять это разрешение несистемным приложениям.Согласно моим собственным тестам, поведение без этих разрешений отличается: Anbox вернет полный logcat, тогда как LineageOS (протестированный на 15.1) будет показывать только записи журнала из приложения, которое его вызвало (включая предыдущие экземпляры, предположительно все, что связано с тем же пользователем Linux).).Это может быть ограничение или функция фильтра приветствия.YMMV.

logcat удобно имеет параметр командной строки -f для указания выходного файла.Я попытался

Runtime.getRuntime().exec("logcat -f " + absolutePathToLogFile);

, и logcat продолжает регистрировать, пока работает процесс приложения.Уничтожение приложения (нажав X в строке заголовка на Anbox), по-видимому, также завершило дочерний процесс.

Теперь вы можете запустить этот код при запуске приложения или превратить эту функцию в отдельную.приложение, которое запускается при загрузке и непрерывно собирает журналы для всех приложений.

Предостережения: Это может быстро заполнить ваше хранилище, если у вас запущены некоторые болтливые приложения (именно поэтому записи вращаются изЛогкат так быстро в первую очередь).Рекомендуется настроить зеркалирование журналов (например, через «Предпочтения») и / или регулярно удалять старые файлы.Кроме того, если вы продолжите процесс logcat до завершения работы приложения, вы не сможете получить доступ к файлу через MTP, поскольку нет простого способа запустить сканер мультимедиа (если вы сканируете файл, пока он все еще записывается в, он будет обрезан по протоколу MTP, пока не будет запущено другое сканирование носителя.

0 голосов
/ 26 февраля 2019

Вы не указали, если выбрасывается какое-то исключение, но вы не обрабатываетеНа всякий случай посмотрите на этот ответ: Исключение необработанной обработки Android

Если вам нужно взглянуть на кучу переменных и объектов, я бы предложил два варианта:

  • Напишите копию вашего журнала в файл.Когда ваша проблема возникает, просто попросите пользователя отправить файл вам.Это идеально для тестов с самоосознающими пользователями.
  • Получайте статистику использования, как это делают коммерческие программы.Просто зарегистрируйте пользовательские операции и отправьте данные на ваш сервер (для этого вам понадобится).Это самый прозрачный способ ведения удаленного ведения журнала.

В случае записи журнала в файл вы можете читать и записывать то, что вы хотите, во внутренней памяти (в песочнице приложения) или во внешней памяти.(в этом случае требуется разрешение на запись и явное разрешение должно быть предоставлено во время выполнения, если вы ориентируетесь на Android 6 и выше).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...