关于将 yaml 解组为结构的错误

Posted

技术标签:

【中文标题】关于将 yaml 解组为结构的错误【英文标题】:A bug about Unmarshal yaml into struct 【发布时间】:2021-01-11 00:38:17 【问题描述】:

我想解组一个 []byte 变量 int struct prometheusyml。这里是promethuesyml和[]byte变量的定义。

type prometheusyml struct 
        Global        global          `yaml:"global,omitempty"`
        ScrapeConfigs []scrapeConfigs `yaml:"scrape_configs,omitempty"`


type global struct 
        ScrapeInterval     string `yaml:"scrape_interval,omitempty"`
        EvaluationInterval string `yaml:"evaluation_interval,omitempty"`


type scrapeConfigs struct 
        JobNmaes        string            `yaml:"job_name,omitempty"`
        RelabelConfigs  []relabelConfigs  `yaml:"relabel_configs,omitempty"`
        MetricsPath     string            `yaml:"metrics_path,omitempty"`
        Scheme          string            `yaml:"scheme,omitempty"`
        ConsulSdConfigs []consulSdConfigs `yaml:"consul_sd_configs,omitempty"`


type relabelConfigs struct 
        SourceLabels string `yaml:"source_labels,omitempty"`
        Action       string `yaml:"action,omitempty"`
        Regex        string `yaml:"regex,omitempty"`
        Replacement  string `yaml:"replacement,omitempty"`
        TargetLabel  string `yaml:"target_label,omitempty"`


type consulSdConfigs struct 
        Server   string   `yaml:"server,omitempty"`
        Services []string `yaml:"services,omitempty"`


# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).


scrape_configs:
  - job_name: 'consul'
    relabel_configs:
        - source_labels:  ["__meta_consul_service"]
          action: replace
          regex: "(.*)"
          replacement: '$1'
          target_label: "service"
        - source_labels: ["__meta_consul_tags"]
          action: replace
          regex: ',(?:[^,]+,)0([^=]+)=([^,]+),.*'
          replacement: '$2'
          target_label: '$1'
        - source_labels: ["__meta_consul_tags"]
          action: replace
          regex: ',(?:[^,]+,)1([^=]+)=([^,]+),.*'
          replacement: '$2'
          target_label: '$1'
        - source_labels: ["__meta_consul_tags"]
          action: replace
          regex: ',(?:[^,]+,)2([^=]+)=([^,]+),.*'
          replacement: '$2'
          target_label: '$1'
    metrics_path: /metrics
    scheme: http
    consul_sd_configs:
        - server: 192.168.0.101:8500
          services:
              - cfs

但是当我运行程序时。它显示了错误,这意味着 source_labels 无法解组到结构中。很可能 ["__meta_consul_tags"] 不能翻译成字符串!!!!但是我应该怎么做才能修复这个错误?实际的类型是什么?

line 11: cannot unmarshal !!seq into string

【问题讨论】:

您将应该用SourceLabels 填充的字段声明为string,但您尝试将其传递给["__meta_consul_service"]。既然名字是复数,你的意思不是一片字符串吗?这可以通过将行更改为SourceLabels []string `yaml:"source_labels,omitempty"` 来实现 【参考方案1】:

relabel_configs 中的source_labels 显然是string 的数组。因此,您必须将SourceLabels 中的data typestring 替换为[]string。那你就可以走了。

type relabelConfigs struct 
    SourceLabels []string `yaml:"source_labels,omitempty"`
    Action       string   `yaml:"action,omitempty"`
    Regex        string   `yaml:"regex,omitempty"`
    Replacement  string   `yaml:"replacement,omitempty"`
    TargetLabel  string   `yaml:"target_label,omitempty"`

只需更改此设置即可解决您的问题。

【讨论】:

以上是关于关于将 yaml 解组为结构的错误的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SOAP XML 解组为 Java 对象 [重复]

json:无法将字符串解组为 MyMap.map 类型的 Go 值

将 json 数组解组为 go struct(数组在 JSON 字符串的中间

当 JSON 字段键是日期时,如何将 JSON 对象解组为 Golang 结构?

yaml:使用 go 时解组错误

部分 JSON 在 Go 中解组为地图