มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ
การบันทึกแบบมีโครงสร้างและการแทรก ID การติดตาม
มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องบันทึกแบบมีโครงสร้าง
บันทึกข้อความธรรมดาแยกวิเคราะห์ได้ยากเมื่อมีปริมาณมาก การบันทึกแบบมีโครงสร้าง (JSON หรือ key=value) ช่วยให้ตัวรวบรวมบันทึก เช่น Datadog, Loki และ ELK กรองและเชื่อมโยงรายการตามช่องข้อมูลได้
การสร้าง ID คำขอ
สร้าง ID ที่ไม่ซ้ำกันสำหรับแต่ละคำขอ (UUID หรือ ULID) ในมิดเดิลแวร์ แล้วแนบไว้กับส่วนหัวการตอบกลับและบริบท:
func RequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := r.Header.Get("X-Request-ID")
if id == "" { id = uuid.New().String() }
w.Header().Set("X-Request-ID", id)
ctx := context.WithValue(r.Context(), reqIDKey{}, id)
next.ServeHTTP(w, r.WithContext(ctx))
})
}มิดเดิลแวร์บันทึกล็อกด้วย slog
Go 1.21 เพิ่ม log/slog สำหรับการบันทึกแบบมีโครงสร้าง สามารถใช้ภายในมิดเดิลแวร์ได้:
func StructuredLogger(logger *slog.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
cw := &captureWriter{ResponseWriter: w}
next.ServeHTTP(cw, r)
logger.Info("request",
"method", r.Method,
"path", r.URL.Path,
"status", cw.status,
"latency_ms", time.Since(start).Milliseconds(),
"request_id", r.Context().Value(reqIDKey{}),
)
})
}
}captureWriter
ห่อ ResponseWriter เพื่อดักจับรหัสสถานะที่ตัวจัดการเขียน:
type captureWriter struct {
http.ResponseWriter
status int
}
func (cw *captureWriter) WriteHeader(code int) {
cw.status = code
cw.ResponseWriter.WriteHeader(code)
}
func (cw *captureWriter) Status() int {
if cw.status == 0 { return http.StatusOK }
return cw.status
}การเพิ่ม ID คำขอในทุกบรรทัดบันทึก
สร้างตัวบันทึกลูกสำหรับแต่ละคำขอโดยเติม ID ไว้ล่วงหน้า แล้วจัดเก็บตัวบันทึกนั้นในบริบท:
reqLogger := logger.With("request_id", id)
ctx := context.WithValue(r.Context(), loggerKey{}, reqLogger)การดึงตัวบันทึกจากบริบท
ฟังก์ชันช่วยเหลือสำหรับดึงตัวบันทึกที่มีขอบเขตตามคำขอจากตัวจัดการหรือบริการใด ๆ:
func LoggerFromContext(ctx context.Context) *slog.Logger {
l, ok := ctx.Value(loggerKey{}).(*slog.Logger)
if !ok { return slog.Default() }
return l
}ระดับการบันทึก
ใช้ระดับให้เหมาะสม ได้แก่ Debug สำหรับรายละเอียดระหว่างการพัฒนา Info สำหรับสรุปคำขอ Warn สำหรับความผิดปกติที่กู้คืนได้ และ Error สำหรับความล้มเหลวที่ต้องดำเนินการ อย่าบันทึกช่องข้อมูลที่มีความละเอียดอ่อน เช่น โทเคนและรหัสผ่าน
กลุ่มช่วงเวลาแฝง
ใส่เวลาแฝงของคำขอในทุกบรรทัดบันทึก แล้วรวมเป็นกลุ่มฮิสโตแกรมในระบบเมตริกของคุณ (Prometheus) เพื่อติดตามเปอร์เซ็นไทล์ P50/P95/P99
รหัสสหสัมพันธ์ในไมโครเซอร์วิส
ส่งต่อส่วนหัว X-Request-ID จากคำขอขาเข้าทั้งหมดไปยังการเรียกใช้ HTTP และ gRPC ขาออกทั้งหมด เพื่อเปิดใช้การติดตามแบบกระจายโดยไม่ต้องมีระบบติดตามเต็มรูปแบบ
การสุ่มตัวอย่างล็อก
สำหรับบริการที่มีปริมาณการใช้งานสูง ให้สุ่มบันทึกล็อกระดับ debug/info เช่น บันทึก 1 จากทุก 100 คำขอที่ระดับ debug เพื่อลดค่าใช้จ่ายในการจัดเก็บ โดยยังคงบันทึกล็อกข้อผิดพลาดไว้อย่างครบถ้วน
zap เทียบกับ slog
zap (Uber) ทำงานเร็วกว่า slog สำหรับบริการที่มีปริมาณงานสูง แต่ต้องตั้งค่ามากกว่า ส่วน slog เป็นไลบรารีมาตรฐาน พกพาได้ และเพียงพอสำหรับบริการส่วนใหญ่ ควรเลือกใช้ slog เว้นแต่ผลการทดสอบประสิทธิภาพจะแสดงว่ามีคอขวด
ตรวจสอบอย่างรวดเร็ว
เหตุใดจึงต้องใช้ captureWriter ในมิดเดิลแวร์การบันทึกล็อก
สรุป: การบันทึกล็อกและรหัสคำขอ
ประเด็นสำคัญ:
- สร้างหรือส่งต่อ X-Request-ID ในมิดเดิลแวร์ แล้วจัดเก็บไว้ในบริบท
- ใช้ slog สำหรับล็อกแบบมีโครงสร้างพร้อมฟิลด์แบบคีย์-ค่า
- captureWriter ดักจับรหัสสถานะเพื่อใช้บันทึกล็อกหลังตัวจัดการทำงานเสร็จ
- ส่งต่อรหัสสหสัมพันธ์ไปยังการเรียกใช้ปลายทางทั้งหมด
คำถามที่พบบ่อย
บทเรียน “มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ”
การบันทึกแบบมีโครงสร้างและการแทรก ID การติดตาม คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐานสายโซ่มิดเดิลแวร์ HTTP
- มิดเดิลแวร์สำหรับการบันทึกและ ID คำขอ
- มิดเดิลแวร์การยืนยันตัวตนและจำกัดอัตรา
- มิดเดิลแวร์ CORS และกู้คืนจาก panic