1. Tổng quan.
Hiểu một cách đơn giản thì log là những thứ dùng để lưu vết, những thông tin được thông báo, lưu lại trong quá trình hoạt động của một ứng dụng. Ví dụ: user A đang đăng nhập thì ứng dụng sẽ ghi thêm 1 dòng trong file log rằng: user A đã đăng nhập thành công hay thất bại.
![](https://wiki.hoanghd.com/wp-content/uploads/2023/11/image-46-1024x551.png)
Ghi log để có thể xem lại các thông tin hoạt động của ứng dụng trong quá khứ nhằm nhiều mục đích như debug, check health, xem info, xem lỗi, warning,…
Hãy xem một số khái niệm sau đây:
- Log là gì?
- Log là những thông tin được ghi lại trong quá trình hoạt động của một ứng dụng.
- Ví dụ: Ghi lại việc đăng nhập thành công hoặc thất bại của một người dùng.
- Ghi log để làm gì?
- Xem lại các hoạt động của ứng dụng trong quá khứ.
- Mục đích như debug, kiểm tra sức khỏe, xem thông tin, xác định lỗi, cảnh báo, v.v.
- Ghi log là ghi gì?
- Ghi lại thông tin cần thiết để phục vụ mục đích sử dụng, như debug hay xác định lỗi.
- Một dòng log tiêu chuẩn thường bao gồm: Timestamp (thời gian sự kiện xảy ra), Log level (mức độ của log: debug, info, error), và Contextual data (dữ liệu ngữ cảnh).
- Độ chi tiết và chính xác của log
- Độ chi tiết và chính xác của log ảnh hưởng đến khả năng bắt lỗi (debug) của ứng dụng.
- Log càng chi tiết và chính xác, việc bắt lỗi càng hiệu quả.
- Tầm quan trọng của log trong phát triển ứng dụng
- Log là một công cụ quan trọng để theo dõi và phân tích hoạt động của ứng dụng.
- Nó hỗ trợ quá trình phát triển, bảo trì, và nâng cấp ứng dụng.
2. Loggin trong Golang.
Trong ngôn ngữ lập trình Go (Golang), “log” là một gói (package) cung cấp các chức năng để ghi thông tin log. Package này cung cấp các hàm để ghi thông tin log vào các nguồn khác nhau, như stderr hoặc một tập tin log.
Bạn có thể sử dụng module log trong Go bằng cách import gói “log” và sau đó sử dụng các hàm như Print, Printf, Println để ghi thông tin log.
Dưới đây là một ví dụ đơn giản:
package main
import "log"
func main() {
log.Print("This is a log message")
log.Printf("This is a formatted log message with a variable: %s", "example")
log.Println("This is a log message with a newline")
}
Các thông tin log này thường xuất hiện trên stderr theo mặc định, nhưng bạn có thể định cấu hình log để xuất hiện ở nơi khác bằng cách sử dụng các phương thức khác nhau trong package log hoặc sử dụng các gói khác như “logrus” hoặc “zerolog” để có các tính năng mở rộ hơn và quản lý log linh hoạt hơn.
3. Ví dụ logging trong Golang trong thực tế.
Ở Go có một thư viện chuẩn tương tự như các ngôn ngữ khác để log một dòng text ra console, ví dụ như đưới đây. Ví dụ này mình sử dụng module log
có trong Go để demo.
Viết một chương trình kiểm tra kết nối mạng bằng ICMP.
package main
import (
"log"
"os/exec"
"regexp"
)
func main() {
// Thực hiện lệnh ping và lấy kết quả đầu ra
var count string = "1"
var ipaddr string = "8.8.8.8"
cmd := exec.Command("ping", "-c", count, ipaddr)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("cmd.Run() failed with %s\n", err)
}
// Chuyển đổi đầu ra thành chuỗi
output := string(out)
// Sử dụng regex để tìm kiếm giá trị "0%" trong đoạn văn bản
re := regexp.MustCompile(`(\d+)% packet loss`)
matches := re.FindStringSubmatch(output)
// Kiểm tra nếu có matches và lấy giá trị tương ứng
if len(matches) > 1 {
packetLoss := matches[1]
log.Printf("Check IP: %s, Packet Loss: %s\n", ipaddr, packetLoss)
} else {
log.Println("Không tìm thấy thông tin về packet loss.")
}
}
Hãy để ý kết quả khi chạy chương trình, phía trước kết quả in ra bạn nhận được thêm log về thời gian hoàn thành.
$ go run main.go
2023/11/15 09:24:32 Check IP: 8.8.8.8, Packet Loss: 0
Và đây là một ví dụ tương tự nhưng mình đổi module log
thành module fmt
.
package main
import (
"os/exec"
"regexp"
"fmt"
)
func main() {
// Thực hiện lệnh ping và lấy kết quả đầu ra
var count string = "1"
var ipaddr string = "8.8.8.8"
cmd := exec.Command("ping", "-c", count, ipaddr)
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("cmd.Run() failed with %s\n", err)
}
// Chuyển đổi đầu ra thành chuỗi
output := string(out)
// Sử dụng regex để tìm kiếm giá trị "0%" trong đoạn văn bản
re := regexp.MustCompile(`(\d+)% packet loss`)
matches := re.FindStringSubmatch(output)
// Kiểm tra nếu có matches và lấy giá trị tương ứng
if len(matches) > 1 {
packetLoss := matches[1]
fmt.Println("Check IP: " + ipaddr + ", Packet Loss: " + packetLoss)
} else {
fmt.Println("Không tìm thấy thông tin về packet loss.")
}
}
Bạn sẽ thấy giờ đây bạn chỉ còn kết quả in ra màn hình và thông tin về thời gian hoàn thành bạn sẽ không thấy chúng nữa.
$ go run main.go
Check IP: 8.8.8.8, Packet Loss: 0