Structured Logging with slog
Bài tóm tắt Go 2023 3. Quy mô lớn Độ khó: Dễ
Go · 2023 · 3. Quy mô lớn · Độ khó: Dễ — bài gốc
Bài của đội Go về một API thư viện chuẩn, không phải hệ thống production; giữ lại vì kể cách một hệ sinh thái gom các thư viện log rời rạc về một backend chung.
Bối cảnh
- Log là nơi đầu tiên người ta tìm khi debug server, nên log nhiều và phải lọc, tìm nhanh. Log có cấu trúc (cặp key-value) phân tích được tin cậy hơn log chữ.
- Thư viện chuẩn
logkhông có cấu trúc. Hệ sinh thái tự lấp: logrus được hơn 100.000 package dùng, cộng zap, logr, go-kit/log... Chương trình lớn thường kéo vào nhiều thư viện log qua dependency và phải cấu hình từng cái để output cùng nơi, cùng định dạng.
Thay đổi chính
- Tách frontend và backend:
Loggerlà API gọi,Handlerlà interface backend. Có sẵnTextHandler(key=value) vàJSONHandler; ai cũng viết được handler, kể cả handler bọc handler khác. Mục tiêu không phải thay thư viện bên thứ ba mà cho chúng nói chung một backend (đã có handler cho zap, logr, hclog). - Hiệu năng theo dữ liệu thật: khảo sát code mã nguồn mở trên module proxy, hơn 95% lời gọi log có từ 5 thuộc tính trở xuống, phần lớn thuộc vài kiểu phổ biến; benchmark cho đúng các ca đó; phần lợi lớn nhất đến từ giảm cấp phát bộ nhớ.
Handler.Enabledcho bỏ sớm sự kiện không cần;WithAttrs/WithGroupcho format trước thuộc tính gắn bằngLogger.Withmột lần thay vì mỗi lần gọi;LogAttrs+Attrcho đường nóng. - Context: một bộ hàm nhận
context.Contextđể handler lấy trace ID; hủy context không chặn việc ghi log. - Quy trình thiết kế: 4/2022 quyết định thử; 8/2022 công bố bản thử nghiệm và GitHub discussion (khoảng 300 bình luận trong hai tháng); proposal chính thức hơn 800 bình luận; chấp nhận 15/3/2023; phát hành cùng Go 1.21 ngày 8/8/2023. Bỏ tính năng gắn logger vào context vì gây tranh cãi (phụ thuộc ngầm); giữ cú pháp key-value xen kẽ cho nhẹ dù nhiều người phản đối, thêm
vetcheck để bắt lỗi thiếu key/value.
Vì sao
- Theo đội Go, đưa log có cấu trúc vào thư viện chuẩn tạo một khung chung cho mọi thư viện log, giải bài toán nhiều logger trong một chương trình mà không bắt ai viết lại.
Bài học cho SWE
- Khi hệ sinh thái đã phân mảnh, chuẩn hoá interface backend thay vì thay mọi frontend: dữ liệu ra một nơi, code cũ không phải đổi.
- Tối ưu theo phân phối dùng thật (95% lời gọi ≤ 5 thuộc tính), không theo ca xấu nhất.
Liên quan
- Stripe 2019 (một dòng log có cấu trúc mỗi request) · Grab 2019 · Salesforce 2017
- Observability và monitoring
#Structured logging#log/slog#Handler interface#Logger frontend#JSONHandler#Allocation#Proposal process#Interoperability
Được nhắc tới trong
Chủ đề (1)
Công ty (1)