关于LogStash运行在AIX 64位机器上的问题与临时解决方案
需求;logstash运行在SUSE,LINUX,PPC LINUX,AIX机器上,并监控文件发送日志到KAFKA中去,
问题:在AIX机器上,file插件总是报异常,无法完成数据的读取
NotImplementedError: stat.st_dev unsupported or native support failed to load
分析:环境 :AIX 64 OSLEVEL :6.1.0 7.1.0
JDK : IBM JAVA 71 64
报错显示:是在获取设备的主辅号时出了问题,显示没有实现的本地方法,没有详细的报错信息,
我同事细查相关的JAVA源码,一步一步地添加一些日志输出,找到了报错的具体原因.
我们看LOGSTASH的VENDOR JRUBY中就会发现,它的/vendor/jruby/lib/jni
下面没有 PPC64-AIX文件夹,所以具体报错的原因是没有找到相对应的JNI需要调用的本地库文件.
解决方案:
1.编译一份AIX-64位的LIB库文件放置到PPC64-AIX文件夹下
这个过程比较困难,相关的同事说做起来比较麻烦
2.临时解决方案,
使用32位的JDK,因为JRUBY自身带有32位的库文件,然后修改一个地方:
我们直接修改源码部分:
https://github.com/jnr/jnr-posix/blob/master/src/main/java/jnr/posix/POSIXFactory.java
中返回AIX类的固定让它反回32位的库文件.
case AIX:
return jnr.ffi.Runtime.getSystemRuntime().addressSize() == 4
? new String[] { "libc.a(shr.o)" }
: new String[] { "libc.a(shr_64.o)" };
写死成:return new String[]{"libc.a(shr.o)"}
重新编译,把编译后的类替换原来jruby.jar包中相关的class文件,重新打包即可.
jar cMf ../jruby.jar *
java 调用本地库文件来实现某些功能,JRUBY使用JNR/JFFI第三方提供的包来做这件事.