边缘函数

日志记录

如何访问边缘函数的日志


每次函数调用都会在本地和托管环境中提供日志记录。

如何访问日志

托管环境

您可以通过控制台的函数部分访问以下两种工具。从列表中选择您的函数,然后点击调用记录日志

  • 调用记录:显示每次执行的请求和响应。您可以查看每次调用的请求头、请求体、状态码和持续时间。还可以按日期、时间或状态码筛选调用记录。
  • 日志:显示平台事件、未捕获的异常和自定义日志事件。您可以查看每个日志事件的时间戳、级别和消息。还可以按日期、时间或日志级别筛选日志事件。

函数调用记录

本地环境

在本地开发时,您将在本地终端窗口中看到错误信息和控制台日志输出。

被记录的日志事件

  • 未捕获的异常:函数执行期间抛出的未捕获异常会被自动记录。您可以在日志工具中查看错误信息和堆栈跟踪。
  • 自定义日志事件:您可以在代码中使用 console.logconsole.errorconsole.warn 来发送自定义日志事件。这些事件也会出现在日志工具中。
  • 启动和关闭日志:日志工具还包含函数启动和关闭时的日志记录。

以下是在函数中使用自定义日志事件的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.(async () => { try { const { } = await .() if (!) { .('Empty name provided') } const = { : `Hello ${ || 'Guest'}!`, // 如果名称为空则提供默认值 } .(`Name: ${}`) return new (.(), { : { 'Content-Type': 'application/json' } }) } catch () { .(`Error processing request: ${}`) return new (.({ : 'Internal Server Error' }), { : 500, : { 'Content-Type': 'application/json' }, }) }})

日志记录技巧

记录请求头信息

在调试边缘函数时,一个常见错误是尝试通过以下代码将请求头记录到开发者控制台:

1
2
3
4
5
6
7
8
9
10
11
12
.(async () => { const = .(.) .(`请求头: ${}`) // 或者 .(`请求头: ${.(.)}`) return new ('ok', { : { 'Content-Type': 'application/json', }, : 200, })})

这两种尝试都会输出字符串 "{}",尽管使用 request.headers.get("Your-Header-Name") 确实能获取到正确的值。这种行为与浏览器的表现一致。

这种现象的原因是 Headers 对象并不将头信息存储在可枚举的 JavaScript 属性中。因此,无论是开发者控制台还是 JSON 字符串化器都无法正确解析头信息的名称和值。本质上,这不是一个空对象,而是一个不透明的对象。

不过,Headers 对象是可迭代的。您可以利用这个特性编写几个简洁的单行代码来调试和打印头信息。

使用 Object.fromEntries 将请求头转换为对象

您可以使用 Object.fromEntries 方法将请求头转换为对象:

1
2
3
4
5
6
7
8
9
10
11
.(async () => { let = .(.) let = .(, null, 2) .(`请求头: ${}`) return new ('ok', { : { 'Content-Type': 'application/json', }, : 200, })})

执行结果类似如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
请求头: { "accept": "*/*", "accept-encoding": "gzip", "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InN1cGFuYWNobyIsInJvbGUiOiJhbm9uIiwieW91IjoidmVyeSBzbmVha3ksIGh1aD8iLCJpYXQiOjE2NTQ1NDA5MTYsImV4cCI6MTk3MDExNjkxNn0.cwBbk2tq-fUcKF1S0jVKkOAG2FIQSID7Jjvff5Do99Y", "cdn-loop": "cloudflare; subreqs=1", "cf-ew-via": "15", "cf-ray": "8597a2fcc558a5d7-GRU", "cf-visitor": "{\"scheme\":\"https\"}", "cf-worker": "supabase.co", "content-length": "20", "content-type": "application/x-www-form-urlencoded", "host": "edge-runtime.supabase.com", "my-custom-header": "abcd", "user-agent": "curl/8.4.0", "x-deno-subhost": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6InN1cGFiYXNlIn0.eyJkZXBsb3ltZW50X2lkIjoic3VwYW5hY2hvX2M1ZGQxMWFiLTFjYmUtNDA3NS1iNDAxLTY3ZTRlZGYxMjVjNV8wMDciLCJycGNfcm9vdCI6Imh0dHBzOi8vc3VwYWJhc2Utb3JpZ2luLmRlbm8uZGV2L3YwLyIsImV4cCI6MTcwODYxMDA4MiwiaWF0IjoxNzA4NjA5MTgyfQ.-fPid2kEeEM42QHxWeMxxv2lJHZRSkPL-EhSH0r_iV4", "x-forwarded-host": "edge-runtime.supabase.com", "x-forwarded-port": "443", "x-forwarded-proto": "https"}