注:本文代码是在网上的示例代码基础上修改的,本人可没法100%全自己开发。
Windows日志收集,而Logstash原本的eventlog插件,在调用WMI时有漏内存的问题,导致运行几天就挂了。没折只好自己开发下吧。
本人不是搞开发的,只在学生时代学过开发,对Jruby更是不了解,也就没找到Ruby里原生的库对WMI支持好的。好在Jruby可以调用Java库,好吧那咱就看看强大的Java里有没有好的库来使使。
上网一查,好多啊。有Java调用WMI的,也有就JNA、sigra直接读的,而且示例代码也是一大堆,那我就一个个试试吧。这过程也挺曲折。。。
开始,我先用JNA、sigra分别实现了读eventlog,但不完美。主要是这两个家伙读出来的是原始日志,与我们在事件管理器中看到的格式化好的日志不一样,好多都不能直接看懂。这种东东收集来对后面的分析会造成困难。看来还是要调用WMI来搞。
然后,我找了几个Java调用WMI的库,一个个试,经过各种不爽后终于感觉j-Interop库不错,那就它吧。在网上找到了j-Interop库读eventlog的示例代码,一跑结果是能显示日志了,也不漏内存。但所有的示例代码都是只完成了显示(按一个大字符串),而我是想将Win32_NTLogEvent单独取出成为对象,这样我就可以一个个的get其中的属性。但网上就是没有后面这步的示例,害我折腾几天。目前总算搞出来,所以就分享出来吧。以下是Java代码(我已经用下面的代码思路,转成了Jruby了而且在Logstash里跑的挺好):
package com.mytest;
import java.io.IOException;
import java.util.logging.Level;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.JIClsid;
import org.jinterop.dcom.core.JIComServer;
//import org.jinterop.dcom.core.JIProgId;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.core.JIString;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.impls.JIObjectFactory;
import org.jinterop.dcom.impls.automation.IJIDispatch;
public class EventLogListener {
private static JISession configAndConnectDCom(String domain, String user,
String pass) throws Exception {
JISystem.getLogger().setLevel(Level.OFF);
try {
JISystem.setInBuiltLogHandler(false);
} catch (IOException ignored) {
;
}
JISystem.setAutoRegisteration(true);
// JISession dcomSession = JISession.createSession(domain, user, pass);
JISession dcomSession = JISession.createSession(); //这个是直接用当前账号读,上面那行是用指定账号读
dcomSession.useSessionSecurity(true);
dcomSession.useNTLMv2(true);
return dcomSession;
}
private static IJIDispatch getWmiLocator(String host, JISession dcomSession)
throws Exception {
// JIComServer wbemLocatorComObj = new JIComServer(JIProgId
// .valueOf("WbemScripting.SWbemLocator"), host, dcomSession);
JIComServer wbemLocatorComObj = new JIComServer(
JIClsid.valueOf("76a64158-cb41-11d1-8b02-00600806d9b6"), host,
dcomSession);
return (IJIDispatch) JIObjectFactory.narrowObject(wbemLocatorComObj
.createInstance().queryInterface(IJIDispatch.IID));
}
private static IJIDispatch toIDispatch(JIVariant comObjectAsVariant)
throws JIException {
return (IJIDispatch) JIObjectFactory.narrowObject(comObjectAsVariant
.getObjectAsComObject());
}
private static S