0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Go/Docker】効率的なバックエンドデバッグ術 - docker logsを活用したAPIトラブルシューティング

Posted at

こんにちは!フリーランスエンジニアのこたろうです。
今回は、Docker環境で動作するGoバックエンドのデバッグ方法について、実践的な知見を共有します。

1. docker logsの基本

リアルタイムでログを確認

# コンテナのログをリアルタイムで表示
docker logs -f backend-container

# 直近100行のログを表示
docker logs --tail 100 backend-container

# タイムスタンプ付きでログを表示
docker logs -f --timestamps backend-container

Goコードでのログ出力

// handlers/message.go
func (h *MessageHandler) Create(c *gin.Context) {
    // リクエストの開始をログ出力
    fmt.Printf("Message creation started at: %v\n", time.Now())
    
    var message Message
    if err := c.ShouldBindJSON(&message); err != nil {
        fmt.Printf("Error binding JSON: %v\n", err)
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    
    // 処理の結果をログ出力
    fmt.Printf("Message created: %+v\n", message)
}

2. grepを使ったログのフィルタリング

特定のAPIリクエストの抽出

# /api/messages/createへのリクエストのみ表示
docker logs -f backend-container | grep "/api/messages/create"

# エラーを含むログの抽出
docker logs backend-container | grep "Error"

# 特定の時間帯のログを抽出
docker logs backend-container | grep "2024-02-06T15"

パイプを活用した複雑なフィルタリング

# エラーを含み、特定のAPIに関連するログを抽出
docker logs backend-container | grep "Error" | grep "/api/messages"

# JSONデータの内容を確認
docker logs backend-container | grep "Message created" | jq .

3. CORSデバッグのテクニック

OPTIONSリクエストの確認

// main.go
func setupCORS(r *gin.Engine) {
    fmt.Println("Setting up CORS...")
    
    r.Use(cors.New(cors.Config{
        AllowOrigins: []string{"http://localhost:3000"},
        AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
        AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
        ExposeHeaders: []string{"Content-Length"},
        AllowCredentials: true,
        MaxAge: 12 * time.Hour,
    }))
    
    // OPTIONSリクエストのログ
    r.OPTIONS("/*path", func(c *gin.Context) {
        fmt.Printf("OPTIONS request received: %s\n", c.Request.URL.Path)
        c.Status(http.StatusNoContent)
    })
}

CORSエラーのデバッグ

# OPTIONSリクエストのログを確認
docker logs backend-container | grep "OPTIONS request received"

# CORSヘッダーの確認
docker logs backend-container | grep "Access-Control-Allow"

4. WebSocketデバッグのポイント

コネクション確立のログ

func (h *WebSocketHandler) HandleWebSocket(c *gin.Context) {
    fmt.Printf("WebSocket connection attempt from: %s\n", c.Request.RemoteAddr)
    
    conn, err := h.upgrader.Upgrade(c.Writer, c.Request, nil)
    if err != nil {
        fmt.Printf("WebSocket upgrade error: %v\n", err)
        return
    }
    defer conn.Close()
    
    fmt.Printf("WebSocket connection established with: %s\n", c.Request.RemoteAddr)
}

WebSocketメッセージのログ

# WebSocketの接続ログを確認
docker logs backend-container | grep "WebSocket connection"

# エラーを含むWebSocketログを確認
docker logs backend-container | grep "WebSocket" | grep "error"

5. 実践的なトラブルシューティング例

エラーの原因特定

# エラーの発生時刻を特定
docker logs --timestamps backend-container | grep "Error"

# エラー前後のログを確認
docker logs --timestamps backend-container | grep -A 5 -B 5 "Error"

# 特定のリクエストの一連の流れを確認
docker logs backend-container | grep -E "(Started|Completed|Error)"

デバッグ用ログの実装

type DebugLogger struct {
    Enabled bool
}

func (l *DebugLogger) Printf(format string, v ...interface{}) {
    if l.Enabled {
        fmt.Printf("[DEBUG] "+format+"\n", v...)
    }
}

// 使用例
logger := &DebugLogger{Enabled: true}
logger.Printf("Processing request: %s", requestID)

まとめ

効果的なデバッグのポイント:

  1. 適切なログレベルの設定
  2. 必要な情報の選択的な出力
  3. grepを活用したログの絞り込み
  4. エラー発生時の文脈の把握
  5. システマティックな原因特定
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?