Statistics 学习/检测日志中URL的可变部分

Statistics 学习/检测日志中URL的可变部分,statistics,analysis,logparser,Statistics,Analysis,Logparser,假设您有一个web服务器日志(apache、nginx等)。您可以从中提取大量URL: /article/1/view /article/2/view /article/1/view /article/1323/view /article/1/edit /help /article/1/view /contact /contact/thank-you /article/8/edit ... 或 您将这些URL分解成不同的部分,这样您就有了['article'、'1323'、'view']或['

假设您有一个web服务器日志(apache、nginx等)。您可以从中提取大量URL:

/article/1/view
/article/2/view
/article/1/view
/article/1323/view
/article/1/edit
/help
/article/1/view
/contact
/contact/thank-you
/article/8/edit
...

您将这些URL分解成不同的部分,这样您就有了['article'、'1323'、'view']或['blog'、'2012'、'08'、'30'、'how-i-wasted-my-summer-vacation']

如何分析和比较这些url,以检测和调用url路径中的“变量”。也就是说,您需要识别诸如
/article/XXX/view
/article/XXX/edit
、和
/blog/XXX/XXX/XXX/XXX
之类的内容,以便您可以在日志中总结关于这些行的信息

我假设,对于构成可变片段与外观相似但不同的模板的差异数量,需要有一些统计阈值。我也不确定什么样的数据结构可以使分析变得快速和简单


我希望脚本的输出输出它认为是服务器上存在的所有url模板,如果合适的话,可能会有一些置信值。

一个简单的解决方案是计算路径出现的次数,并了解哪些值对应于模板。假设文件
input
包含来自第一个代码段的URL。然后计算每路径访问次数:

awk -F '/' '{ for (i=2; i<=NF; ++i) { for (j=2; j<=i; ++j) printf "/%s", $j; printf "\n" }}' input \
    | sort \
    | uniq -c \
    | sort -rn
现在你有了每条路径的权重,你可以把它输入到分数函数f(x,y),其中x代表路径的计数,y代表路径的深度。例如,第一行将导致调用f(7,2),并可能返回[0,1]中的值,例如0.8,以告诉您给定的参数化对应于80%的模板。当然,所有的魔法都发生在f中,你必须根据你看到的被访问的路径给出合理的值。为了得到一个好的f,你可以在一些小数据集上使用逻辑回归,看看它是否能很好地预测作为模板的二元特征

你也可以走一条普通的路线:只需放下尾巴,例如,所有值使用一个?除了节点存储的不是字母,而是URI片段。像这样:

这是一个非常好的数据结构:它的内存需求非常小,很容易遍历,而且,作为一个DAG,有很多简单且经过充分研究的算法。它也恰巧描述了一个状态机,它接受样本中的所有URL并拒绝所有其他URL(因此我们实际上可以用它构建一个正则表达式,这非常简洁,但我还不知道如何从那里开始)

无论如何,有了这样的结构,你的问题就转化为寻找“瓶颈”。我想有合适的算法,但是对于一个足够大的样本,变量变化很大,基本上是这样的:在某个深度的节点越多,就越有可能是可变的部分

一个可能很天真的方法是这样的:为每个起始部分保留单独的DAWG,我会找到DAWG的平均宽度(可能基于深度加权)。如果一个级别的宽度高于那个意思,我会认为它是一个变量,它的概率取决于它离平均值有多远。在这一点上,你很可能会释放统计的力量。对宽度的分布进行建模

这种方法不适用于以相同部分开始的独立模式,如“shop/?/?”和“shop/admin/?/edit”。这也许可以通过以更动态的方式检查DAWG-s来缓解,使用滑动窗口,总是一次只检查DAWG的一部分,但我不知道怎么做。哦,如果第一部分是一个变量,那么整个过程都会失败,但谢天谢地,这很少见

您还可能会注意某些小事情,例如相同级别的所有节点都有数值(更可能是一个变量),在构建DAWG之前,我肯定会检查示例中的常见日期模式,将它们分解会使处理类似博客的模式更容易


(哦,加上“algorithm”标签可能会吸引更多的注意力。)

这让我有了一个很好的起点。我必须小心,我的词干分析器不会创建不存在的URL。如果输入是“/a/1/view”和“/b/1”,像这样一个简单的DAWG将允许“/b/1/view”出现,但我想我已经涵盖了它。谢谢
awk -F '/' '{ for (i=2; i<=NF; ++i) { for (j=2; j<=i; ++j) printf "/%s", $j; printf "\n" }}' input \
    | sort \
    | uniq -c \
    | sort -rn
7 /article
4 /article/1
3 /article/1/view
2 /contact
1 /help
1 /contact/thank-you
1 /article/8/edit
1 /article/8
1 /article/2/view
1 /article/2
1 /article/1323/view
1 /article/1323
1 /article/1/edit