Skip to content

Commit

Permalink
doc: add debug notes (#794)
Browse files Browse the repository at this point in the history
Signed-off-by: spacewander <[email protected]>
  • Loading branch information
spacewander authored Nov 11, 2024
1 parent 018123a commit c258914
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 3 deletions.
2 changes: 1 addition & 1 deletion site/content/en/docs/concept/filterpolicy.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ This FilterPolicy contains a `targetRef`, which determines the kind of resource

The `sectionName` field is optional and is only effective when the `kind` is set to either VirtualService or Gateway.

* When it applies to VirtualService, it can be used to specify which particular Route under VirtualService it will be effective for. In this case, `sectionName` must match the `name` field of a Route under VirtualService.
* When it applies to VirtualService, it can be used to specify which route under the VirtualService it takes effect on. At this time, the sectionName needs to match the name field of a route under the VirtualService. Note that if multiple VirtualServices with the same domain name set routes with the same name, Istio will eventually generate multiple routes with the same name for that domain, leading to the FilterPolicy actually hitting another route with the same name on other VirtualServices. Therefore, for different VirtualServices under the same domain name, routes with the same name should be avoided.
* When it applies to Gateway, it can be used to specify which particular Server or Listener under Gateway it will be effective for. In this case, `sectionName` must match the `name` field of a Server under the istio Gateway or a Listener under the k8s Gateway. Note that since the policy at the Gateway level currently only applies at the port level, it is, in effect, applicable to the port where the matched Server or Listener is located.

For specific examples of using `sectionName`, see the following.
Expand Down
27 changes: 27 additions & 0 deletions site/content/en/docs/developer-guide/plugin_development.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,30 @@ A consumer plugin needs to meet the following conditions:
* Defines the `DecodeHeaders` method, and in this method, it calls `LookupConsumer` and `SetConsumer` to complete the setting of the consumer.

You can take the `keyAuth` plugin as an example to write your own consumer plugin.

## Why is my plugin not being executed?

First, ensure that the plugin has been loaded. Envoy will print the following log when loading the Go plugin:

```text
[plugins] "msg"="register plugin" "name"="casbin"
```

Second, when Envoy receives the Go plugin configuration and the log level is set to info or lower, it will print the following log:

```text
[2024-10-16 12:02:28.505][1][info][golang] [contrib/golang/common/log/cgo.cc:18] receive consumer configuration: {"auth":{"hmacAuth":"{\"accessKey\":\"ak\",\"secretKey\":\"sk\",\"signedHeaders\":[\"x-custom-a\"],\"algorithm\":\"HMAC_SHA256\"}","keyAuth":"{\"key\":\"rick\"}"}}
...
[2024-10-16 12:02:29.033][1][info][golang] [contrib/golang/common/log/cgo.cc:18] receive filtermanager config: {"namespace":"ns", "plugins":[{"config":{"keys":[{"name":"Authorization", "source":"HEADER"}, {"name":"ak", "source":"QUERY"}]}, "name":"keyAuth"}, {"config":{"deny_if_no_consumer":true}, "name":"consumerRestriction"}]}
```

Please check if it matches your expectations. The order of the plugins in the `filtermanager config` indicates the execution order of the plugins. If the plugin has been loaded and there is corresponding configuration info on the target route, but the plugin is not being executed, it may be because:

* The method definitions of the plugin do not meet expectations, for example, if the `DecodeRequest` method is defined but `DecodeHeaders` does not return `WaitAllData`.
* A plugin with a higher priority halted the request beforehand, such as a preceding authentication plugin returning 403.
* There may be a bug in HTNN.

You can check the executed plugins and their execution order through the following methods:

* Reduce the log level to debug, and we will see the specific plugin execution logs: `finish running plugin coverage, method: DecodeHeaders`.
* Set the debugMode plugin, and lower the slow threshold to 0. This way, each request will log the executed plugin information in the application logs.
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,17 @@ The test framework will occupy the following ports on the host machine:
* `:10000` for the Envoy proxy, which can be modified by the environment variable `TEST_ENVOY_DATA_PLANE_PORT`

For example, `TEST_ENVOY_CONTROL_PLANE_PORT=19999 go test -v ./tests/integration -run TestPluginXX` will use `:19999` as the control plane port.

## Debugging Failed Test Cases

The application logs and access logs of Envoy will be output to stdout, and can ultimately be found in `$test_dir/test-envoy/$test_name/stdout`.

If Envoy crashes on startup, it is usually because the ABI used by the Go shared library loaded does not match the Envoy started by the testing framework. In this case, it is necessary to set the `PROXY_IMAGE` environment variable to use the correct version of Envoy.

By default, the testing framework will use the `info` level for application logs. If you want to investigate unexpected behavior from Envoy, it is recommended to lower the log level to `debug`:

```go
dp, err := dataplane.StartDataPlane(t, &dataplane.Option{
LogLevel: "debug",
})
```
2 changes: 1 addition & 1 deletion site/content/zh-hans/docs/concept/filterpolicy.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ status:

`sectionName` 是可选的,仅在 `kind` 为 VirtualService 或 Gateway 时才生效。

* 当它作用于 VirtualService 时,可用于指定针对 VirtualService 下面的哪条路由生效。此时,`sectionName` 需要和 VirtualService 下面的某个路由的 `name` 字段匹配。
* 当它作用于 VirtualService 时,可用于指定针对 VirtualService 下面的哪条路由生效。此时,`sectionName` 需要和 VirtualService 下面的某个路由的 `name` 字段匹配。注意如果同一个域名的多个 VirtualService 都设置了同名的路由,那么 istio 最终也会给该域名生成多条同名的路由,导致 FilterPolicy 实际上会命中其他 VirtualService 上的同名路由。所以对于同一域名的不同 VirtualService,需要避免出现同名的路由。
* 当它作用于 Gateway 时,可用于指定针对 Gateway 下面的哪个 Server 或者 Listener 生效。此时,`sectionName` 需要和 istio Gateway 下面的某个 Server 的 `name` 字段抑或 k8s Gateway 下面的某个 Listener 的 `name` 字段匹配。注意因为目前 Gateway 级策略的粒度最细到端口级别,所以实际上针对匹配到的 Server 或 Listener 所在的端口生效。

使用 `sectionName` 的具体示例见下文。
Expand Down
27 changes: 27 additions & 0 deletions site/content/zh-hans/docs/developer-guide/plugin_development.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,30 @@ filter manager 实现了以下特性:
* 定义 `DecodeHeaders` 方法,且在该方法里调用 `LookupConsumer``SetConsumer` 完成消费者的设置。

您可以以 `keyAuth` 插件为例,编写自己的消费者插件。

## 为什么我的插件没有被执行

首先确保插件已经被加载。Envoy 在加载 Go 插件时会打印如下日志:

```text
[plugins] "msg"="register plugin" "name"="casbin"
```

其次,当 Envoy 收到 Go 插件配置时,且日志等级在 info 或以下时,会打印如下日志:

```text
[2024-10-16 12:02:28.505][1][info][golang] [contrib/golang/common/log/cgo.cc:18] receive consumer configuration: {"auth":{"hmacAuth":"{\"accessKey\":\"ak\",\"secretKey\":\"sk\",\"signedHeaders\":[\"x-custom-a\"],\"algorithm\":\"HMAC_SHA256\"}","keyAuth":"{\"key\":\"rick\"}"}}
...
[2024-10-16 12:02:29.033][1][info][golang] [contrib/golang/common/log/cgo.cc:18] receive filtermanager config: {"namespace":"ns", "plugins":[{"config":{"keys":[{"name":"Authorization", "source":"HEADER"}, {"name":"ak", "source":"QUERY"}]}, "name":"keyAuth"}, {"config":{"deny_if_no_consumer":true}, "name":"consumerRestriction"}]}
```

请检查和预期是否一致。其中 `filtermanager config` 里面的 plugins 里的插件顺序就是插件执行的顺序。如果插件已经加载,且在目标路由上有对应的配置信息,但是插件没有被执行,可能是因为:

* 插件的方法定义不合预期,比如定义了 `DecodeRequest` 方法但 `DecodeHeaders` 没有返回 `WaitAllData`
* 优先级在该插件之前的插件提前中止了请求,比如前面的认证插件返回 403。
* HTNN 的 bug。

可以通过以下方法查看具体执行的插件和执行顺序:

* 将日志等级降到 debug,我们将看到具体的插件执行日志: `finish running plugin coverage, method: DecodeHeaders`
* 设置 debugMode 插件,并将 slow threshold 降为 0。这样每个请求都会在应用日志中打印执行过的插件信息。
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,17 @@ title: 插件集成测试框架
* `:10000` 用于数据面,可通过环境变量 `TEST_ENVOY_DATA_PLANE_PORT` 修改

例如,`TEST_ENVOY_CONTROL_PLANE_PORT=19999 go test -v ./tests/integration -run TestPluginXX` 将使用 `:19999` 端口作为控制平面端口。

## 调试失败的测试用例

Envoy 的应用日志和访问日志都会输出到 stdout,最终被写入到 `$test_dir/test-envoy/$test_name/stdout` 中找到。

如果出现 Envoy 在启动时崩溃,通常是因为加载到 Go shared library 使用的 ABI 和测试框架启动的 Envoy 不一样。这种情况下需要通过设置 `PROXY_IMAGE` 环境变量来使用正确的 Envoy 版本。

默认情况下测试框架会使用 `info` 级别的应用日志。如果想要调查和预期不一样的 Envoy 行为,推荐把日志等级降到 `debug`

```go
dp, err := dataplane.StartDataPlane(t, &dataplane.Option{
LogLevel: "debug",
})
```
2 changes: 1 addition & 1 deletion tools/cmd/linter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ func lintFeatureMaturityLevel() error {
}

func main() {
// change to the root directory so that we don't need to worry about why this tool locates
// change to the root directory so that we don't need to worry about where this tool locates
os.Chdir("..")

type linter func() error
Expand Down

0 comments on commit c258914

Please sign in to comment.