为你的 Go API 添加日志记录和错误处理中间件

开发 前端
在 main​ 函数中,我们首先创建了一个 mux.NewRouter​ 对象,它用于路由请求。然后,我们使用 r.Use​ 函数全局应用了 loggingMiddleware​ 和 errorHandlingMiddleware。这样,所有请求都会经过这两个中间件。

在构建 Go API 时,日志记录和错误处理是至关重要的组成部分,它们可以帮助你调试代码、监控 API 行为并为用户提供友好的错误提示。中间件提供了一种优雅的方式来实现这些功能,它允许你在请求到达你的 API 端点之前拦截请求并执行一些操作。

本文将引导你逐步添加日志记录和错误处理中间件到你的 Go API 中,使你的 API 更加健壮、易于维护和用户友好。

什么是中间件?

中间件就像你最喜欢的夜总会里的保安,它会在请求到达你的 API 端点之前拦截请求。你可以使用中间件来检查身份验证(比如我们在 JWT 中所做的那样)、记录信息或在出现错误时进行处理。

今天,我们将构建一个中间件,它可以:

  • 记录:每个传入请求,以便我们知道谁在敲打我们的 API 的门。
  • 处理错误:优雅地处理错误,这样你的用户就不会看到那些难看的 500 错误。

让我们深入研究吧!

第一步:创建日志记录中间件

日志记录是你调试和了解 API 中发生的事情时最好的朋友。我们将创建一个中间件,它记录每个传入请求——方法、URL 和所用时间。

import (
 "log"
 "net/http"
 "time"
)

func loggingMiddleware(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  start := time.Now()

  // 记录方法和请求的 URL
  log.Printf("Started %s %s", r.Method, r.URL.Path)

  // 调用链中的下一个处理程序
  next.ServeHTTP(w, r)

  // 记录所用时间
  log.Printf("Completed in %v", time.Since(start))
 })
}

这段代码定义了一个名为 loggingMiddleware 的函数,它接受一个 http.Handler 作为参数,并返回一个新的 http.Handler。这个新处理程序包含一个匿名函数,它会在每个请求到达时执行。在函数中,我们首先记录了请求的开始时间,然后记录了请求的方法和 URL。接下来,我们调用 next.ServeHTTP 将请求传递给链中的下一个处理程序。最后,我们记录了请求的处理时间。

第二步:错误处理中间件

让我们谈谈错误。错误会发生,对吧?但是,与其让它们导致崩溃或发送模糊的错误消息,不如让我们优雅地处理它们。

func errorHandlingMiddleware(next http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  defer func() {
   if err := recover(); err != nil {
    // 记录错误并发送用户友好的消息
    log.Printf("Error occurred: %v", err)
    http.Error(w, "Internal Server Error", http.StatusInternalServerError)
   }
  }()
  next.ServeHTTP(w, r)
 })
}

这段代码定义了一个名为 errorHandlingMiddleware 的函数,它接受一个 http.Handler 作为参数,并返回一个新的 http.Handler。这个新处理程序包含一个匿名函数,它会在每个请求到达时执行。在函数中,我们使用 defer 关键字来确保在函数返回之前执行一个匿名函数。这个匿名函数使用 recover() 函数来捕获任何恐慌,并记录错误信息,然后向客户端发送一个 500 错误。

第三步:在你的 API 中集成中间件

现在我们已经构建了日志记录和错误处理中间件,让我们将它们连接到我们的 API。我们将全局应用它们,这样每个请求都会被记录,并且错误会被捕获。

import (
 "fmt"
 "log"
 "net/http"

 "github.com/gorilla/mux"
)

// ... 其他代码 ...

func main() {
 // ... 其他代码 ...

 r := mux.NewRouter()

 // 全局应用中间件
 r.Use(loggingMiddleware)
 r.Use(errorHandlingMiddleware)

 // ... 其他代码 ...

 fmt.Println("Server started on port :8000")
 log.Fatal(http.ListenAndServe(":8000", r))
}

在 main 函数中,我们首先创建了一个 mux.NewRouter 对象,它用于路由请求。然后,我们使用 r.Use 函数全局应用了 loggingMiddleware 和 errorHandlingMiddleware。这样,所有请求都会经过这两个中间件。

第四步:测试它

为了确保一切正常,启动你的 API:

go run main.go

现在,尝试访问你的任何端点(例如 /books)并检查你的终端。你应该看到类似以下的日志:

Started GET /books
Completed in 1.2ms

如果出现错误,你会看到:

Error occurred: some error details

但是,你的用户只会看到一条干净的“500 内部服务器错误”消息。🎉

为什么这很重要?

  1. 日志记录有助于你跟踪错误和监控 API 的行为。如果出现问题,你会确切地知道哪个端点被访问以及请求花费了多长时间。
  2. 错误处理可以防止你的 API 在出现意外情况时崩溃。相反,它会优雅地恢复并向客户端发送一条清晰的错误消息。
责任编辑:武晓燕 来源: 源自开发者
相关推荐

2023-10-26 15:49:53

Go日志

2024-05-06 12:30:51

Go语言中间件

2022-11-18 07:54:02

Go中间件项目

2021-09-13 07:53:31

Go错误处理

2015-12-21 14:56:12

Go语言Http网络协议

2021-10-06 19:03:35

Go中间件Middleware

2014-11-17 10:05:12

Go语言

2021-04-29 09:02:44

语言Go 处理

2013-12-12 10:55:21

2022-10-25 08:01:17

洋葱模型Koa

2020-06-28 09:20:33

代码开发Go

2022-07-14 08:17:59

中间件微服务开发

2023-11-27 07:10:06

日志中间件

2016-11-11 21:00:46

中间件

2023-12-06 07:14:28

前端API中间件

2024-01-05 08:17:53

FiberGolang路由

2011-05-24 15:10:48

2021-02-11 08:21:02

中间件开发CRUD

2022-09-05 08:55:15

Go2提案语法

2011-12-30 10:31:38

云计算
点赞
收藏

51CTO技术栈公众号