mirror of
https://github.com/hengyoush/kyanos.git
synced 2025-12-20 01:03:46 +08:00
docs: add debug tips doc (#240)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { defineConfig } from 'vitepress'
|
||||
import { defineConfig } from "vitepress";
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
@@ -6,57 +6,64 @@ export default defineConfig({
|
||||
description: "Kyanos official website",
|
||||
head: [["link", { rel: "icon", href: "/kyanos.png" }]], // 浏览器标签页logo
|
||||
locales: {
|
||||
cn: { label: '简体中文', lang: 'cn' },
|
||||
root: { label: 'English', lang: 'en' },
|
||||
cn: { label: "简体中文", lang: "cn" },
|
||||
root: { label: "English", lang: "en" }
|
||||
},
|
||||
appearance: 'dark',
|
||||
appearance: "dark",
|
||||
themeConfig: {
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
logo: "/kyanos.png",
|
||||
nav: [
|
||||
{ text: 'Home', link: '/' },
|
||||
{ text: 'Guide', link: './what-is-kyanos' }
|
||||
{ text: "Home", link: "/" },
|
||||
{ text: "Guide", link: "./what-is-kyanos" }
|
||||
],
|
||||
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Introduction',
|
||||
text: "Introduction",
|
||||
items: [
|
||||
{ text: 'What is Kyanos?', link: './what-is-kyanos' },
|
||||
{ text: 'Quickstart', link: './quickstart' },
|
||||
{ text: 'FAQ', link: './faq' },
|
||||
{ text: "What is Kyanos?", link: "./what-is-kyanos" },
|
||||
{ text: "Quickstart", link: "./quickstart" },
|
||||
{ text: "FAQ", link: "./faq" }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Tutorial',
|
||||
text: "Tutorial",
|
||||
items: [
|
||||
|
||||
{ text: 'Learn kyanos in 5 minutes', link: './how-to' },
|
||||
{ text: 'How to use watch', link: './watch' },
|
||||
{ text: 'How to use stat', link: './stat' },
|
||||
{ text: "Learn kyanos in 5 minutes", link: "./how-to" },
|
||||
{ text: "How to use watch", link: "./watch" },
|
||||
{ text: "How to use stat", link: "./stat" }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Development',
|
||||
text: "Development",
|
||||
items: [
|
||||
|
||||
{ text: 'How to build', link: './how-to-build' },
|
||||
{ text: 'How to add a new protocol', link: './how-to-add-a-new-protocol' },
|
||||
{ text: "How to build", link: "./how-to-build" },
|
||||
{
|
||||
text: "How to add a new protocol",
|
||||
link: "./how-to-add-a-new-protocol"
|
||||
},
|
||||
{
|
||||
text: "Debug Tips",
|
||||
link: "./debug-tips"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/hengyoush/kyanos' }
|
||||
{ icon: "github", link: "https://github.com/hengyoush/kyanos" }
|
||||
],
|
||||
|
||||
|
||||
footer: {
|
||||
message: 'Released under the <a href="https://github.com/hengyoush/kyanos/blob/main/LICENSE">Apache-2.0 license.',
|
||||
copyright: 'Copyright © 2024-present <a href="https://github.com/hengyoush">Hengyoush'
|
||||
message:
|
||||
'Released under the <a href="https://github.com/hengyoush/kyanos/blob/main/LICENSE">Apache-2.0 license.',
|
||||
copyright:
|
||||
'Copyright © 2024-present <a href="https://github.com/hengyoush">Hengyoush'
|
||||
},
|
||||
|
||||
|
||||
search: {
|
||||
provider: 'local'
|
||||
},
|
||||
provider: "local"
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Theme from "vitepress/theme";
|
||||
import "./style/index.css";
|
||||
export default {
|
||||
...Theme,
|
||||
};
|
||||
...Theme
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
@import "./var.css"
|
||||
@import "./var.css";
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
:root {
|
||||
/* 标题 */
|
||||
--vp-home-hero-name-color: transparent;
|
||||
/* 渐变色 */
|
||||
--vp-home-hero-name-background: linear-gradient(
|
||||
135deg,
|
||||
#76fddd 10%,
|
||||
#bbe2fe 100%
|
||||
);
|
||||
/* 纯色 */
|
||||
/* --vp-home-hero-name-background: red; */
|
||||
--vp-home-hero-image-background-image: linear-gradient(
|
||||
135deg,
|
||||
#bbe2fe 10%,
|
||||
#76fddd 100%
|
||||
);
|
||||
/* 设置模糊度 */
|
||||
--vp-home-hero-image-filter: blur(150px);
|
||||
}
|
||||
/* 标题 */
|
||||
--vp-home-hero-name-color: transparent;
|
||||
/* 渐变色 */
|
||||
--vp-home-hero-name-background: linear-gradient(
|
||||
135deg,
|
||||
#76fddd 10%,
|
||||
#bbe2fe 100%
|
||||
);
|
||||
/* 纯色 */
|
||||
/* --vp-home-hero-name-background: red; */
|
||||
--vp-home-hero-image-background-image: linear-gradient(
|
||||
135deg,
|
||||
#bbe2fe 10%,
|
||||
#76fddd 100%
|
||||
);
|
||||
/* 设置模糊度 */
|
||||
--vp-home-hero-image-filter: blur(150px);
|
||||
}
|
||||
|
||||
77
docs/cn/debug-tips.md
Normal file
77
docs/cn/debug-tips.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Debug Tips
|
||||
|
||||
## 构建相关
|
||||
|
||||
注意每次修改eBPF相关代码后都需要使用`make build-bpf`重新生成一些bpf相关代码,然后再用`make`构建或者在IDE里调试。
|
||||
|
||||
使用 `kyanos-debug` 来构建带有调试信息的二进制文件, 以便更好地进行调试。
|
||||
|
||||
```sh
|
||||
make kyanos-debug
|
||||
```
|
||||
|
||||
## 日志相关
|
||||
|
||||
启动kyanos开启日志,日志分为几个模块可分别开启,5为debug级别,默认是warn级别。如下是每个模块的日志选项:
|
||||
|
||||
| 参数 | 含义 |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| --agent-log-level | 指定agent模块日志级别,主要是和Agent启动等相关的日志 |
|
||||
| --bpf-event-log-level | 指定bpf事件日志级别,一些内核上报的和syscall层上报的事件会打印出来 |
|
||||
| --conntrack-log-level | 指定conntrack模块日志级别,一些连接相关的事件比如连接创建、协议推断、连接关闭等会打印出来 |
|
||||
| --protocol-log-level | 指定协议模块日志级别,主要是具体协议解析相关的日志 |
|
||||
| --uprobe-log-level | 指定uprobe模块日志级别,主要是和ssl探针相关的日志 |
|
||||
|
||||
比如如果你在调试协议解析相关部分的代码建议加上:`--bpf-event-log-level 5 --conntrack-log-level 5 --protocol-log-level 5`。
|
||||
|
||||
如果你碰到eBPF代码加载失败的情况,可以加上`--agent-log-level 5`日志打印一些Agent启动时的日志。
|
||||
|
||||
日志输出默认到/tmp下,加上 `--debug-output`
|
||||
选项可以让日志输出到标准输出,而且不再展示tui会展示的表格,抓取到的请求都会直接输出到控制台:
|
||||
|
||||
```
|
||||
WARN[0023] [ Request ]
|
||||
GET /health HTTP/1.1
|
||||
Host: :8080
|
||||
User-Agent: Go-http-client/1.1
|
||||
Accept-Encoding: gzip
|
||||
|
||||
[ Response ]
|
||||
HTTP/1.1 200 OK
|
||||
Date: Wed, 01 Jan 2025 16:20:20 GMT
|
||||
Content-Length: 2
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
|
||||
OK
|
||||
|
||||
[conn] [pid=2252][local addr]=127.0.0.1:8080 [remote addr]=127.0.0.1:38664 [side]=server [ssl]=false
|
||||
[total duration] = 0.423(ms)(start=2025-01-02 00:20:20.095, end=2025-01-02 00:20:20.095)
|
||||
[read from sockbuf]=0.296(ms)
|
||||
[process internal duration]=0.078(ms)
|
||||
[syscall] [read count]=1 [read bytes]=92 [write count]=1 [write bytes]=118
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> 调试协议解析相关代码时可以使用:`--bpf-event-log-level 5 --conntrack-log-level 5 --protocol-log-level 5 --debug-output`
|
||||
> 选项就基本上足够了。
|
||||
|
||||
## 源码结构
|
||||
|
||||
```
|
||||
> agent
|
||||
> analysis (聚合分析模块,stat命令用到)
|
||||
> conn (连接跟踪模块)
|
||||
> protocol(协议解析模块)
|
||||
> render(TUI渲染模块)
|
||||
> uprobe(uprobe相关主要是ssl探针)
|
||||
> bpf
|
||||
> loader (bpf 程序加载逻辑)
|
||||
pktlatency.bpf.go (内核态核心代码,包括系统调用和内核部分的事件上报等逻辑)
|
||||
gotls.bpf.go (gotls探针相关)
|
||||
protocol_inference.h (协议推断相关)
|
||||
openssl* (openssl相关)
|
||||
> cmd (命令行相关)
|
||||
> common (一些工具类)
|
||||
> docs (基于vitepress的文档)
|
||||
```
|
||||
@@ -85,12 +85,12 @@ type ParsedMessage interface {
|
||||
}
|
||||
```
|
||||
|
||||
| 方法名 | 作用 |
|
||||
| ------------------ | ------------------------------------------------------------------------ |
|
||||
| `FormatToString()` | 将消息格式化为字符串表示形式。 |
|
||||
| `TimestampNs()` | 返回消息的时间戳(以纳秒为单位)。 |
|
||||
| `ByteSize()` | 返回消息的字节大小。 |
|
||||
| `IsReq()` | 判断消息是否为请求。 |
|
||||
| 方法名 | 作用 |
|
||||
| ------------------ | -------------------------------------------------------------------------- |
|
||||
| `FormatToString()` | 将消息格式化为字符串表示形式。 |
|
||||
| `TimestampNs()` | 返回消息的时间戳(以纳秒为单位)。 |
|
||||
| `ByteSize()` | 返回消息的字节大小。 |
|
||||
| `IsReq()` | 判断消息是否为请求。 |
|
||||
| `Seq()` | 返回消息的字节流序列号, 可以从 `streamBuffer.Head().LeftBoundary()` 获取。 |
|
||||
|
||||
HTTP 的例子:
|
||||
@@ -137,10 +137,11 @@ ParseStream(streamBuffer *buffer.StreamBuffer, messageType MessageType) ParseRes
|
||||
|
||||
注意 eBPF 数据事件可能会无序到达,或者丢失事件,因此数据缓冲区中的数据可能缺少数据块,参数 streamBuffer 中通过
|
||||
`streamBuffer.Head`
|
||||
函数获取到目前为止已接收到的缓冲区前面的所有连续数据。因此,此时 **无法保证数据有效或缓冲区与数据包的开头对齐**。
|
||||
函数获取到目前为止已接收到的缓冲区前面的所有连续数据。因此,此时
|
||||
**无法保证数据有效或缓冲区与数据包的开头对齐**。
|
||||
|
||||
如果返回 `ParseResult` 中的 `state` 为
|
||||
`success`,且那么 kyanos 会自动删除掉 `ParseResult.ReadBytes` 个字节的数据;如果返回 `invalid`,那么通过
|
||||
如果返回 `ParseResult` 中的 `state` 为 `success`,且那么 kyanos 会自动删除掉
|
||||
`ParseResult.ReadBytes` 个字节的数据;如果返回 `invalid`,那么通过
|
||||
`FindBoundary` 找到下一个可能的 `Message` 边界;如果返回
|
||||
`needsMoreData`,则不会删除数据,而是稍后重试。
|
||||
|
||||
@@ -242,7 +243,8 @@ func init() {
|
||||
|
||||
## Step.6-添加 e2e 测试
|
||||
|
||||
在 testdata 目录下添加对应协议的 e2e 测试,可以参考其他协议的写法(比如 `test_redis.sh` 等)。
|
||||
在 testdata 目录下添加对应协议的 e2e 测试,可以参考其他协议的写法(比如
|
||||
`test_redis.sh` 等)。
|
||||
|
||||
## 其他
|
||||
|
||||
@@ -252,7 +254,9 @@ func init() {
|
||||
`common.ProtocolParserLog`. 打开 protocol 解析日志:`--protocol-log-level 5`
|
||||
设置协议解析相关 log 日志为 debug 级别。
|
||||
|
||||
协议解析框架代码在 conntrack.go 的 `addDataToBufferAndTryParse` 函数里。
|
||||
协议解析框架代码在 conntrack.go 的 `addDataToBufferAndTryParse` 函数里。
|
||||
|
||||
更多调试建议参考:[Debug Tips](./debug-tips)
|
||||
|
||||
### 协议解析持久化信息
|
||||
|
||||
|
||||
87
docs/debug-tips.md
Normal file
87
docs/debug-tips.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Debug Tips
|
||||
|
||||
## Build Related
|
||||
|
||||
Note that every time you modify the eBPF-related code, you need to use
|
||||
`make build-bpf` to regenerate some bpf-related code, and then use `make` to
|
||||
build or debug in the IDE.
|
||||
|
||||
Use `kyanos-debug` to build binary files with debug information for better
|
||||
debugging.
|
||||
|
||||
```sh
|
||||
make kyanos-debug
|
||||
```
|
||||
|
||||
## Log Related
|
||||
|
||||
Start kyanos with logging enabled. Logs are divided into several modules that
|
||||
can be enabled separately. Level 5 is the debug level, and the default is the
|
||||
warn level. The following are the log options for each module:
|
||||
|
||||
| Parameter | Meaning |
|
||||
| --------------------- | -------------------------------------------------------------------------------------- |
|
||||
| --agent-log-level | Specify the log level for the agent module, mainly related to Agent startup logs |
|
||||
| --bpf-event-log-level | Specify the log level for bpf events, logs related to kernel and syscall layer events |
|
||||
| --conntrack-log-level | Specify the log level for the conntrack module, logs related to connection events |
|
||||
| --protocol-log-level | Specify the log level for the protocol module, mainly related to protocol parsing logs |
|
||||
| --uprobe-log-level | Specify the log level for the uprobe module, mainly related to ssl probe logs |
|
||||
|
||||
For example, if you are debugging the protocol parsing part of the code, it is
|
||||
recommended to add:
|
||||
`--bpf-event-log-level 5 --conntrack-log-level 5 --protocol-log-level 5`.
|
||||
|
||||
If you encounter a situation where the eBPF code fails to load, you can add
|
||||
`--agent-log-level 5` to print some logs during Agent startup.
|
||||
|
||||
Logs are output to /tmp by default. Adding the `--debug-output` option allows
|
||||
logs to be output to standard output, and the tables displayed by the TUI will
|
||||
not be shown. All captured requests will be directly output to the console:
|
||||
|
||||
```
|
||||
WARN[0023] [ Request ]
|
||||
GET /health HTTP/1.1
|
||||
Host: :8080
|
||||
User-Agent: Go-http-client/1.1
|
||||
Accept-Encoding: gzip
|
||||
|
||||
[ Response ]
|
||||
HTTP/1.1 200 OK
|
||||
Date: Wed, 01 Jan 2025 16:20:20 GMT
|
||||
Content-Length: 2
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
|
||||
OK
|
||||
|
||||
[conn] [pid=2252][local addr]=127.0.0.1:8080 [remote addr]=127.0.0.1:38664 [side]=server [ssl]=false
|
||||
[total duration] = 0.423(ms)(start=2025-01-02 00:20:20.095, end=2025-01-02 00:20:20.095)
|
||||
[read from sockbuf]=0.296(ms)
|
||||
[process internal duration]=0.078(ms)
|
||||
[syscall] [read count]=1 [read bytes]=92 [write count]=1 [write bytes]=118
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> When debugging protocol parsing related code, you can use:
|
||||
> `--bpf-event-log-level 5 --conntrack-log-level 5 --protocol-log-level 5 --debug-output`
|
||||
> This option is generally sufficient.
|
||||
|
||||
## Source Code Structure
|
||||
|
||||
```
|
||||
> agent
|
||||
> analysis (aggregation analysis module, used by the stat command)
|
||||
> conn (connection tracking module)
|
||||
> protocol (protocol parsing module)
|
||||
> render (TUI rendering module)
|
||||
> uprobe (uprobe related, mainly ssl probe)
|
||||
> bpf
|
||||
> loader (bpf program loading logic)
|
||||
pktlatency.bpf.go (kernel core code, including syscall and kernel event reporting logic)
|
||||
gotls.bpf.go (gotls probe related)
|
||||
protocol_inference.h (protocol inference related)
|
||||
openssl* (openssl related)
|
||||
> cmd (command line related)
|
||||
> common (some utility classes)
|
||||
> docs (documentation based on vitepress)
|
||||
```
|
||||
@@ -300,6 +300,8 @@ protocol parsing-related log levels to debug.
|
||||
The protocol parsing framework code is in the `addDataToBufferAndTryParse`
|
||||
function in conntrack.go.
|
||||
|
||||
More debug tips are here:[Debug Tips](./debug-tips)
|
||||
|
||||
### Persisting Protocol Parsing Information
|
||||
|
||||
In some protocols, if you need to retain some data during the parsing process
|
||||
|
||||
Reference in New Issue
Block a user