"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Go API에 로깅 및 오류 처리 미들웨어 추가

Go API에 로깅 및 오류 처리 미들웨어 추가

2024-11-08에 게시됨
검색:177

Adding Logging and Error Handling Middleware to Your Go API

빠른 참고: JWT 인증에 대한 이전 게시물을 확인하고 일부 렌더링 문제를 발견했다면 이제 해당 문제가 해결되었습니다! 이 예제는 해당 튜토리얼을 기반으로 구축되었으므로 다시 한 번 살펴보시기 바랍니다. :)

자 여러분, Go API를 실행하고 JWT 인증을 추가했으며 이를 PostgreSQL 데이터베이스에 연결했습니다. 하지만 아직 끝나지 않았습니다! 이번 주에 우리는 로깅더 스마트하게 더욱 개발자 친화적으로 만들 예정입니다. ]오류 처리.

미들웨어란 무엇인가? ?

미들웨어는 좋아하는 클럽의 경비원과 같습니다. 요청이 API 엔드포인트에 도달하기 전에 차단합니다. JWT에서 했던 것처럼 인증을 확인하고, 정보를 기록하고, 문제가 발생했을 때 오류를 처리하는 미들웨어를 가질 수 있습니다.

오늘 우리는 다음과 같은 미들웨어를 구축할 것입니다:

  • 로그: 들어오는 모든 요청을 통해 누가 우리 API의 문을 두드리고 있는지 알 수 있습니다.
  • 오류 처리: 사용자가 보기 흉한 500 오류를 보지 않도록 정상적으로 처리합니다.
자세히 살펴보겠습니다!


1단계: 로깅 미들웨어 생성?

로깅은 API에서 일어나는 일을 디버깅하고 이해하는 데 있어 가장 좋은 친구입니다. 메서드, URL, 소요 시간 등 들어오는 모든 요청을 기록하는 미들웨어를 만들 예정입니다.

func loginMiddleware(다음 http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 시작 := 시간.지금() // 메소드와 요청된 URL을 기록합니다. log.Printf("%s %s 시작됨", r.Method, r.URL.Path) // 체인의 다음 핸들러를 호출합니다. next.ServeHTTP(w, r) // 걸린 시간을 기록합니다. log.Printf("%v에 완료됨", time.Since(start)) }) }

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

        // Log the method and the requested URL
        log.Printf("Started %s %s", r.Method, r.URL.Path)

        // Call the next handler in the chain
        next.ServeHTTP(w, r)

        // Log how long it took
        log.Printf("Completed in %v", time.Since(start))
    })
}


로깅 미들웨어에 대해 더 자세히 알아보고 싶은 분들은 Go에서 로깅 미들웨어 작성에 대한 Matt Silverlock의 환상적인 가이드를 확인해 보시기 바랍니다. 그는 인증, 추적, 로깅과 같은 다양한 사용 사례에 맞게 재사용 가능한 미들웨어를 구성하는 방법을 자세히 설명합니다!

2단계: 미들웨어 오류 처리?

오류에 대해 이야기해 보겠습니다. 오류가 발생하죠? 하지만 충돌을 일으키거나 모호한 오류 메시지를 보내도록 하기보다는 우아하게 처리해 봅시다.

func errorHandlingMiddleware(다음 http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 연기 기능() { if err := 복구(); 오류 != 없음 { // 오류를 기록하고 사용자에게 친숙한 메시지를 보냅니다. log.Printf("오류가 발생했습니다: %v", err) http.Error(w, "내부 서버 오류", http.StatusInternalServerError) } }() next.ServeHTTP(w, r) }) }

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 the error and send a user-friendly message
                log.Printf("Error occurred: %v", err)
                http.Error(w, "Internal Server Error", http.StatusInternalServerError)
            }
        }()
        next.ServeHTTP(w, r)
    })
}



3단계: API에 미들웨어 통합?

로깅 및 오류 처리 미들웨어를 구축했으므로 이제 이를 API에 연결해 보겠습니다. 우리는 이를 전역적으로 적용하여 모든 요청이 기록되고 오류가 발견되도록 할 것입니다.

기능 메인() { DB = 연결DB() db.Close() 연기 r := mux.NewRouter() // 미들웨어를 전역적으로 적용 r.사용(loggingMiddleware) r.사용(errorHandlingMiddleware) r.HandleFunc("/login", login).Methods("POST") r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET") r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST") fmt.Println("서버가 포트 :8000에서 시작되었습니다") log.Fatal(http.ListenAndServe(":8000", r)) }

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 the error and send a user-friendly message
                log.Printf("Error occurred: %v", err)
                http.Error(w, "Internal Server Error", http.StatusInternalServerError)
            }
        }()
        next.ServeHTTP(w, r)
    })
}



4단계: 테스트해 보세요.

모든 것이 제대로 작동하는지 확인하려면 API를 시작하세요.

main.go를 실행해 보세요

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

        // Log the method and the requested URL
        log.Printf("Started %s %s", r.Method, r.URL.Path)

        // Call the next handler in the chain
        next.ServeHTTP(w, r)

        // Log how long it took
        log.Printf("Completed in %v", time.Since(start))
    })
}


이제 엔드포인트(예: /books)에 접속하여 터미널을 확인해보세요. 다음과 같은 로그가 표시됩니다.

GET /books 시작됨 1.2ms 안에 완료됨

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

        // Log the method and the requested URL
        log.Printf("Started %s %s", r.Method, r.URL.Path)

        // Call the next handler in the chain
        next.ServeHTTP(w, r)

        // Log how long it took
        log.Printf("Completed in %v", time.Since(start))
    })
}


오류가 있으면 다음이 표시됩니다.

오류 발생: 일부 오류 세부정보

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

        // Log the method and the requested URL
        log.Printf("Started %s %s", r.Method, r.URL.Path)

        // Call the next handler in the chain
        next.ServeHTTP(w, r)

        // Log how long it took
        log.Printf("Completed in %v", time.Since(start))
    })
}


그러나 사용자에게는 깨끗한 "500 내부 서버 오류" 메시지만 표시됩니다. ?


이것이 왜 중요합니까?

  1. 로깅은 버그를 추적하고 API 동작을 모니터링하는 데 도움이 됩니다. 문제가 발생하면 정확히 어느 엔드포인트에 도달했는지, 요청에 걸린 시간은 얼마나 되는지 알 수 있습니다.

  2. 오류 처리는 예상치 못한 일이 발생할 때 API가 충돌하는 것을 방지합니다. 대신, 정상적으로 복구되고 깨끗한 오류 메시지를 클라이언트에 보냅니다.


다음은 무엇입니까?

다음에는 다음 단계로 나아가서

Go API를 Docker화하겠습니다! 이렇게 하면 앱을 이식할 수 있고 모든 컴퓨터나 클라우드 서비스에 배포할 수 있습니다. 컨테이너의 마법을 경험해보세요! ?

릴리스 선언문 이 기사는 https://dev.to/neelp03/adding-logging-and-error-handling-middleware-to-your-go-api-2f33?1에 복제되어 있습니다. 침해가 있는 경우에는 Study_golang@163으로 문의하시기 바랍니다. .com에서 삭제하세요
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3