Поток вывода android logcat на SD-карту

Я хочу добиться следующего, но пока не повезло

  • Откройте файл на SD-карте при первом запуске приложения Android.
  • Поток вывода logcat в файл.
  • Когда приложение закроется, остановите потоковую передачу logcat.

В моем ApplicationClass расширяет метод Application onCreate(), я делаю это

wwLogManager.openLogFile();

а вот код в openLogFile()

        private static final String LOGCAT_COMMAND = "logcat -v time -f ";
        String timestamp = Long.toString(System.currentTimeMillis());
        String logFileName = BuildConstants.LOG_LOCATION + "_" + timestamp + ".log";                    
        mLogFile = new File(Environment.getExternalStorageDirectory() + logFileName);
        mLogFile.createNewFile();
        String cmd = LOGCAT_COMMAND + mLogFile.getAbsolutePath();
        Runtime.getRuntime().exec(cmd);

Я получаю файлы журналов на SD-карте, но вывод журнала в этих файлах не имеет никаких следов вызовов Log.i(), которые я размещал в своих действиях. Правильна ли команда logcat, которую я использовал здесь? Спасибо!


person Michael    schedule 07.08.2011    source источник
comment
Вы когда-нибудь находили решение?   -  person JPM    schedule 24.01.2012
comment
да. В итоге я использовал BufferedReader для чтения вывода из Runtime.getRuntime().exec(cmd).   -  person Michael    schedule 27.01.2012
comment
Можете ли вы опубликовать здесь ответ, который точно показывает, что вы сделали, для меня и всех остальных?   -  person JPM    schedule 27.01.2012
comment
@JPM: Пожалуйста, посмотрите ответ, который я только что опубликовал...   -  person Michael    schedule 28.01.2012


Ответы (4)


Прошу прощения, если я неправильно понимаю ваши цели, но, возможно, вы могли бы использовать java.util.logging API вместо использования Logcat или механизма ведения журнала Android.

Как и API ведения журналов Android, java.util.logging API позволяет легко регистрировать сообщения на различных уровнях, таких как FINE, FINER, WARN, SEVERE и т. д.

Но у стандартного API ведения журналов есть и дополнительные преимущества. Например, вы можете легко создать файл журнала с помощью Обработчик файлов. Фактически, FileHandler имеет встроенный журнал механизм ротации, поэтому вам не нужно (так сильно) беспокоиться об очистке файлов журнала. Вы также можете создать иерархию регистраторов; так, например, если у вас есть два регистратора s, com.example.foo и com.example.foo.bar, изменение уровня ведения журнала первого также изменит уровень ведения журнала второго. Это будет работать даже в том случае, если два регистратора созданные в разных классах! Кроме того, вы можете изменить поведение ведения журнала во время выполнения, указав файл конфигурации ведения журнала. Наконец, вы можете настроить формат журнала, внедрив собственный . Formatter (или просто используйте SimpleFormatter чтобы избежать формата XML по умолчанию).

Чтобы использовать стандартный API ведения журнала, вы можете попробовать что-то вроде этого:

    // Logger logger is an instance variable
    // FileHandler logHandler is an instance variable

    try {
        String logDirectory =
            Environment.getExternalStorageDirectory() + "/log_directory";

        // the %g is the number of the current log in the rotation
        String logFileName = logDirectory + "/logfile_base_name_%g.log";

        // ...
        // make sure that the log directory exists, or the next command will fail
        // 

        // create a log file at the specified location that is capped 100kB.  Keep up to 5 logs.
        logHandler = new FileHandler(logFileName, 100 * 1024, 5);
        // use a text-based format instead of the default XML-based format
        logHandler.setFormatter(new SimpleFormatter());
        // get the actual Logger
        logger = Logger.getLogger("com.example.foo");
        // Log to the file by associating the FileHandler with the log
        logger.addHandler(logHandler);
    }
    catch (IOException ioe) {
        // do something wise
    }

    // examples of using the logger
    logger.finest("This message is only logged at the finest level (lowest/most-verbose level)");
    logger.config("This is an config-level message (middle level)");
    logger.severe("This is a severe-level message (highest/least-verbose level)");

