请问下,我该怎么写一个main去调下面代码最后一段的OutRecvErrRateSumFunc,本人小白,弄了很久,请大神能帮忙解答一下!!!

请问下,我该怎么写一个main去调下面代码最后一段的OutRecvErrRateSumFunc,本人小白,弄了很久,请大神能帮忙解答一下!!!


package system

import (
    "bufio"
    "errors"
    "fmt"
    "io"
    "net"
    "os"
    "strconv"
    "strings"
    "time"
)

type Ifi struct {
    Name              string
    Ip                string
    Speed             float64
    OutRecvPkgErrRate float64 //外网收包错误率
    OutSendPkgErrRate float64 //外网发包错误率
    RecvByte          uint64  //接收的字节数
    RecvPkg           uint64  //接收正确的包数
    RecvErr           uint64  //接收错误的包数
    SendByte          uint64  //发送的字节数
    SendPkg           uint64  //发送正确的包数
    SendErr           uint64  //发送错误的包数

    RecvByteAvg float64 //一个周期平均每秒接收字节数
    SendByteAvg float64 //一个周期平均每秒发送字节数
    RecvErrRate float64 //一个周期收包错误率
    SendErrRate float64 //一个周期发包错误率
    RecvPkgAvg  float64 //一个周期平均每秒收包数
    SendPkgAvg  float64 //一个周期平均每秒发包数

    Last int64 //上次采集时间
}

//判断是否为内网
func (this *Ifi) IsInEth() bool {
    if this.Ip == "" {
        return false
    }
    fields := strings.Split(this.Ip, ".")
    if len(fields) != 4 {
        return false
    }
    field1 := fields[0]
    if strings.Contains(field1, "10") ||
        strings.Contains(field1, "127") ||
        strings.Contains(field1, "192") ||
        strings.Contains(field1, "172") {
        return true
    }
    return false
}

type NetWork struct {
    IfiMap      map[string]*Ifi
    IfiNames    []string
    RecvByteSum float64 //所有内外网网络接口一个周期平均接收字节数之和
    SendByteSum float64 //所有内外网网络接口一个周期平均发送字节数之和

    InRecvByteSum    float64 //所有内网网络接口平均每秒接收字节数之和
    InSendByteSum    float64 //所有内网网络接口平均每秒发送字节数之和
    InRecvPkgSum     float64 //所有内网网络接口平均每秒收包数之和
    InSendPkgSum     float64 //所有内网网络接口平均每秒发包数之和
    InRecvErrRateSum float64 //所有内网网络接口收包错误率之和
    InSendErrRateSum float64 //所有内网网络接口发包错误率之和

    OutRecvByteSum    float64 //所有外网网络接口平均每秒接收字节数之和
    OutSendByteSum    float64 //所有外网网络接口平均每秒发送字节数之和
    OutRecvPkgSum     float64 //所有外网网络接口平均每秒收包数之和
    OutSendPkgSum     float64 //所有外网网络接口平均每秒发包数之和
    OutRecvErrRateSum float64 //所有外网网络接口收包错误率之和
    OutSendErrRateSum float64 //所有外网网络接口发包错误率之和

    EthInMaxUseRate  float64 //内网网卡使用率
    EthOutMaxUseRate float64 //外网网卡使用率

    RecvSendDetail string //收发接口收发字节数详细信息
    ModelDetail    string //网络接口型号带宽详细信息

    /*
        //外网网卡流入环比
        OutRecvByteSum10Sum   float64 //外网网卡平均每秒接收字节累加和
        OutRecvByteSum10Times int     //外网网卡平均每秒接收字节累加次数
        OutRecvByteSum10      float64 //外网网卡流入10分钟环比
        OutRecvByteSum10Last  int64

        OutRecvByteSum60Sum   float64 //外网网卡平均每秒接收字节累加和
        OutRecvByteSum60Times int     //外网网卡平均每秒接收字节累加次数
        OutRecvByteSum60      float64 //外网网卡流入60分钟环比
        OutRecvByteSum60Last  int64

        OutRecvByteSumDaySum   float64 //外网网卡平均每秒接收字节累加和
        OutRecvByteSumDayTimes int     //外网网卡平均每秒接收字节累加次数
        OutRecvByteSumDay      float64 //外网网卡流入日同比
        OutRecvByteSumDayLast  int64
    */
}

