텍스트 파일에 Android 쓰기 로그


129

이 Mine 코드를 사용하여 Android 파일의 사용자 정의 Log.txt 파일에 로그를 작성하려고 하는데이 방법은 파일을 생성하지만 아무것도 포함하지 않습니다. 기본적으로 파일의 이전 내용을 읽은 다음 기존 내용에 내 데이터를 추가하고 싶습니다.

코드는 다음과 같습니다.

public static void write(String str) 
    {
        InputStream fileInputStream = null;
        FileOutputStream fileOutpurStream = null;
        try
        { 
            fileInputStream = new FileInputStream(file);
            fileOutpurStream = new FileOutputStream(file);
            if(file.exists())
            {
                int ch = 0;
                int current = 0;
                StringBuffer buffer = new StringBuffer();
                while((ch = fileInputStream.read()) != -1)
                {
                    buffer.append((char) ch);
                    current++;
                }
                byte data[]=new byte[(int)file.length()];
                fileInputStream.read(data);   
                fileOutpurStream.write(data);
                fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
                fileOutpurStream.flush();
            } 
            else
            {   
                file.createNewFile();
                fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
                fileOutpurStream.flush();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                fileInputStream.close();
                fileOutpurStream.flush();
                fileOutpurStream.close();
                fileOutpurStream = null;
                fileInputStream = null;
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

답변:


247

이것이 도움이되기를 바랍니다 ...

public void appendLog(String text)
{       
   File logFile = new File("sdcard/log.file");
   if (!logFile.exists())
   {
      try
      {
         logFile.createNewFile();
      } 
      catch (IOException e)
      {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   try
   {
      //BufferedWriter for performance, true to set append to file flag
      BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
      buf.append(text);
      buf.newLine();
      buf.close();
   }
   catch (IOException e)
   {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}

83
Manifest에서 writing_external_storage에 대한 권한을 추가하는 것을 잊지 마십시오!
virusss8

5
buf.flush ();를 추가해야했습니다. beforebuf.close (); 그러나 tjis 기능은 정확히 내가 필요한 것입니다. 감사
Csabi

1
이 함수를 어디에서 호출해야 모든 응용 프로그램의 로그인 파일을 작성합니까 ???
uniruddh 2014

10
블록 buf.close()안에 있도록 코드를 재구성하는 것이 좋습니다 finally.
William Price

2
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />물론 @ virusss8이 의미하는 바였습니다.
Bengt 2015

29

일반적인 Java 로깅 및 Android 로깅을 처음 사용하는 경우

  1. Log4j 는 일반적인 Java 로깅 구현이며 이제 Apache 소프트웨어 기반의 프로젝트입니다. Android 전용이 아니므로 Android와 일부 비 호환성이 있습니다.
  2. SL4J는 로깅 구현이 아니라 추상화 계층입니다. Log4j와 같은 자체 로깅 구현을 사용하려는 경우 프로젝트에 대한 각 타사 라이브러리 종속성과 같은 상황을 피하는 데 도움이됩니다. 소스 .

Android에서 txt에 로깅하는 몇 가지 옵션은 다음과 같습니다.

  1. logcat -f답변 에서와 같이 사용 파일에 로그인 할 수 있습니다. Android 4.2부터 READ_LOGS 권한은 영향을 미치지 않으며 모든 애플리케이션 (전화가 루팅되지 않은 경우)은 자체 로그 만 읽을 수 있습니다. 여기서 단점은 logcat 버퍼가 순환적이고 크기 제한이 있다는 것입니다. 이전 로그를 얻지 못할 수 있습니다.
  2. 이전 답변 에서와 같이 microlog4android (Android와 같은 모바일 장치 용으로 작성 됨)를 사용하십시오 . 방법이있을 수 있지만 응용 프로그램 내부 저장소에 로깅하기 위해 microlog4Android를 사용하는 방법을 알 수 없었습니다. 로그 경로에 대한 유일한 옵션은 sdcard와 같은 외부 저장소 였으므로 사용할 수 없었습니다.
  3. android-logging-log4j 와 함께 Log4j 를 사용합니다 . android-logging-log4j는 무엇을합니까? 두 가지 기능을 제공하여 Android에서 Log4j를 더 쉽게 사용할 수 있습니다.

    • 로깅 파일 외에도 logcat에 로그를 보내는 옵션
    • LogConfigurator 클래스를 제공하여 파일 경로, 최대 파일 크기, 백업 수 등과 같은 Log4j 구성 옵션을 설정하는 간단한 방법입니다.

    아래의 간단한 예. 공지 사항 것을 logger아래의 예에서 객체는의 Log4j 반환 된 객체가 아니라 안드로이드 로깅-의 log4j 클래스입니다. 따라서 android-logging-log4j는 Log4j 구성에만 사용됩니다.

  4. 아직 LogBack 시도 . LogBack은 Log4J 1.x 및 SL4J 라이브러리를 만든 동일한 사람이 개발했습니다. 하지만 Log4j 2.x와는 관련이 없습니다.

Android에서 Log4j를 사용하는 단계.

  1. log4j-1.2.x.jarandroid-logging-log4j-1.0.3.jar 모두 추가 libs와 폴더로.

  2. 외부 저장소를 사용하는 경우에만 권한 추가
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  3. Log4j도우미 클래스 작성

    package com.example.logger;
    
    import android.os.Environment;
    import de.mindpipe.android.logging.log4j.LogConfigurator;
    
    public class Log4jHelper {
        private final static LogConfigurator mLogConfigrator = new LogConfigurator();
    
        static {
            configureLog4j();
        }
    
        private static void configureLog4j() {
            String fileName = Environment.getExternalStorageDirectory() + "/" + "log4j.log";
            String filePattern = "%d - [%c] - %p : %m%n";
            int maxBackupSize = 10;
            long maxFileSize = 1024 * 1024;
    
            configure( fileName, filePattern, maxBackupSize, maxFileSize );
        }
    
        private static void configure( String fileName, String filePattern, int maxBackupSize, long maxFileSize ) {
            mLogConfigrator.setFileName( fileName );
            mLogConfigrator.setMaxFileSize( maxFileSize );
            mLogConfigrator.setFilePattern(filePattern);
            mLogConfigrator.setMaxBackupSize(maxBackupSize);
            mLogConfigrator.setUseLogCatAppender(true);
            mLogConfigrator.configure();
    
        }
    
        public static org.apache.log4j.Logger getLogger( String name ) {
            org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger( name );
            return logger;
        }
    }
  4. 활동 수업에서

    org.apache.log4j.Logger log= Log4jHelper.getLogger( "YourActivity" );
    log.error("Error");
    log.info("Info");
    log.warn("Warn");

예제 소스 . 처음부터 다시 작성된 log4j 2.x (개선 된 기능)는 log4j 1.x와 역 호환되지 않습니다. 따라서 android-logging-log4j jar와 함께 log4j 1.2.x jar를 사용해야합니다. 애플리케이션 내부 파일에 로그인하고 나중에 파일을 이메일로 보낼 수있었습니다.setReadable(true, false)


24

microlog4android는 나를 위해 작동하지만 문서는 매우 열악합니다. 추가해야 할 것은 빠른 시작 자습서입니다. 입니다.

여기 내가 찾은 빠른 튜토리얼이 있습니다.

  1. 기본 활동에 다음 정적 변수를 추가하십시오.

    private static final Logger logger = LoggerFactory.getLogger();
  2. onCreate()방법에 다음을 추가하십시오 .

    PropertyConfigurator.getConfigurator(this).configure();
  3. 이름이 지정된 파일을 microlog.properties만들고 assets디렉토리에 저장합니다.

  4. microlog.properties다음과 같이 파일을 편집하십시오 .

    microlog.level=DEBUG
    microlog.appender=LogCatAppender;FileAppender
    microlog.formatter=PatternFormatter
    microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
  5. 다음과 같은 로깅 문을 추가합니다.

    logger.debug("M4A");

각 클래스에 대해 1)에 지정된 로거 객체를 만듭니다.

6. 다음 권한을 추가 할 수 있습니다.

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

다음은 튜토리얼 소스 입니다.


4
FileAppender는 sdcard에 "microlog.txt"파일을 생성합니다 (제 경우 전체 경로는 "/sdcard/microlog.txt).
Ruslan Yanchyshyn 2014

2
이 빠른 자습서는 Microlog4Android 공식 문서의 일부 여야합니다.
Johan Karlsson 2014 년

오류 : Android Dex : [프로젝트] com.android.dex.DexException : 여러 dex 파일이 Lcom / google / code / microlog4android / Level을 정의합니다. ?

10

경고 : 완전히 오해 할 수 있지만 로그 파일 만 있으면되는데 왜 땀을 흘리나요?

이것을 bat 파일에 넣으십시오 (도구 디렉토리의 경로를 변경하면 yourappname은 물론 앱의 이름입니다).

cd "C:\devAndroid\Software\android-sdk-windows-1.6_r1\android-sdk-windows-1.6_r1\tools"
adb logcat -v time   ActivityManager:W  yourappname:D  *:W >"C:\devAndroid\log\yourappname.log"

그런 다음 코드에서 다음과 유사한 작업을 수행하십시오.

Log.d("yourappname", "Your message");

로그를 생성하려면 USB 케이블을 연결하고 bat 파일을 실행하십시오.

문안 인사


android.util.Log 가져 오기를 잊지 마세요.
Spidey

"오류 : 둘 이상의 장치 및 에뮬레이터-장치 대기 중"을 반환하며 그 이상은 없습니다. 뭔가 잘못 되었나요?
eros

20
응용 프로그램을 실행하는 동안 PC 근처에 있지 않은 경우 어떻게 작동합니까?
DDSports

@DDSports 그렇지 않습니다. 그러나 그는 문제의 본질을 이해하지 못했다
Ewoks

@DDSports 당신은 와이파이를 통해 adb를 사용할 수 있습니다.
Daniel F

8

slf4android lib를 사용하십시오 . android java.util.logging. *을 사용하여 slf4j api
간단하게 구현 한 것입니다 .

풍모:

  • 즉시 파일에 로그인
  • 다른 대상에 로그인 LoggerConfiguration.configuration().addHandlerToLogger
  • 기기를 흔들어 이메일을 통해 스크린 샷과 함께 로그를 보냅니다.
  • 정말 작습니다. 55kB 밖에 걸리지 않습니다.

slf4android는 주로 유지 @miensol .

블로그에서 slf4android에 대해 자세히 알아보세요.


7

microlog4android를 살펴보아야합니다. 그들은 파일에 기록 할 준비가 된 솔루션을 가지고 있습니다.

http://code.google.com/p/microlog4android/


12
이것은 좋은 라이브러리처럼 보이지만 문서는 끔찍합니다. 나는 그것을 작동시키는 방법을 알아낼 수 없었고 결국 스스로 무언가를 조립하게되었습니다.
Paul Lammertsma 2011

@PaulLammertsma : 대신 Microlog4Android에 기여한 것이 좋을 것 같습니다. 참고 : Log4j와 동일한 API가 있습니다. 잘못된 문서에 대해 죄송합니다.
Johan Karlsson 2014 년

@Paul Lammertsma 문서가 그렇게 나빠서 사용할 수 없다면 어떻게 좋을 수 있습니까? 당신이 그것을 작동시킬 수 없다면 그것은 쓰레기입니다.
놀라운 1

7

늦었지만 도움이 되었으면 좋겠어요.

public void writefile()
    {
        File externalStorageDir = Environment.getExternalStorageDirectory();
        File myFile = new File(externalStorageDir , "yourfilename.txt");

        if(myFile.exists())
        {
           try
           {

        FileOutputStream fostream = new FileOutputStream(myFile);
        OutputStreamWriter oswriter = new OutputStreamWriter(fostream); 
        BufferedWriter bwriter = new BufferedWriter(oswriter);   
        bwriter.write("Hi welcome ");
        bwriter.newLine();            
        bwriter.close(); 
        oswriter.close(); 
        fostream.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
        else
        {
            try {
                myFile.createNewFile();
            }
            catch (IOException e) 
            {
                e.printStackTrace();
            }
        }

여기 bfwritter.newline에서 파일에 텍스트를 씁니다. 그리고 권한을 추가하십시오

 <uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>

당신의 매니페스트 파일에 실패없이.


6

명령 줄 방식으로 다음 코드를 사용하여이 문제를 해결했습니다.

File outputFile = new File("pathToFile"); 
Runtime.getRuntime().exec("logcat -c");
Runtime.getRuntime().exec("logcat -v time -f " + outputFile.getAbsolutePath())

여기서 "시간"옵션은 메시지를 발행하는 프로세스의 날짜, 호출 시간, 우선 순위 / 태그 및 PID에 대한 메타 데이터 필드 세부 사항을 추가합니다.

그런 다음 코드에서 다음과 유사한 작업을 수행하십시오 (android.util.Log 사용).

Log.d("yourappname", "Your message");

4
때 잘 작동 adb연결되어 있지만 장치가 독립형 모드에있을 때하지 작업을 수행합니다. 프로덕션에서는 사용하지 않겠지 만 디버그 모드에서는 간단한 솔루션입니다.
Julien Kronegg

2

일반적으로 스트림을 열기 전에 파일 핸들이 있어야합니다. else 블록에서 createNewFile () 전에 fileOutputStream 핸들 이 있습니다. 스트림이 파일이 없으면 생성하지 않습니다.

실제로 안드로이드에 국한된 것은 아니지만이 목적을위한 많은 IO입니다. 많은 "쓰기"작업을 차례로 수행하면 어떻게됩니까? 전체 내용을 읽고 전체 내용을 작성하며 시간이 걸리며 더 중요한 것은 배터리 수명입니다.

java.io.RandomAccessFile, seek () 'ing을 끝까지 사용한 다음 writeChars ()를 사용하여 추가하는 것이 좋습니다. 훨씬 더 깔끔한 코드이고 훨씬 빠를 것입니다.


2

파일 기반 로깅을 사용하여 표준 android.util.Log 구현을 확장하는 간단하고 가벼운 클래스 (약 260 LoC)를 만들었습니다.
모든 로그 메시지는 android.util.Log를 통해 기록되고 장치의 텍스트 파일에도 기록됩니다.

github에서 찾을 수 있습니다 :
https://github.com/volkerv/FileLog


1
UI 스레드에서 파일 작업이 수행되지 않도록하기 위해 필요한 것은 아닙니다. 엄청난 양의 파일 로깅이있는 경우?
Jayshil 데이브

2

오랜 조사 끝에 다음과 같은 사실을 발견했습니다.

  • android.util.Log 기본적으로 사용 java.util.logging.Logger
  • LogCat은 loggername과 함께 사용 하여 ""인스턴스를 가져옵니다.LogManager.getLogManager().getLogger("")
  • Android 장치는 디버그 앱 실행 후 LogCat logger인스턴스에 추가됩니다.com.android.internal.logging.AndroidHandler
  • 그러나!!! ( ) 와 같은 com.android.internal.logging.AndroidHandler수준 이상으로 만 logcat에 메시지를 인쇄합니다.java.util.logging.Level.INFOLevel.INFO, Level.WARNING, Level.SEVERE, Level.OFF

따라서 파일에 로그를 작성하려면 다음을 rootLogger "" 추가하십시오 java.util.logging.FileHandler.

  class App : Application{
    override fun onCreate() {
      super.onCreate()
      Log.d(TAG, printLoggers("before setup"))

      val rootLogger = java.util.logging.LogManager.getLogManager().getLogger("")
      val dirFile = destinationFolder
      val file = File(dirFile,"logFile.txt")
      val handler = java.util.logging.FileHandler(file.absolutePath, 5* 1024 * 1024/*5Mb*/, 1, true)
      handler.formatter = AndroidLogFormatter(filePath = file.absolutePath)

      rootLogger?.addHandler(handler)

      Log.d(TAG, printLoggers("after setup"))
    }
  }

val destinationFolder: File
        get() {
            val parent = 
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absoluteFile
            val destinationFolder = File(parent, "MyApp")
            if (!destinationFolder.exists()) {
                destinationFolder.mkdirs()
                destinationFolder.mkdir()
            }
            return destinationFolder
        }
class AndroidLogFormatter(val filePath: String = "", var tagPrefix: String = "") : Formatter() {

    override fun format(record: LogRecord): String {
        val tag = record.getTag(tagPrefix)
        val date = record.getDate()
        val level = record.getLogCatLevel()
        val message = record.getLogCatMessage()
        return "$date $level$tag: $message\n"
    }
}

fun LogRecord.getTag(tagPrefix: String): String {
    val name = loggerName
    val maxLength = 30
    val tag = tagPrefix + (if (name.length > maxLength) name.substring(name.length - maxLength) else name)
    return tag
}

fun LogRecord.getDate(): String? {
    return Date(millis).formatedBy("yyyy-MM-dd HH:mm:ss.SSS")
}

fun Date?.formatedBy(dateFormat: String): String? {
    val date = this
    date ?: return null
    val writeFormat = SimpleDateFormat(dateFormat, Locale.getDefault()) //MM в HH:mm
    return writeFormat.format(date)
}

fun LogRecord.getLogCatMessage(): String {
    var message = message

    if (thrown != null) {
        message += Log.getStackTraceString(thrown)
    }
    return message
}

fun Int.getAndroidLevel(): Int {
    return when {
        this >= Level.SEVERE.intValue() -> { // SEVERE
            Log.ERROR
        }
        this >= Level.WARNING.intValue() -> { // WARNING
            Log.WARN
        }
        this >= Level.INFO.intValue() -> { // INFO
            Log.INFO
        }
        else -> {
            Log.DEBUG
        }
    }
}

fun LogRecord.getLogCatLevel(): String {
    return when (level.intValue().getAndroidLevel()) {
        Log.ERROR -> { // SEVERE
            "E/"
        }
        Log.WARN -> { // WARNING
            "W/"
        }
        Log.INFO -> { // INFO
            "I/"
        }
        Log.DEBUG -> {
            "D/"
        }
        else -> {
            "D/"
        }
    }
}

fun getLoggerLevel(level: Int): Level {
    return when (level) {
        Log.ERROR -> { // SEVERE
            Level.SEVERE
        }
        Log.WARN -> { // WARNING
            Level.WARNING
        }
        Log.INFO -> { // INFO
            Level.INFO
        }
        Log.DEBUG -> {
            Level.FINE
        }
        else -> {
            Level.FINEST
        }
    }
}

앱에서 모든 로거를 인쇄하려면 다음을 사용하십시오.

Log.e(TAG, printLoggers("before setup"))

 private fun printLoggers(caller: String, printIfEmpty: Boolean = true): String {
        val builder = StringBuilder()
        val loggerNames = LogManager.getLogManager().loggerNames
        builder.appendln("--------------------------------------------------------------")
        builder.appendln("printLoggers: $caller")
        while (loggerNames.hasMoreElements()) {
            val element = loggerNames.nextElement()
            val logger = LogManager.getLogManager().getLogger(element)
            val parentLogger: Logger? = logger.parent
            val handlers = logger.handlers
            val level = logger?.level
            if (!printIfEmpty && handlers.isEmpty()) {
                continue
            }
            val handlersNames = handlers.map {
                val handlerName = it.javaClass.simpleName
                val formatter: Formatter? = it.formatter
                val formatterName = if (formatter is AndroidLogFormatter) {
                    "${formatter.javaClass.simpleName}(${formatter.filePath})"
                } else {
                    formatter?.javaClass?.simpleName
                }
                "$handlerName($formatterName)"
            }
            builder.appendln("level: $level logger: \"$element\" handlers: $handlersNames parentLogger: ${parentLogger?.name}")
        }
        builder.appendln("--------------------------------------------------------------")
        return builder.toString()
    }

안녕하세요. 이 ""로거를 사용하는 이점은 무엇입니까? 커스텀 로거와 차이가 없습니다. 아니면 내가 뭔가를 놓치고 있습니까?
Abins Shaji

1

이 변형은 훨씬 더 짧습니다.

{
    최종 파일 경로 = new File (
            Environment.getExternalStorageDirectory (), "DBO_logs5");
    if (! path.exists ()) {
        path.mkdir ();
    }
    Runtime.getRuntime (). exec (
            "logcat -d -f"+ 경로 + File.separator
                    + "dbo_logcat"
                    + ".txt");
} catch (IOException e) {
    e.printStackTrace ();
}

1

내가 작성한 도서관을 사용할 수 있습니다. 사용하기 매우 쉽습니다.

이 종속성을 gradle 파일에 추가하십시오.

dependencies {
    compile 'com.github.danylovolokh:android-logger:1.0.2'
}

Application 클래스에서 라이브러리를 초기화합니다.

File logsDirectory = AndroidLogger.getDefaultLogFilesDirectory(this);
    int logFileMaxSizeBytes = 2 * 1024 * 1024; // 2Mb
    try {
        AndroidLogger.initialize(
                this,
                logsDirectory,
                "Log_File_Name",
                logFileMaxSizeBytes,
                false
                );
    } catch (IOException e) {
        // Some error happened - most likely there is no free space on the system
    }

라이브러리를 사용하는 방법은 다음과 같습니다.

AndroidLogger.v("TAG", "Verbose Message");

그리고 이것은 로그를 검색하는 방법입니다.

AndroidLogger.processPendingLogsStopAndGetLogFiles(new AndroidLogger.GetFilesCallback() {
        @Override
        public void onFiles(File[] logFiles) {
            // get everything you need from these files
            try {
                AndroidLogger.reinitAndroidLogger();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

다음은 자세한 정보가있는 github 페이지에 대한 링크입니다. https://github.com/danylovolokh/AndroidLogger

도움이 되었기를 바랍니다.


1

log4j의 많은 이전 버전이 현재 작동하지 않습니다 (2019 년 5 월). 하지만 Hyperlog를 사용할 수 있습니다. 작동하는지 확인할 수 있습니다.

  1. 종속성 및 동기화 프로젝트에이 줄 추가

    implementation 'com.hypertrack:hyperlog:0.0.10'
  2. 새 응용 프로그램 클래스를 만듭니다 (새 Java 클래스를 만들고 응용 프로그램을 확장). 그런 다음 onCreate 메서드에서 다음 줄을 추가합니다.

    HyperLog.initialize(this);
    HyperLog.setLogLevel(Log.VERBOSE);
    
    HyperLog.getDeviceLogsInFile(this);
  3. 응용 프로그램 파일이 정의되도록 매니페스트 파일을 변경합니다.

    <application
        android:name=".AppClass"
        .....
  4. 다른 기록 방법 :

    HyperLog.d(TAG,"debug");
    HyperLog.i(TAG,"information");
    HyperLog.e(TAG,"error");
    HyperLog.v(TAG,"verbose");
    HyperLog.w(TAG,"warning");
    HyperLog.a(TAG,"assert");
    HyperLog.exception(TAG,"exception",throwable);
  5. 로그 파일을 찾으십시오. 로 이동

    RootFolder/android/data/"appPackageName/LogFiles/

HyperLog.getDeviceLogsInFile (this);로 생성 된 파일에서이 라이브러리를 시도했습니다. 마지막 생성 된 로그가
mad_greasemonkey은
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.