Java JNA解析windows事件日志记录中的描述字符串

Java JNA解析windows事件日志记录中的描述字符串,java,jna,event-log,Java,Jna,Event Log,我正在使用JNA读取应用程序交付的一些事件日志。我最感兴趣的是描述字符串数据 我正在使用下面的代码: private static void readLog() { Advapi32Util.EventLogIterator iter = new Advapi32Util.EventLogIterator("Application"); while (iter.hasNext()) { Advapi32Util.Even

我正在使用JNA读取应用程序交付的一些事件日志。我最感兴趣的是描述字符串数据

我正在使用下面的代码:

private static void readLog() {
        Advapi32Util.EventLogIterator iter = new Advapi32Util.EventLogIterator("Application");
        while (iter.hasNext()) {
            Advapi32Util.EventLogRecord record = iter.next();

            System.out.println("------------------------------------------------------------");
            System.out.println(record.getRecordNumber()
                    + ": Event ID: " + record.getInstanceId()
                    + ", Event Type: " + record.getType()
                    + ", Event Strings: " + Arrays.toString(record.getStrings())
                    + ", Data: " + record.getRecord().toString());
            System.out.println();
        }
    }
我的应用程序生成的事件示例:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>
        <Provider Name="Microsoft-Windows-MyApp" Guid="{4d5ae6a1-c7c8-4e6d-b840-4d8080b42e1b}" />
        <EventID>201</EventID>
        <Version>0</Version>
        <Level>2</Level>
        <Task>2</Task>
        <Opcode>30</Opcode>
        <Keywords>0x4010000001000000</Keywords>
        <TimeCreated SystemTime="2021-02-19T15:16:03.675690900Z" />
        <EventRecordID>3622</EventRecordID>
        <Correlation ActivityID="{e6ee2b3b-9b9a-4c9d-b39b-6c2bf2550000}" />
        <Execution ProcessID="2108" ThreadID="8908" />
        <Channel>Microsoft-Windows-MyApp/Operational</Channel>
        <Computer>computer</Computer>
        <Security UserID="S-1-5-20" />
    </System>
    <UserData>
        <EventInfo xmlns="aag">
            <Username>username</Username>
            <IpAddress>127.0.0.1</IpAddress>
            <AuthType>NTLM</AuthType>
            <Resource />
            <ConnectionProtocol>HTTP</ConnectionProtocol>
            <ErrorCode>23003</ErrorCode>
        </EventInfo>
    </UserData>
</Event>

201
0
2.
2.
30
0x40100000000
3622
Microsoft Windows MyApp/Operational
计算机
用户名
127.0.0.1
NTLM
超文本传输协议
23003
其他事件用户数据:

<UserData>
    <EventInfo xmlns="aag">
        <Username>otherUserName</Username>
        <IpAddress>10.235.163.52:50427</IpAddress>
    </EventInfo>
</UserData>

其他用户名
10.235.163.52:50427
JNA在
EVENTLOGRECORD
类中提供事件日志记录,该类仅包含仅获取描述字符串值的方法。如果我能得到XML格式的记录,我的问题就解决了。 UserData中的数据并不总是相同的,它包含不同的值,具体取决于事件类型。我想将数据从UserData部分解析到POJO(它可以是一个包含所有可用字段的POJO)。我不想使用字段顺序,因为有些事件有不同的字段(如示例所示)


有没有办法使用xml标记名来实现这一点?我会考虑切换到其他的Lang.< /P> < P>,正如我在我的评论中指出的,你需要进入XML。还指出JNA中的
WevtapiTest
test类中提供了一些示例代码

使用该测试类,我创建了下面的程序,该程序从系统日志中读取最近50个事件的XML。将事件筛选为所需内容留给读者作为练习

publicstaticvoidmain(字符串[]args){
EVT_HANDLE queryHandle=null;
//需要对日志进行提升或共享访问。
String path=“C:\\Windows\\System32\\Winevt\\Logs\\System.evtx”;
试一试{
queryHandle=Wevtapi.INSTANCE.EvtQuery(null,path,null,Winevt.EVT\u QUERY\u FLAGS.EvtQueryFilePath);
//一次阅读10个事件
int-eventArraySize=10;
int-evtNextTimeout=1000;
int-arrayIndex=0;
EVT_句柄[]事件数组=新的EVT_句柄[eventArraySize];
返回的IntByReference=新的IntByReference();
while(Wevtapi.INSTANCE.EvtNext(queryHandle,eventArraySize,eventArray,evtNextTimeout,0,返回)){
记忆增益;
//这只需要是0。从测试样本中保留相同的名称
IntByReference propertyCount=新的IntByReference();
Winevt.EVT_VARIANT evtVariant=新的Winevt.EVT_VARIANT();
for(int i=0;i=5){
打破
}
}
if(Kernel32.INSTANCE.GetLastError()!=WinError.ERROR\u成功
&&Kernel32.INSTANCE.GetLastError()!=WinError.ERROR\u无\u更多项目){
抛出新的Win32异常(Kernel32.INSTANCE.GetLastError());
}
}最后{
if(queryHandle!=null){
EvtClose(queryHandle);
}
}
}

这是否回答了您的问题?不幸的是,没有,因为来自Windows事件日志的事件不是由JNA liblary以XML格式提供的。它们存储在一个类中,该类表示名为
EVENTLOGRECORD
的单个日志记录。如果我能以xml的形式获得整个记录,我将毫无问题地解析它。问题是我无法将其作为XML阅读。啊,感谢您的澄清。我认为您需要获取XML表单。这可能需要在JNA中已经映射的WinAPI函数之外映射其他WinAPI函数。JNA在
EventLogRecord
类上有一个
getStrings()
方法,该方法提供了一个非结构化字符串数组,可能对某些用例有所帮助。实际上,快速查看JNA平台的代码库,我发现了
EventLogRecord
甚至是一个处理内存分配的包装
Util
版本。查看com.sun.jna.platform.win32.WevtapiTest.testReadEvents()可能会有更多帮助。啊,我错过了单独的Wevtapi映射集。那个测试班看起来确实很像我需要的。谢谢,这正是我需要的