在上篇的Loki操作方法系列中,我已经分享了创建快速过滤器查询的所有最佳技巧,这些查询可以在几秒钟内过滤掉TB级的数据。

在本篇中,我将介绍如何在Loki的LogQL中正确转义字符串中的特殊字符。

在编写LogQL查询时,可能已经意识到,我们必须在多个地方编写用双引号分隔的字符串。对于标签匹配器,行过滤器,正则表达式和标签过滤器来说,这是没问题的,我们也在很多地方都使用双引号字符串。

但是,当我们突然想要过滤包含双引号的行时,就会出现问题。例如,下面这条查询语句

{namespace="loki-ops",container="query-frontend"} |= """

{namespace="loki-ops",container="query-frontend"} |= """

Logql将返回解析错误,因为Loki认为没有关闭双引号字符串。

这是另一个示例:这次我们假装正在研究Windows容器。在这种查询中也是相同的结果……

{namespace="dev",container="win-broker"} |= "c:\Users\test\null"

{namespace="dev",container="win-broker"} |= "c:\Users\test\null"

这将导致一个错误,因为\U\t\n被认为是特殊字符。

因此,我们需要转义那些特殊字符。转义的方法是\在特殊字符前面使用

{namespace="loki-ops",container="query-frontend"} |= "\”"
{namespace="dev",container="win-broker"} |= "c:\\Users\\test\\null"

{namespace="loki-ops",container="query-frontend"} |= "\”"
{namespace="dev",container="win-broker"} |= "c:\\Users\\test\\null"

最后但并非最不重要的,做的正则表达式时,还有更特殊字符(\.+?,等)在起作用。例如,如果要匹配数字\d或点.,则还需要对它们进行转义。

因此,如果要提取IP地址,查询将如下所示:

{namespace="grafana-com",container="nginx"} |= "/observabilitycon" != "assets" |  regexp "(?P\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"
{namespace="grafana-com",container="nginx"} |= "/observabilitycon" != "assets" |  regexp "(?P\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"

这有很多\,而且很容易混淆。

但好消息是,在Loki中有一个更酷的方法来做到这一点!我们可以使用所谓的原始字符串,不需要转义。原始字符串以反引号(```)引起来的字符串。

上面的三个示例使用原始字符串更简单:

{namespace="loki-ops",container="query-frontend"} |= `"`
{namespace="dev",container="win-broker"} |= `c:\Users\test\null`
{namespace="grafana-com",container="nginx"} |= "/observabilitycon" != "assets" |  regexp `(?P\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})`
{namespace="loki-ops",container="query-frontend"} |= `"`
{namespace="dev",container="win-broker"} |= `c:\Users\test\null`
{namespace="grafana-com",container="nginx"} |= "/observabilitycon" != "assets" |  regexp `(?P\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})`

唯一使用原始字符串的问题是,如果您实际上需要转义像反引号(`)这样的字符,因为它标志着原始字符串的结尾和开始,所以它并不有效。因此,在这种情况下,我们必须使用字符串。

nginx特殊字符替换 nginx特殊字符过滤_nginx过滤特殊字符