如何解析包含XML数据的不断更新的日志?

如何解析包含XML数据的不断更新的日志?

在pastebin中添加了同样的问题:https://pastebin.com/QtZKcBic (我发现粘贴时缺少一些xml标签)

我需要从持续运行的日志中读取数据,该日志以毫秒为单位刷新,因为每分钟都会有数千人访问。我的要求是:

假设有一个这样的xml请求:

<dataReq>
  <id>1</id>
  <name>test</name>
  <reqId>ddaabyy234</reqid>
   ....
   ...
   ....
</dataReq>

上述请求的响应是:

<dataRes>
   <id>1</id>
   <dept>railway</dept>
   <reqId>ddaabyy234</reqid>
   .......
   .......
   <errcode>
       <errNum>404</errNum>
   </errcode>
 </dataRes>

如果<errNum>不是200,那么我需要捕获<dataReq>..</dataReq><dataRes>..</dataRes>

这里的问题是,可以有多个<dataReq>...</dataReq>标签。因为,为了生成响应,后端系统需要一些时间,同时许多用户将从 webUI(或)移动(或)应用程序发送请求到同一个应用程序。

日志还将每 5 分钟归档到归档文件中,因为日志文件的大小每 5 分钟就会变得巨大。

答案1

TXR语言其库中具有“尾流”功能:这些是跟随动态日志文件的流对象,与tail -f实用程序类似。

该函数调用(open-tail "/path/to/it")创建并返回尾流。该文件不必存在。如果文件确实存在,则流将读取它直到结束,然后监视它的增长、突然收缩或消失/重新出现,从而给应用程序带来平坦、永无止境的数据流的错觉。当然,应用程序必须足够快地从流中读取数据,这与文件轮换的频率有关。

在下面的程序中,我们定义一个数据结构来跟踪每个事务(请求-响应对)的信息,并使用尾流来扫描data使用 TXR 模式语言调用的日志文件。

当我们匹配请求时,我们创建一个新的交易对象并将其放入以 ID 为键的哈希表中。

当我们看到失败的响应(代码不是 200)时,我们会检索该 ID 的交易。如果存在,那么我们用响应信息更新它并打印它(使用对象的自定义打印函数重新生成 XML 请求-响应对)。

匹配响应后,无论成功与否,我们都会从哈希表中删除匹配的交易。

@(do                                                                        
   (defstruct xact nil
     id
     req-inner-xml
     res-inner-xml
     (:method print (me *stdout* pretty-p)
       (cond
         (pretty-p
           (put-line "<dataReq>")
           [mapdo put-line me.req-inner-xml]
           (put-line "</dataReq>")
           (put-line "<dataRes>")
           [mapdo put-line me.res-inner-xml]
           (put-line "</dataRes>"))
         (t :))))

   (defvarl xact (hash)))
@(next (open-tail "data"))
@(repeat)
@  (cases)
<dataReq>
@    (all)
  <id>@id</id>
@    (and)
@      (collect)
@lines
@      (until)
</dataReq>
@      (end)
@    (end)
@    (do (set [xact id] (new xact
                             id id
                             req-inner-xml lines)))
@  (or)
<dataRes>
@    (all)
   <id>@id</id>
@    (and)
@      (skip)
   <errcode>
       <errNum>@err</errNum>
   </errcode>
@    (and)
@      (collect)
@lines
@      (until)
</dataRes>
@      (end)
@    (end)
@    (do
       (whenlet ((x (del [xact id])))
         (when (nequal err "200")
           (set x.res-inner-xml lines)
           (pprint x))))
@  (end)
@(end)

相关内容