背景
測試群里經常看到客戶端的同學反饋發現了偶現Bug,但是來不及抓包,最后不了了之,最近出現得比較頻繁,所以寫個小腳本解決這個問題。
實現思路
之前寫過一個埋點工具,輔助測試埋點的數據,解決多個端的埋點需要打開不同的抓包軟件,並且需要肉眼去比對的的不便,也是使用的抓包分析數據並在界面(pyqt5)展示的方式,這一次主要是進行日志的管理,保存請求記錄,所以實現的思路比較簡單:
- 抓包
- 存日志
- 做日志管理
具體實現
此前使用過優步的號稱性能最好的golang日志管理包zap,結合lumberjack對日志的管理特別的方便,幾個配置參數就能滿足需求,比如一鍵日志壓縮壓縮后1M只占20Kb。所以拿來即用,
lumberjack常見的配置參數
參數 | 含義 |
---|---|
Filename: | // 日志文件路徑 |
MaxSize: | // 每個日志文件保存的最大尺寸 單位:M |
MaxBackups: | // 日志文件最多保存多少個備份 |
MaxAge: | // 文件最多保存多少天 |
Compress: | // 是否壓縮, 壓縮后1M約占20Kb |
Go build 成不同操作系統可執行文件
而且golang可以很簡單的把代碼編譯成不同系統都能執行的程序或者二進制包。
Mac下編譯Linux, Windows平台的64位可執行程序:
$ CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build test.go # Mac
$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build test.go # linux
$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go # windows
具體代碼
package main
import (
"fmt"
"os"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var (
device = "en0" // 指定監控網卡名稱信息
snapshotLen int32 = 10000000
promiscuous = false
err error
timeout = 30 * time.Second
handle *pcap.Handle
)
func main() {
handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
filter := "host test.baidu.com" // 指定抓取域名
err = handle.SetBPFFilter(filter)
defer handle.Close()
log := initLog()
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
applicationLayer := packet.ApplicationLayer()
if applicationLayer != nil {
log.Info(string(applicationLayer.LayerContents()))
}
if err := packet.ErrorLayer(); err != nil {
fmt.Println("Error decoding some part of the packet:", err)
}
}
}
func initLog() *zap.Logger {
hook := lumberjack.Logger{
Filename: "./logs/package.log", // 日志文件路徑
MaxSize: 10, // 每個日志文件保存的最大尺寸 單位:M
MaxBackups: 5, // 日志文件最多保存多少個備份
MaxAge: 7, // 文件最多保存多少天
Compress: true, // 是否壓縮, 壓縮后1M約占20Kb
}
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
MessageKey: "msg",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder, // 小寫編碼器
EncodeTime: zapcore.ISO8601TimeEncoder, // ISO8601 UTC 時間格式
EncodeDuration: zapcore.SecondsDurationEncoder, //
}
// 設置日志級別
atomicLevel := zap.NewAtomicLevel()
atomicLevel.SetLevel(zap.InfoLevel)
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig), // 編碼器配置
zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件
atomicLevel, // 日志級別
)
logger := zap.New(core)
logger.Info("log 初始化成功")
return logger
}
Python 抓包
Python使用scapy也能很簡單的完成抓包操作:
from scapy.all import *
def _print(_packet):
"""
指定抓包信息打印規則
:param _packet:
:return:
"""
return "\n".join((
"\n".join(_packet.sprintf("{Raw:%Raw.load%}").split(r"\r\n")),
))
sniff(
iface='en0',
prn=_print,
filter="host test.baidu.com" # 指定過濾域名
)
配上日志管理模塊也能很快的完成實現。
總結
抓包,日志管理。