zoukankan      html  css  js  c++  java
  • 【Golang】嗅探抓包工具,解决线上偶现问题来不及抓包的情况

    背景

    测试群里经常看到客户端的同学反馈发现了偶现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 "
    ".join((
            "
    ".join(_packet.sprintf("{Raw:%Raw.load%}").split(r"
    ")),
        ))
    
    
    sniff(
        iface='en0',
        prn=_print,
        filter="host test.baidu.com"  # 指定过滤域名
    )
    

    配上日志管理模块也能很快的完成实现。

    总结

    抓包,日志管理。

  • 相关阅读:
    python cook 整理
    Ajax
    跨站请求伪造 CSRF
    tornado web
    python hashable
    扩大了一个逻辑卷,resize2fs 保错:没有这个超级块
    linux重启后进入了救援模式,无法远程登录
    如何安装JDK以及配置win10的环境变量
    输出菱形
    6.28作业(2.使用3种方式求100以内偶数和)
  • 原文地址:https://www.cnblogs.com/Detector/p/12020382.html
Copyright © 2011-2022 走看看