iRules 101 - #9 – 调试
既然你已经写好了你的第一个iRules :"Hello World",那么现在可以动手来写简单的、比如包含"when HTTP_RESPONSE" 或者 "HTTP::respond 200 content {Hello World}"的irules了,接下来还准备写一些更高级irules。不过,在此之前,首先你需要了解的是如何去调试这些你写的irules代码。本文将介绍几个调试技术,希望可以帮助你构建一个自检测的iRules 。
Logging
你可以用来武装你自己的第一个工具是是iRules的 “log”命令。它的语法如下:
log [<facility>.<level>] <message>
facility : "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"
level : "alert", "crit", "debug", "emerg", "err", "error", "info", "none", "notice", "panic", "warn", "warning"
facility 和 level这两个参数是可选的,你需要知道的是,当指定了这两个可选参数<facility>.<level>时,将对指令的执行带来显著的、不同的行为。当iRuels在写入log信息时,如果没有facility和/或level参数,则这些Log信息将会被分类并且被限速,也就是说,再限速的期间内,这些Log信息将会被压缩(合并)尽管他们是不同的文本。然而,当指定了facility和/或者level参数的时候,这些Log信息将不会被限速(尽管syslog-ng仍然会对重复的内容进行压缩)。
这两个参数的可选项有很多,幸运的是,只有在需要自定义一些特殊的Syslog-ng时才需要明确指定这两个参数,通常你只需要使用默认值就可以了,<facility>. 和<level>的默认值分别是”local0”和”error”。而事实上,我们已经简化了你的操作,你完全可以省略level 这个参数,因为我们会自动将它添加上。DevCentral中的每一个iRule ,几乎99%是使用下面的语法来记录log的,这种用法几乎可以满足所有需求。
log local0. "message goes here"
这样写的好处是确保记录日志信息时将不受到写入限制,可以直接写入日志文件,它们将被储存在系统的log文件: /var/log/ltm。
一个实际的例子
那些需要log,那些不需要log取决于你的iRule和你需要努力达到的目地。如果你想处理HTTP的请求,那么使用irules 的log记录一些输入信息是很好的做法,比如记录HTTP::host和HTTP::uri,记录一些临时的变量也是很好的想法,如果你需要处理这些字符串的话。让我们来看看下面的iRule:
when HTTP_REQUEST {
switch -glob [HTTP::uri] {
"/app1*" {
pool app1_pool
}
"*.gif" -
"*.jpg" {
pool images_pool
}
default {
pool def_pool
}
}
}
显而易见。上述irules中所有发送到应用程序“/app1”的请求将被发送到app1_pool中,所有访问扩展名为 “.gif”和“ .jpg”文件的请求将被发送到images_pool中,其余的所有请求将被发送到def_pool中。然而当我们测试这个irules时,会发现app1应用中的图片显示不出来。为什么呢?那么调试这个问题的方法是将iRules的逻辑判断元素记入日志记录中,以确定问题的根源。
首先想到的是查看Web服务器中有关image服务器的日志,检查为什么请求没有得到响应。让你惊讶的是,log中的记录显示并没有请求到达image服务器。那么接下来很明显我们需要调试一下iRule ,来仔细看看究竟什么原因导致了这个问题。下面是改后的irules:
when HTTP_REQUEST {
log local0. "Request: [HTTP::uri]"
switch -glob [HTTP::uri] {
"/app1*" {
log local0. "Sending request to app1_pool"
pool app1_pool
}
"*.gif" -
"*.jpg" {
log local0. "Sending request to images_pool"
pool images_pool
}
default {
log local0. "Sending request to def_pool"
pool def_pool
}
}
}
测试后,你会在log中看到像这样的记录:
... Request: /app1/index.html Sending request to app1_pool Request: /js/file.js Sending request to def_pool Request: /app1/smile.gif Sending request to app1_pool
根据上面的irules,你可能认为所有的图像文件的请求都应该被发送到images_pool中,但事实上他们却被发送到了app1_pool中。这是由于在irules中请求先匹配了“app1”,所以会将请求发送往app1_pool中的服务器中,而不会继续向后查找匹配项。现在,知道了这些信息以后,那么可以重新调整switch语句中的条件处理顺序,以确保所有对图片的请求发往images_pool中。调整后如下:
when HTTP_REQUEST {
log local0. "Request: [HTTP::uri]"
switch -glob [HTTP::uri] {
"*.gif" -
"*.jpg" {
log local0. "Sending request to images_pool"
pool images_pool
}
"/app1*" {
log local0. "Sending request to app1_pool"
pool app1_pool
}
default {
log local0. "Sending request to def_pool"
pool def_pool
}
}
}
现在好了,所有的图像都能正常显示了。正如你在日志中看到的内容:
... Request: /app1/index.html Sending request to app1_pool Request: /js/file.js Sending request to def_pool Request: /app1/smile.gif Sending request to images_poo
问题似乎解决了,所有的应用都能正常访问,并且图片也都能正常显示。大功告成了吗?错...
删除调试用的log
logging是调试过程中一个很有用的工具,甚至可以确定服务器上发生的一些问题。但是,系统磁盘只有这么大,而使用log命令记录日志信息会占用一定的空间,在大多数情况下,应该将调试用的logging disable。可以采取多种方式来实现。
1、第一种方法:在iRule中将调试用的log命令删除。这是最简单的方法,只要删除log命令那一行,然后保存便可以了。这样做可以简化你的iRule 并且更易于阅读。
2、 第二种方法:使用注释符:“#”符号注释掉log命令。这样做的好处是:当你需要调试一个新的应用错误时,你可以轻松地恢复这些日志命令,只需要删除掉“#”符号取消对日志的注释,单击保存,便可以回到以前的状态了。
3、 第三种方法:使用全局变量来控制日志命令。具体是现实通过if语句判断变量的值,这样就可以像使用变量一样来启用或禁用log命令。上述iRule可以这样写:
when HTTP_REQUEST {
set DEBUG 1
if { $DEBUG } { log local0. "Request: [HTTP::uri]" }
switch -glob [HTTP::uri] {
"*.gif" -
"*.jpg" {
if { $DEBUG } { log local0. "Sending request to images_pool" }
pool images_pool
}
"/app1*" {
if { $DEBUG } { log local0. "Sending request to app1_pool" }
pool app1_pool
}
default {
if { $DEBUG } { log local0. "Sending request to def_pool" }
pool def_pool
}
}
}
这样,可以通过设置DEBUG 变量的值为1来启用logging或者为0来关闭loging。使用那种方法完全取决于你的实际环境。第一种方法和第二种方法不会占用CPU来处理log程序,但第三种方法会进行一次布尔类型变量的检测。如果面对成百上千的请求 ,这也是不容忽视的。
总结
最后,首先要牢记在心的logging工具是个很好的助手。你应该养成使用它来调试你的irules的习惯,这样可以加快iRules开发的问题分析速度。但不要忘记在将iRules放到生产环境的时候将那些调试命令注释掉,这样避免你把BIG-IP的文件系统充满。
Published Feb 02, 2009
Version 1.0ltwagnon
Ret. Employee
Joined May 15, 2019
ltwagnon
Ret. Employee
Joined May 15, 2019
No CommentsBe the first to comment
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)