func (this *NetWork) Collect() error {
    this.ResetIfiData()
    return this.InitNetWorkInfo()
}

func (this *NetWork) ResetIfiData() {
    this.RecvByteSum = 0
    this.SendByteSum = 0

    this.InRecvByteSum = 0
    this.InSendByteSum = 0
    this.InRecvPkgSum = 0
    this.InSendPkgSum = 0
    this.InRecvErrRateSum = 0
    this.InSendErrRateSum = 0

    this.OutRecvByteSum = 0
    this.OutSendByteSum = 0
    this.OutRecvPkgSum = 0
    this.OutSendPkgSum = 0
    this.OutRecvErrRateSum = 0
    this.OutSendErrRateSum = 0

    this.EthInMaxUseRate = 0
    this.EthOutMaxUseRate = 0

    this.RecvSendDetail = ""
    this.ModelDetail = ""
}

func (this *NetWork) InitNetWorkInfo() error {
    f, err := os.Open("/proc/net/dev")
    if err != nil {
        return err
    }
    defer f.Close()
    reader := bufio.NewReader(f)
    for {
        line, err := reader.ReadString('\n')
        if err == io.EOF {
            break
        }
        if err != nil {
            return err
        }
        if !strings.Contains(line, ":") {
            continue
        }
        fields := strings.Split(line, ":")
        if len(fields) < 2 {
            continue
        }

        ethname := fields[0]
        Trim(ðname)

        fields = strings.Fields(fields[1])
        if len(fields) != 16 {
            continue
        }
        recvByte, _ := strconv.ParseUint(fields[0], 10, 64)
        recvPkg, _ := strconv.ParseUint(fields[1], 10, 64)
        recvErr, _ := strconv.ParseUint(fields[2], 10, 64)
        sendByte, _ := strconv.ParseUint(fields[8], 10, 64)
        sendPkg, _ := strconv.ParseUint(fields[9], 10, 64)
        sendErr, _ := strconv.ParseUint(fields[10], 10, 64)

        //根据网卡名得到对应的网络接口
        netifi, err := net.InterfaceByName(ethname)
        if err != nil {
            continue
        }
        var addrs []net.Addr
        addrs, err = netifi.Addrs()
        if err != nil {
            continue
        }
        if len(addrs) == 0 {
            continue
        }
        moniTag := true
        for _, addr := range addrs {
            cidr := addr.String()
            if strings.Contains(cidr, "0.0.0.0") || strings.Contains(cidr, "127.0.0.1") {
                //0.0.0.0 127.0.0.1 不监控
                moniTag = false
                break
            }
        }
        if moniTag == false {
            continue
        }
        _, exists := this.IfiMap[ethname]
        if !exists {
            this.IfiMap[ethname] = &Ifi{}
            this.IfiNames = append(this.IfiNames, ethname)
        }
        ifi, _ := this.IfiMap[ethname]

        var (
            recvByteAvg float64
            recvPkgAvg  float64
            recvErrRate float64
            sendByteAvg float64
            sendPkgAvg  float64
            sendErrRate float64
        )
        now := time.Now().Unix()
        difftime := float64(now - ifi.Last)
        if ifi.Last == 0 {
            //第一次采集,没有时间差,不计算
        } else {
            if difftime > 0 {
                recvByteAvg = float64(recvByte-ifi.RecvByte) / difftime //平均每秒接收字节数
                recvPkgAvg = float64(recvPkg-ifi.RecvPkg) / difftime    //平均每秒接收正确的包数
                if recvPkg-ifi.RecvPkg > 0 {
                    recvErrRate = float64(recvErr-ifi.RecvErr) / float64(recvPkg-ifi.RecvPkg) //一个周期收包错误率
                }
                sendByteAvg = float64(sendByte-ifi.SendByte) / difftime //平均每秒发送字节数
                sendPkgAvg = float64(sendPkg-ifi.SendPkg) / difftime    //平均每秒发送正确的包数
                if sendPkg-ifi.SendPkg > 0 {
                    sendErrRate = float64(sendErr-ifi.SendErr) / float64(sendPkg-ifi.SendPkg) //一个周期发包错误率
                }
            }
        }

        ifi.Name = ethname
        ifi.Ip = addrs[0].String()
        ifi.RecvByte = recvByte
        ifi.RecvPkg = recvPkg
        ifi.RecvErr = recvErr
        ifi.SendByte = sendByte
        ifi.SendPkg = sendPkg
        ifi.SendErr = sendErr
        ifi.RecvByteAvg = recvByteAvg
        ifi.SendByteAvg = sendByteAvg
        ifi.RecvErrRate = recvErrRate
        ifi.SendErrRate = sendErrRate
        ifi.RecvPkgAvg = recvPkgAvg
        ifi.SendPkgAvg = sendPkgAvg
        ifi.Last = now

        if ifi.IsInEth() {
            //内网
            this.InRecvByteSum += recvByteAvg
            this.InSendByteSum += sendByteAvg
            this.InRecvPkgSum += recvPkgAvg
            this.InSendPkgSum += sendPkgAvg
            this.InRecvErrRateSum += recvErrRate
            this.InSendErrRateSum += sendErrRate
        } else {
            //外网
            this.OutRecvByteSum += recvByteAvg
            this.OutSendByteSum += sendByteAvg
            this.OutRecvPkgSum += recvPkgAvg
            this.OutSendPkgSum += sendPkgAvg
            this.OutRecvErrRateSum += recvErrRate
            this.InSendErrRateSum += sendErrRate
        }

        this.RecvByteSum += recvByteAvg
        this.SendByteSum += sendByteAvg
        this.RecvSendDetail += ifi.Ip + "=" + ifi.Name + "=(" + strconv.FormatFloat(recvByteAvg, 'f', 0, 64) + "|" +
            strconv.FormatFloat(sendByteAvg, 'f', 0, 64) + ")$"

        cmd := fmt.Sprintf("/sbin/ethtool %s 2>/dev/null", ethname)
        output, err := Exec(cmd)
        if err != nil {
            continue
        }
        lines := strings.Split(output, "\n")
        for _, line := range lines {
            if strings.Contains(line, "Speed") {
                fields := strings.Split(line, ":")
                if len(fields) != 2 {
                    continue
                }
                field2 := fields[1]
                Trim(&field2)
                field2 = strings.Replace(field2, "Mb/s", "", -1)
                speed, err := strconv.ParseFloat(field2, 64) //Mb/s, 注意是小b
                if err != nil {
                    continue
                }
                ifi.Speed = speed
                if speed > 0 {
                    inEthUseRate := float64(recvByteAvg*8*100) / float64(speed*1024*1024)
                    if inEthUseRate > this.EthInMaxUseRate {
                        this.EthInMaxUseRate = inEthUseRate
                    }
                    outEthUseRate := float64(sendByteAvg*8*100) / float64(speed*1024*1024)
                    if outEthUseRate > this.EthOutMaxUseRate {
                        this.EthOutMaxUseRate = outEthUseRate
                    }
                }
                break
            }
        }
        this.ModelDetail += ifi.Name + "|" + ifi.Ip + "|" + FloatToString(ifi.Speed) + "$"
    }
    return nil
}

//外网收包错误率
func (this *NetWork) OutRecvErrRateSumFunc(args string) string {
    return FloatToString(this.OutRecvErrRateSum)
}

================================================

package main

import ( "github.com/lycclsltt/system" )

func main() { net := &system.NetWork{} net.Collect()

println("外网网卡流入流量", net.OutEthRecvByteAvgFunc(""), "byte/s")

}

我想上面这样写,编译执行一直报下面的错误 [root@Test-Machine5 tmp]# ./main panic: assignment to entry in nil map

goroutine 1 [running]: github.com/lycclsltt/system.(NetWork).InitNetWorkInfo(0xc42003beb8, 0x0, 0x0) D:/project/src/github.com/lycclsltt/system/net.go:196 +0x1261 github.com/lycclsltt/system.(NetWork).Collect(0xc42003beb8, 0xc420096000, 0x0) D:/project/src/github.com/lycclsltt/system/net.go:104 +0xdc main.main() D:/project/src/check_machine/main/main.go:17 +0x8b

已邀请:

bfcaicai - 向往niubility...

赞同来自:

IfiMap 没有初始化吧

hedakui - 90后it男

赞同来自:

IfiMap 这个Map 没有初始化导致报错

要回复问题请先登录注册