首页 > 解决方案 > 解析文件中的数据时地图大小不同的地图

问题描述

我正在为 Nagios 构建一个受此项目启发的 API 。我已经开始重新创建读取 status.dat 文件并将数据存储在多个对象中的代码,然后这些对象用于创建 core.py 文件中的主机、服务、信息字典。

下面是我的 Python 代码的 Go 版本,它似乎按预期工作。它仍处于早期阶段,因此我对任何编码不良做法表示歉意。

var mu = &sync.RWMutex{}

func openStatusFile() *os.File {
    file, err := os.Open("/usr/local/nagios/var/status.dat")
    if err != nil {
    }
    return file
}

func nextStanza() <-chan map[string]string {

    myChannel := make(chan map[string]string)

    scanner := bufio.NewScanner(openStatusFile())

    current := make(map[string]string)

    go func() {
        for scanner.Scan() {
            mainline := scanner.Text()
            line := strings.TrimSpace(mainline)
            if strings.HasSuffix(line, "{") {
                if len(current) != 0 {
                    myChannel <- current
                }
                result := strings.SplitN(line, " ", 2)
                mu.Lock()
                current["type"] = result[0]
                mu.Unlock()
            } else if strings.Contains(line, "=") {
                result := strings.SplitN(line, "=", 2)
                key := result[0]
                val := result[1]
                mu.Lock()
                current[key] = val
                mu.Unlock()
            }
        }
        close(myChannel)
    }()
    return myChannel
}

在主函数中,我创建了我的嵌套地图,暂时只保存主机数据,这完成了,没有任何抱怨。我遇到的问题是,当我检查此地图的长度时,我希望看到 104 个主机,但每次运行此测试文件时都会得到不同的结果。

func main() {

    hoststatus := nextStanza()

    hosts := make(map[string]map[string]string)
    // services := make(map[string]map[string]map[string]string)
    var host string
    // var service string

    for obj := range hoststatus {
        var hostPlaceHolder string
        var typePlaceHolder string

        mu.Lock()
        hostPlaceHolder = obj["host_name"]
        mu.Unlock()

        if hostPlaceHolder != "" {
            host = hostPlaceHolder
        }

        mu.Lock()
        typePlaceHolder = obj["type"]
        mu.Unlock()

        if typePlaceHolder == "hoststatus" {
            mu.Lock()
            hosts[host] = obj
            mu.Unlock()
        }
    }
    fmt.Println(len(hosts))
}

首轮:

$ go run -race mytest.go
93

第二次运行:

$ go run -race mytest.go
95

第三轮:

$ go run -race mytest.go
63

你明白了。

我觉得问题与地图有关,因为如果我只是打印主机而不将它们放入地图中,我会看到所有我期待的主机。每次运行时地图大小不同的原因是什么?

标签: gonagios

解决方案


我能够通过在将current地图发送到频道后清空地图来解决我的问题。

myChannel <- current
current = make(map[string]string)

然后在循环main()之后的函数中for obj := range hoststatus,我将这些数据放入一个单独的映射中,然后从中工作。

hostStatusMap := make(map[string]string)
    for k, v := range obj {
        hostStatusMap[k] = v
    }

我还能够删除散布在代码中的锁,现在它在每次运行时返回正确的主机长度。


推荐阅读