Механизм регистрации Android, безусловно, прост и удобен. Тем не менее, он не очень настраиваемый, и фильтрация журналов должна выполняться с помощью тегов, что может легко стать громоздким. С помощью java.uitl.logging API, вы можете избежать работы с множеством тегов, но легко ограничить файл журнала определенными частями вашего приложения, получить больший контроль над расположением и внешним видом журнала и даже настроить поведение журнала во время выполнения.

person swopecr    schedule 07.08.2011
comment
Спасибо! Моя цель состоит в том, чтобы иметь трассировку Android logcat в файле, чтобы я мог отслеживать события, связанные с моим приложением. Знаете ли вы, будет ли java.util.logging включать в себя трассировку стека Android. Например, когда приложение принудительно закрывается, регистрирует ли оно трассировку сбоя? - person Michael; 09.08.2011
comment
@Michael - Если ваше приложение дает сбой, оно должно сделать это через исключение. Метод java.util.logging позволяет регистрировать исключения. См. Logger для получения дополнительной информации. - person swopecr; 12.08.2011
comment
Не замедлит ли это приложение? в конце концов, это всего лишь телефон Android и с ограниченными ресурсами. запись в файл может быть дорогостоящим процессом. Верно? - person Sudarshan Bhat; 23.01.2012
comment
@Enigma: Да, но в экстремальных условиях, когда вам нужно зарегистрировать длительную операцию, эта утилита может быть полезна. Я не думаю, что нам это нужно постоянно. - person Michael; 26.01.2012

Я публикую свой ответ здесь, чтобы @JPM и другие могли видеть ... Код в основном просто выполняет команду logcat, а затем создает журнал из входного потока.

final StringBuilder log = new StringBuilder();
try {        
    ArrayList<String> commandLine = new ArrayList<String>();
    commandLine.add("logcat");
    commandLine.add("-d");
    ArrayList<String> arguments = ((params != null) && (params.length > 0)) ? params[0] : null;
    if (null != arguments){
        commandLine.addAll(arguments);
    }

    Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[0]));
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

    String line;
    while ((line = bufferedReader.readLine()) != null){ 
        log.append(line);
        log.append(LINE_SEPARATOR); 
    }
} 
catch (IOException e){
        //
} 

return log;
person Michael    schedule 27.01.2012

Попробуйте вручную настроить фильтр, как описано здесь: http://developer.android.com/guide/developing/debugging/debugging-log.html#filteringOutput

Что-то типа:

logcat ActivityManager:I MyApp:V *:S

Если вы замените «MyApp» тегами журнала, которые вы используете, это должно показать вам все информационные (и более крупные) журналы из ActivityManager и все подробные (и более крупные) журналы из вашего приложения.

person Connor Brinton    schedule 07.08.2011
comment
Спасибо за подсказку с фильтром - person Michael; 09.08.2011

Я знаю, что это поздний ответ на вопрос, но я настоятельно рекомендую использовать Logback для написания сообщений. в файл журнала, а также logcat.

  1. Скопируйте logback-android-1.0.10- 2.jar и slf4j-api-1.7.5.jar в папку с библиотеками.
  2. Щелкните правой кнопкой мыши обе библиотеки и в меню выберите «Путь сборки» -> «Добавить в путь сборки».
  3. Создайте файл logback.xml в папке с ресурсами и введите следующее:


  

  
  
    
      %msg
    
  

  
  
    
      WARN
    

    ${LOG_DIR}/log.txt

    
      %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
      
  

  
  
    
    
  
  1. Чтобы написать журнал:

    открытый класс MyActivity расширяет активность { public static final Logger logger = LoggerFactory.getLogger (MyActivity.class);

    protected void onCreate(Bundle b)
    {
        super(b);
        try{
            throw new Exception("Test");
        }catch(Exception e){
            logger.error("Something bad happened",e);
        }
    }
    

    }

person W.K.S    schedule 14.12.2013
comment
Честно говоря, я не мог заставить это форматировать правильно. Но вы можете увидеть код, если вы нажмете на редактирование. - person W.K.S; 14.12.2013