[英]Logback-android and ACRA
I'm trying to set up my app so I can write logs using logback-android , and then send them to Google Docs using ACRA . 我正在尝试设置我的应用程序,以便我可以使用logback-android编写日志,然后使用ACRA将它们发送到Google Docs。 I think this is possible but the one issue I have, is where to write the logs. 我认为这是可能的,但我遇到的一个问题是在哪里写日志。
Both libraries need a hard-coded filename, so I can't use getStorageDirectory()
. 两个库都需要一个硬编码的文件名,所以我不能使用getStorageDirectory()
。 So, my first question is, where do the logs get written if you don't specify a full path? 所以,我的第一个问题是,如果你没有指定完整路径,那么日志会写在哪里? Do I have to specify a full path and hardcode it to /data/data/com.example/...
? 我是否必须指定完整路径并将其硬编码到/data/data/com.example/...
?
Here's my configuration: 这是我的配置:
<!-- 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>
And for acra: 对于acra:
@ReportsCrashes(formKey = "dDB4dVRlTjVWa05T..........................",
applicationLogFile = "applog.log",
applicationLogFileLines = 150)
But this gives errors like the following, so clearly I do need an absolute path. 但这会产生如下错误,所以显然我需要一个绝对路径。 What should I use? 我该怎么用?
java.io.FileNotFoundException: /applog.log: open failed: EROFS (Read-only file system)
Final, slightly unrelated question, I want to be able to print the object address, something like [%object :: %method] which would show [MyActivity@33c0d9d :: onCreate] or something similar. 最后,稍微不相关的问题,我希望能够打印对象地址,例如[%object ::%method],它会显示[MyActivity @ 33c0d9d :: onCreate]或类似的东西。 Is there any way to do that? 有没有办法做到这一点?
This is not a solution but an alternative. 这不是解决方案,而是替代方案。
If you have your own logging layer, you could just store the last 50/100/500 log messages in a circular buffer, and provide it to ACRA, when the crash occurs. 如果您有自己的日志记录层,则可以将最后的50/100/500日志消息存储在循环缓冲区中,并在发生崩溃时将其提供给ACRA。
Circular buffer impl example: 循环缓冲区impl示例:
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];
}
}
And then you have to provide log content as custom data fields: 然后,您必须提供日志内容作为自定义数据字段:
int bcSize = Log.logBuffer.size();
for(int i=0; i<bcSize; ++i)
reporter.addCustomData(String.format("LOG%03d", i), Log.logBuffer.get(i));
This latter one should be implemented in your own exception handler, that should surround ACRAs exception handler... 后一个应该在你自己的异常处理程序中实现,它应该包含ACRAs异常处理程序...
I admit, this is not stupid simple, but could save you some DISK I/O, and usage of logback-android... 我承认,这不是愚蠢的简单,但可以节省一些DISK I / O,并使用logback-android ...
There is another workaround. 还有另一种解决方法。
Take a look on ACRA sources, file LogFileCollector.java . 看看ACRA源代码,文件LogFileCollector.java 。 It opens application log file in a follow way: 它以下列方式打开应用程序日志文件:
if (fileName.contains("/")) {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)), 1024);
} else {
reader = new BufferedReader(new InputStreamReader(context.openFileInput(fileName)), 1024);
}
It's possible to use context.openFileOutput for saving log messages and specify log-file name without path in ACRA configuration. 可以使用context.openFileOutput来保存日志消息,并在ACRA配置中指定不带路径的日志文件名。 Ie log file class can be declared in follow way: 即日志文件类可以按以下方式声明:
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 configuration: ACRA配置:
@ReportsCrashes(applicationLogFile = LogOnDisk.LOG_FILE_NAME)
public final class Kernel extends Application {
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.