Http 如何使用ApacheTomcat Valve组件创建健壮的访问日志?
我们正在与ApacheTomcat7合作,并尝试设置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中的一个错误选项卡将损坏数据(该行看起来包含四个
pattern="%{yyyy-MM-dd}t	%{hh:mm:ss}t	%{User-Agent}i	"
问题是Valve组件(据我所知)没有逃逸%{User Agent}I
,因此useragent中的一个错误选项卡将损坏数据(该行看起来包含四个字段,而不是三个)
至于解决方案,除非有一种方法可以避开我错过的useragent,否则我可以看到两种解决方案:
;
?),但似乎不起作用AccessLogValve
,它要么支持转义,要么对选项卡进行消毒-可能类似于本文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并防止解析时出现任何歧义。