Какой лучший способ создать структуры go для удаления следующего файла yaml?

Я распаковываю файл yaml snmp.yml. и мне было интересно, смогу ли я получить предложения по созданию лучших структур. Это то, что у меня есть на данный момент, но я предполагаю, что структуры, которые я создаю для Metric, хороши, но SNMPyaml нуждается в лучшей реструктуризации, чтобы полностью иметь возможность правильно использовать неупорядоченные данные.

Любые предложения / отзывы здесь высоко ценится. Заранее спасибо!

package system

import (
    "fmt"
    "io/ioutil"
    "log"
    "path/filepath"

    y "gopkg.in/yaml.v2"
)

//SNMPyaml struct
type SNMPyaml struct {
    Metrics Metric `yaml:"metrics"`
}

//Metric exportable
type Metric struct {
    Name string `yaml:"name,omitempty"`
    Oid  string `yaml:"oid"`
    Type string `yaml:"type"`
    Help string `yaml:"help,omitempty"`
}

// Yamlparser 
func Yamlparser() {
    // Read the snmp.yml file
    absPath, _ := filepath.Abs("./app/snmp.yml")
    yamlFile, yamlerror := ioutil.ReadFile(absPath)
    if yamlerror != nil {
        log.Fatalf("ioutil err: %v", yamlerror)
    }

    //Unmarshall

    var c SNMPyaml
    err := y.Unmarshal(yamlFile, &c)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Print(c)

}
  metrics:
  - name: sysStatClientCurConns
    oid: 1.3.6.1.4.1.3375.2.1.1.2.1.8
    type: gauge
    indexes:
      - labelname: sysStatClientCurConns
        type: gauge
  - name: sysClientsslStatCurConns
    oid: 1.3.6.1.4.1.3375.2.1.1.2.9.2
    type: gauge
    indexes:
      - labelname: sysClientsslStatCurConns
        type: gauge
  - name: sysClientSslStatTotNativeConns
    oid: 1.3.6.1.4.1.3375.2.1.1.2.9.6
    type: gauge
    indexes:
      - labelname: sysClientSslStatTotNativeConns
        type: gauge

Ошибка, которую я получаю за это:

    2019/07/31 23:25:58 yaml: line 25: mapping values are not allowed in this context
    exit status 1

1 ответ

В вашем входе metrics последовательность (список), поэтому вы не можете объединить это в один Metric, Используйте ломтик: []Metric:

type SNMPyaml struct {
    Metrics []Metric `yaml:"metrics"`
}

Также есть indexes поле, другая последовательность, которой у вас нет соответствующего поля в вашем Metric структура, и у вас есть ненужные Help (по крайней мере в указанном вами входе нет такого поля):

type Metric struct {
    Name    string  `yaml:"name,omitempty"`
    Oid     string  `yaml:"oid"`
    Type    string  `yaml:"type"`
    Indexes []Index `yaml:"indexes"`
}

Где индексы могут быть смоделированы с этой структурой:

type Index struct {
    LabelName string `yaml:"labelname"`
    Type      string `yaml:"type"`
}

С этими изменениями он запускается, попробуйте на Go Playground и получите следующий вывод:

{[{sysStatClientCurConns 1.3.6.1.4.1.3375.2.1.1.2.1.8 gauge [{sysStatClientCurConns gauge}]} {sysClientsslStatCurConns 1.3.6.1.4.1.3375.2.1.1.2.9.2 gauge [{sysClientsslStatCurConsativeSlatSatSatSatSatSatSatTatSatTatS]}} 1.3.6.1.4.1.3375.2.1.1.2.9.6 gauge [{sysClientSslStatTotNativeConns gauge}]}]}

Также обратите внимание, что есть онлайн-конвертер YAML-to-Go, где вы вводите свой источник YAML, и он создает структуры данных Go, моделирующие ваш ввод: https://mengzhuo.github.io/yaml-to-go/

В сгенерированном коде используются безымянные структуры (что очень неудобно, если вам нужно создавать значения), но это хорошая отправная точка, и вы можете легко преобразовать их в именованные типы. Он производит следующую модель из вашего ввода YAML:

type AutoGenerated struct {
    Metrics []struct {
        Name    string `yaml:"name"`
        Oid     string `yaml:"oid"`
        Type    string `yaml:"type"`
        Indexes []struct {
            Labelname string `yaml:"labelname"`
            Type      string `yaml:"type"`
        } `yaml:"indexes"`
    } `yaml:"metrics"`
}
Другие вопросы по тегам