Android 发送日志到 rsyslog

有人向三太爷表示需要这个功能。原本以为应该是很成熟有方案的,但找了一圈发现并没有,只好再多花点力气。原来一直以为 rsyslog 是 syslog 的 remote 版本,这次的信息拼凑过程中才发现是自己想当然了,r 是指 rocket。

既然 Android 上没有现成的,退而求其次,看 Java 实现的有没有。用 Java 实现这个功能的话,可能早些年会遇到 UDP 协议的网络通讯需要 JNI 辅助的问题,但这个问题应该在较新的 Java 中已经不存在才对。检索的结果并不乐观,因为找到的绝大多数都是 Java 一揽子 log 方案中的一个部分,牵扯杂乱。尽管如此,最后还是找到了一个实现,虽然已经是数年前就停更的。

接下来创建 Android 工程测试。又有个插曲。尽管老夫的工作机是 macOS、Ubuntu、Windows 三合一,但是有时候进入到某个系统的话,由于同时会打开很多软件,会导致执行重启切换系统成为一个心里阻碍。眼下的工作环境在 Windows 下,所以首先要弄个 syslog server 跑起来才能接收日志。安装试用了 Kiwi Syslog Server 9.7.1(个头最大,25MB+,上古的老土风格)、Fastvue Syslog Server 2.0、Ipswitch Syslog Server 1.0.0.59。其实还下载了 Syslog Watcher 5.1.0,但没有安装,它个头次大,有 20MB+。最后这个 Ipswitch Syslog Server 最好,留用。

敢于创建 Android 测试工程的底气来自于,大概翻看了一遍源代码,没有看到比较各色的、可能引起 Android 极度不适的玩意儿。编译过程肯定不是一帆风顺,有以下问题需要依次解决。

首先是两个注解,javax.annotation.Nonnulljavax.annotation.Nullable。Android 平台上没有,但有等价物。老一些的 Android 支持库里,是 android.support.annotation.NonNullandroid.support.annotation.Nullable,新的是 androidx.annotation.NonNullandroidx.annotation.Nullable。据此把 import 语句改掉,同时要注意到,非空注解的用词是不一样的,Java 是 Nonnull,而 Android 是 NonNull,因此还要把这些引用之处全改掉。到这儿,代码里的移植工作基本就已经完成。

但编译还会通不过。上述的注解需要引入库依赖:在 gradle 文件的 dependencies 节内增加 implementation 'com.android.support:support-annotations:28.0.0' 语句。

除此外还会有两个注解会产生问题,一个是 ThreadSafe 注解,另一个是 SuppressFBWarning 注解。也需要引入依赖:在 gradle 文件的 dependencies 节内增加 compileOnly 'com.google.code.findbugs:annotations:3.0.1'compileOnly 'com.google.code.findbugs:jsr305:3.0.2' 即可。参考解决方案来自于 https://stackoverflow.com/questions/39412365/what-to-import-to-use-suppressfbwarnings

由于引入的 com.android.support:support-annotationscom.google.code.findbugs:annotations 看上去就有重复之嫌,我编译时又把前者注释掉了,似乎也没有问题。

编译通过之后显然就是真正的测试了。界面上放了个按钮,点击后触发向本地 syslog 发送一条日志的操作。一开始发现初始化就会异常,经检查是没有在 manifest 里申明 internet 网络权限所致(有相同案例,见:https://www.cnblogs.com/lvlv/p/3629297.html)。继而发送操作也会引发异常,名为 NetworkOnMainThreadException。解决方案请参见 https://blog.csdn.net/mad1989/article/details/25964495。对于我来说,当然选择在 Activity 创建时增加这些代码了:

简单/看上去酷/有评论说有效。亲测有效。虽说别的方法才是正道,但对于一个 Demo App 来说,是不是要求太高了……

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注