3

logback-androidを使用してログを書き込み、 ACRAを使用して Google ドキュメントに送信できるようにアプリをセットアップしようとしています。これは可能だと思いますが、ログをどこに書き込むかが問題です。

どちらのライブラリもハードコードされたファイル名が必要なので、getStorageDirectory(). 最初の質問は、フル パスを指定しない場合、ログはどこに書き込まれるのでしょうか? フルパスを指定してハードコードする必要があり/data/data/com.example/...ますか?

これが私の構成です:

<!-- Logback configuration. -->
<logback>
<configuration>
    <appender
        name="FILE"
        class="ch.qos.logback.core.FileAppender" >
        <file>applog.log</file>
        <encoder>
            <pattern>[%method] %msg%n</pattern>
        </encoder>
    </appender>
    <appender
        name="LOGCAT"
        class="ch.qos.logback.classic.android.LogcatAppender" >
        <tagEncoder>
            <pattern>%logger{0}</pattern>
        </tagEncoder>

        <encoder>
            <pattern>[%method] %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug" >
        <appender-ref ref="FILE" />
        <appender-ref ref="LOGCAT" />
    </root>
</configuration>
</logback>

そしてアクラの場合:

@ReportsCrashes(formKey = "dDB4dVRlTjVWa05T..........................",
                applicationLogFile = "applog.log",
                applicationLogFileLines = 150)

しかし、これにより次のようなエラーが発生するため、明らかに絶対パスが必要です。何を使えばいいですか?

java.io.FileNotFoundException: /applog.log: open failed: EROFS (Read-only file system)

最後の、少し関係のない質問ですが、[MyActivity@33c0d9d :: onCreate] などを表示する [%object :: %method] のようなオブジェクト アドレスを出力できるようにしたいと考えています。それを行う方法はありますか?

4

2 に答える 2

0

別の回避策があります。

ACRAソース、ファイルLogFileCollector.javaを見てください。次の方法でアプリケーション ログ ファイルを開きます。

if (fileName.contains("/")) {
    reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)), 1024);
} else {
    reader = new BufferedReader(new InputStreamReader(context.openFileInput(fileName)), 1024);
}

ログメッセージを保存するために context.openFileOutput を使用し、ACRA 構成でパスなしでログファイル名を指定することができます。つまり、ログ ファイル クラスは次のように宣言できます。

public class LogOnDisk {
    public static final String LOG_FILE_NAME = "custom_log";
    private final java.io.FileOutputStream _FS;
    private final java.io.PrintStream _PS;
    public LogOnDisk(Context context) throws IOException {
        _FS = context.openFileOutput(LOG_FILE_NAME, Context.MODE_PRIVATE);
        _PS = new PrintStream(_FS);
    }

    public synchronized void toLog(String message) {
        try {           
            _PS.print(message + "\n");
            _PS.flush();
        } catch (Exception ex) {
            //nothing to do
        }
    }       
}

ACRA 構成:

@ReportsCrashes(applicationLogFile = LogOnDisk.LOG_FILE_NAME)
public final class Kernel extends Application {
于 2012-12-16T07:25:18.863 に答える
0

これは解決策ではなく、代替案です。

独自のログ レイヤーがある場合は、最後の 50/100/500 ログ メッセージを循環バッファーに格納し、クラッシュが発生したときにそれを ACRA に提供できます。

循環バッファ実装の例:

public static final class LogRingBuffer {
    public static final int CAPACITY = 150;
    private String[] buffer = new String[CAPACITY];
    private int position = 0;
    private boolean full = false;
    public synchronized void append(String message) {cost of sync
        buffer[position] = message;
        position = (position+1)%CAPACITY;
        if (position==0) {
            full = true;
        }
    }

    public synchronized int size() {
        return full?CAPACITY:position;
    }

    public synchronized String get(int i) {
        return buffer[(position - i - 1 + CAPACITY) % CAPACITY];
    }
}

そして、ログ コンテンツをカスタム データ フィールドとして提供する必要があります。

int bcSize = Log.logBuffer.size();
for(int i=0; i<bcSize; ++i)
    reporter.addCustomData(String.format("LOG%03d", i), Log.logBuffer.get(i));

この後者のものは、ACRA 例外ハンドラーを囲む必要がある独自の例外ハンドラーに実装する必要があります...

これはばかげた単純ではないことは認めますが、DISK I/O と logback-android の使用を節約できます...

于 2012-11-13T12:44:03.043 に答える