Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 如何使用ApacheTomcat Valve组件创建健壮的访问日志?_Http_Tomcat_Http Headers - Fatal编程技术网

Http 如何使用ApacheTomcat Valve组件创建健壮的访问日志?

Http 如何使用ApacheTomcat Valve组件创建健壮的访问日志?,http,tomcat,http-headers,Http,Tomcat,Http Headers,我们正在与ApacheTomcat7合作,并尝试设置Valve组件来存储访问日志,以便在中进行处理 我们面临的问题是如何使这些日志变得健壮。举个例子-我们可以用制表符分隔字段并提取用户代理字符串,如下所示: pattern="%{yyyy-MM-dd}t	%{hh:mm:ss}t	%{User-Agent}i	" 问题是Valve组件(据我所知)没有逃逸%{User Agent}I,因此useragent中的一个错误选项卡将损坏数据(该行看起来包含四个

我们正在与ApacheTomcat7合作,并尝试设置Valve组件来存储访问日志,以便在中进行处理

我们面临的问题是如何使这些日志变得健壮。举个例子-我们可以用制表符分隔字段并提取用户代理字符串,如下所示:

pattern="%{yyyy-MM-dd}t	%{hh:mm:ss}t	%{User-Agent}i	"
问题是Valve组件(据我所知)没有逃逸
%{User Agent}I
,因此useragent中的一个错误选项卡将损坏数据(该行看起来包含四个字段,而不是三个)

至于解决方案,除非有一种方法可以避开我错过的useragent,否则我可以看到两种解决方案:

  • 使用真正模糊的字段分隔符(或字段分隔符的组合),这不太可能出现在useragent字符串中。我们尝试了Ctrl-A(HTML
    ;
    ?),但似乎不起作用
  • 编写一个自定义的
    AccessLogValve
    ,它要么支持转义,要么对选项卡进行消毒-可能类似于本文
  • 我在网上找不到关于这个的任何其他信息,这让我有点困惑——难道没有人解析他们的Tomcat访问日志吗

    你推荐什么?我们有点卡住了…

    将用户代理字符串定义为

    User-Agent     = "User-Agent" ":" 1*( product | comment )
    
    那么产品的定义是

    product         = token ["/" product-version]
    product-version = token
    
    token          = 1*<any CHAR except CTLs or separators>
    
    comment    = "(" *( ctext | quoted-pair | comment ) ")" 
    ctext      = <any TEXT excluding "(" and ")">
    quoted-pair    = "\" CHAR
    CHAR           = <any US-ASCII character (octets 0 - 127)>
    
    在此之后,令牌被定义为

    product         = token ["/" product-version]
    product-version = token
    
    token          = 1*<any CHAR except CTLs or separators>
    
    comment    = "(" *( ctext | quoted-pair | comment ) ")" 
    ctext      = <any TEXT excluding "(" and ")">
    quoted-pair    = "\" CHAR
    CHAR           = <any US-ASCII character (octets 0 - 127)>
    
    因此,如果我理解正确,您应该能够使用任何
    分隔符
    CTL
    ,只要您能够区分
    注释
    ,它被包装在
    中。如果
    出现在注释中,则应使用
    \

    进行转义。最后,我写了一个:

    • 引入了一个新模式“I”,以转义传入的头
    • 引入了一个新模式“C”,以获取存储在响应上的cookie
    • 重新实现模式“i”,以确保将“”(空字符串)替换为“-”
    • 重新实现模式“q”以删除“”,并确保将“”(空字符串)替换为“-”
    • 重写“v”模式,以写入此AccessLogValve的版本,而不是本地服务器名称

    它看起来相当健壮-我没有遇到任何关于未替换值的问题。

    非常感谢您的回答@mindas,尽管我不确定我是否完全理解它。您是说我们应该只希望所有访问我们网站的用户代理都符合RFC2616,还是说Tomcat有一个拒绝非RFC261的机制6兼容的标题?我希望主要浏览器尊重RFC,但谁知道呢?因为您可以访问大量日志,所以最好编写一些脚本来测试是否有恶意UAs设法潜入。另一种方法是将日志序列化到某个NoSQL存储区而不是文本文件。这样,UA将位于单独的列中n并防止解析时出现任何歧义。