无法使用Go和BurntSushi库读取TOML文件。

huangapple go评论86阅读模式
英文:

Not able to read TOML file using Go with BurntSushi library

问题

我正在使用BurntSushi库在我的GO应用程序中加载一个TOML配置文件。我已经按照该库的说明编写了结构体和配置文件本身。我遇到了一些问题,但似乎找不到问题的根源。

以下是详细信息:

结构体:

package main

// ConfigurationParameters提供了一个结构体,用于保存配置文件中的配置参数
type ConfigurationParameters struct {
    Title              string
    ServiceDiscovery   ConsulConf `toml:"ServiceDiscovery"`
    MetadataReporting MetaDataConf `toml:"MetadataReporting"`
    AwsTagsToLabels    LabelConf `toml:"AwsTagsToLabels"`
    Collectors         CollectorConf `toml:"Collectors"`
    Service            ServiceConf `toml:"Service"`
}

// ConsulConf捕获了与Consul服务发现注册所需的配置参数
type ConsulConf struct {
    enabled    bool
    endpoint   string
    port       int
    datacenter string
    serviceID  string
}

// MetaDataConf捕获了在Consul中注册的服务的元数据
type MetaDataConf struct {
    enabled   bool
    awsregion string
}

// LabelConf捕获了应作为标签添加到报告的指标的AWS标签
type LabelConf struct {
    enabled       bool
    refreshPeriod int
}

// CollectorConf捕获了要使用的收集器列表
type CollectorConf struct {
    goCollectionEnabled       bool
    exporterCollectionEnabled bool
    wmiCollectionEnabled      bool
    agentCollectionEnabled    bool
    enabledCollectors         string
    metricMap                 []MetricMap
}

// MetricMap捕获了一个或多个WMI指标与其应报告的名称之间的映射关系
type MetricMap struct {
    wmiMetricName  []string
    exportName     string
    dropMetric     bool
    computedMetric bool
    computeLogic   string
}

// ServiceConf捕获了与代理相关的配置
type ServiceConf struct {
    listenIP           string
    listenPort         int
    metricPath         string
    collectionInterval int
    serviceName        string
}

配置文件:

Title = "WMI Exporter Configuration"

[ServiceDiscovery]
    enabled = true
    endpoint = "my.consul.server"
    port = 5500
    datacenter = "ucm-west"
    serviceID = "ucm.agent.wmiExporter"

[MetadataReporting]
    enabled = true
    awsregion = "us-west-2"

[AwsTagsToLabels]
    enabled = true
    refreshPeriod = 3600

[Collectors]
    goCollectionEnabled = true
    exporterCollectionEnabled = true
    wmiCollectionEnabled = true
    agentCollectionEnabled = false
    enabledCollectors   = "cpu,os"
    [Collectors.MetricMap.0]
        wmiMetricName = ["test"]
        exportName = "export_test"

[Service]
    listenPort =  9103
    metricPath = "/metrics"
    collectionInterval = 60
    serviceName = "wmi_exporter"

读取配置文件的代码:

// InitializeFromConfig从配置文件中读取配置参数并初始化此服务
func InitializeFromConfig(configfile string) ConfigurationParameters {
    conf := ConfigurationParameters{}

    if configfile == "" {
        return conf
    }

    _, err := toml.DecodeFile(configfile, &conf)
    if err != nil {
        log.Fatalf("Cannot parse configuration file at %s. Error=%s", configfile, err)
    }
    // 在这一点上,conf是一个完全加载的配置,现在从conf初始化所有内容
    return conf
}

我遇到的问题是,只有Title属性的值被映射到GO结构体成员中。所有其他配置都保持未映射。查看BurntSushi和https://stackoverflow.com/questions/34307488/go-how-to-use-toml-files上的所有示例,我无法看出与我当前在代码中所做的任何区别。

我还使用了BurntSushi包中的tomlv验证器来查看TOML文件中的类型,我认为它们看起来是正确的。

数据类型:

  • Title:String
  • ServiceDiscovery:Hash
    • ServiceDiscovery.enabled:Bool
    • ServiceDiscovery.endpoint:String
    • ServiceDiscovery.port:Integer
    • ServiceDiscovery.datacenter:String
    • ServiceDiscovery.serviceID:String
  • MetadataReporting:Hash
    • MetadataReporting.enabled:Bool
    • MetadataReporting.awsregion:String
  • AwsTagsToLabels:Hash
    • AwsTagsToLabels.enabled:Bool
    • AwsTagsToLabels.refreshPeriod:Integer
  • Collectors:Hash
    • Collectors.goCollectionEnabled:Bool
    • Collectors.exporterCollectionEnabled:Bool
    • Collectors.wmiCollectionEnabled:Bool
    • Collectors.agentCollectionEnabled:Bool
    • Collectors.enabledCollectors:String
    • Collectors.MetricMap.0:Hash
      • Collectors.MetricMap.0.wmiMetricName:Array
      • Collectors.MetricMap.0.exportName:String
  • Service:Hash
    • Service.listenPort:Integer
    • Service.metricPath:String
    • Service.collectionInterval:Integer
    • Service.serviceName:String

我尝试调试BurntSushi包的代码,但没有什么帮助(Delve调试器无法显示该包中的某些变量,并且似乎在该包的行之间随机跳转)。

有关我可能做错的任何帮助或指针?

谢谢。

英文:

I am using the BurntSushi library to load a TOML configuration file in my GO application. I have followed the instructions on the library to write the structs and the configuration toml file itself. I am running into some trouble, and I cant seem to find the source of my issues.

Here are the details:

Structs:

package main
//ConfigurationParameters provides the struct to hold configuration parameters from config file
type ConfigurationParameters struct {
Title string
//serviceDiscovery captures configuration parameters needed for service discovery registration with Consul
ServiceDiscovery ConsulConf `toml:"ServiceDiscovery"`
//metadataReporting captures which metadata to be registered with service into consul for use during discovery
MetadataReporting MetaDataConf `toml:"MetadataReporting"`
//awsTagsToLabels captures the aws tags that should be added to reported metrics as Labels
AwsTagsToLabels LabelConf `toml:"AwsTagsToLabels"`
//collectors captures the list of collectors to use
Collectors CollectorConf `toml:"Collectors"`
//service captures agent related configurations
Service ServiceConf `toml:"Service"`
}
//ConsulConf captures configuration parameters needed for service discovery registration with Consul
type ConsulConf struct {
enabled    bool
endpoint   string
port       int
datacenter string
serviceID  string
}
//MetaDataConf captures which metadata to be registered with service into consul for use during discovery
type MetaDataConf struct {
enabled   bool
awsregion string
}
//LabelConf captures the aws tags that should be added to reported metrics as Labels
type LabelConf struct {
enabled       bool
refreshPeriod int
}
//CollectorConf captures the list of collectors to use
type CollectorConf struct {
goCollectionEnabled       bool
exporterCollectionEnabled bool
wmiCollectionEnabled      bool
agentCollectionEnabled    bool
enabledCollectors         string
metricMap                 []MetricMap
}
//MetricMap captures a mapping between one or more WMI metrics and the name it should be reported with
type MetricMap struct {
wmiMetricName  []string
exportName     string
dropMetric     bool
computedMetric bool
computeLogic   string
}
//ServiceConf captures agent related configurations
type ServiceConf struct {
listenIP           string
listenPort         int
metricPath         string
collectionInterval int
serviceName        string
}

and the configuration toml file:

Title = "WMI Exporter Configuration"
[ServiceDiscovery]
enabled = true
endpoint = "my.consul.server"
port = 5500
datacenter = "ucm-west"
serviceID = "ucm.agent.wmiExporter"
[MetadataReporting]
enabled = true
awsregion = "us-west-2"
[AwsTagsToLabels]
enabled = true
refreshPeriod = 3600
[Collectors]
goCollectionEnabled = true
exporterCollectionEnabled = true
wmiCollectionEnabled = true
agentCollectionEnabled = false
enabledCollectors   = "cpu,os"
[Collectors.MetricMap.0]
wmiMetricName = ["test"]
exportName = "export_test"
[Service]
listenPort =  9103
metricPath = "/metrics"
collectionInterval = 60
serviceName = "wmi_exporter"

And the code that reads the config file:

// InitializeFromConfig reads configuration parameters from configuration file and initializes this service
func InitializeFromConfig(configfile string) ConfigurationParameters {
conf := ConfigurationParameters{}
if configfile == "" {
return conf
}
_, err := toml.DecodeFile(configfile, &conf)
if err != nil {
log.Fatalf("Cannot parse configuration file at %s. Error=%s", configfile, err)
}
//at this point, conf is a fully loaded configuration now; now initialize everything from conf
return conf
}

The issue I am facing is that only the value for the Title attribute gets mapped into the GO struct members. All of the other configs stay unmapped. Looking at all of the examples on github for BurntSushi and https://stackoverflow.com/questions/34307488/go-how-to-use-toml-files, I cant see any difference from what I am currently doing in code.

I also used the tomlv validator from the BurntSushi package to look at the types from the TOML file, and I believe they look correct.

Datatypes:

Title                                             String
ServiceDiscovery                                  Hash
ServiceDiscovery.enabled                      Bool
ServiceDiscovery.endpoint                     String
ServiceDiscovery.port                         Integer
ServiceDiscovery.datacenter                   String
ServiceDiscovery.serviceID                    String
MetadataReporting                                 Hash
MetadataReporting.enabled                     Bool
MetadataReporting.awsregion                   String
AwsTagsToLabels                                   Hash
AwsTagsToLabels.enabled                       Bool
AwsTagsToLabels.refreshPeriod                 Integer
Collectors                                        Hash
Collectors.goCollectionEnabled                Bool
Collectors.exporterCollectionEnabled          Bool
Collectors.wmiCollectionEnabled               Bool
Collectors.agentCollectionEnabled             Bool
Collectors.enabledCollectors                  String
Collectors.MetricMap.0                    Hash
Collectors.MetricMap.0.wmiMetricName  Array
Collectors.MetricMap.0.exportName     String
Service                                           Hash
Service.listenPort                            Integer
Service.metricPath                            String
Service.collectionInterval                    Integer
Service.serviceName                           String

I tried debugging into the BurntSushi package code, but it was not very helpful (the Delve debugger was not able to display some of the variables in that package, and seemed to randomly jump between the lines in that package).

Any help or pointers on what I could be doing wrong?

Thanks.

答案1

得分: 2

你需要导出任何你想要BurntSushi/toml解组的字段,包括子字段:

// ConfigurationParameters提供了一个用于保存配置文件中配置参数的结构体
type ConfigurationParameters struct {
    Title              string
    ServiceDiscovery   ConsulConf `toml:"ServiceDiscovery"`
    MetadataReporting MetaDataConf `toml:"MetadataReporting"`
    AwsTagsToLabels    LabelConf `toml:"AwsTagsToLabels"`
    Collectors         CollectorConf `toml:"Collectors"`
    Service            ServiceConf `toml:"Service"`
}

// ConsulConf用于保存与Consul服务发现注册相关的配置参数
type ConsulConf struct {
    Enabled    bool
    Endpoint   string
    Port       int
    Datacenter string
    ServiceID  string
}

// MetaDataConf用于保存要在Consul中注册的与服务相关的元数据
type MetaDataConf struct {
    Enabled   bool
    Awsregion string
}

// LabelConf用于保存作为标签添加到报告的指标中的AWS标签
type LabelConf struct {
    Enabled       bool
    RefreshPeriod int
}

// CollectorConf用于保存要使用的收集器列表
type CollectorConf struct {
    GoCollectionEnabled       bool
    ExporterCollectionEnabled bool
    WmiCollectionEnabled      bool
    AgentCollectionEnabled    bool
    EnabledCollectors         string
    MetricMap                 []MetricMap
}

// MetricMap用于将一个或多个WMI指标与其应报告的名称进行映射
type MetricMap struct {
    WmiMetricName  []string
    ExportName     string
    DropMetric     bool
    ComputedMetric bool
    ComputeLogic   string
}

// ServiceConf用于保存与代理相关的配置
type ServiceConf struct {
    ListenIP           string
    ListenPort         int
    MetricPath         string
    CollectionInterval int
    ServiceName        string
}

此外,我不确定Collectors.MetricMap.0这种语法应该表示什么,但是为了将你的toml值解组到[]MetricMap字段中,你应该这样做:

[[Collectors.MetricMap]]
    wmiMetricName = ["test"]
    exportName = "export_test"
英文:

You need to export any fields that you want BurntSushi/toml to unmarshal into, including subfields:

//ConfigurationParameters provides the struct to hold configuration parameters from config file
type ConfigurationParameters struct {
Title string
//serviceDiscovery captures configuration parameters needed for service discovery registration with Consul
ServiceDiscovery ConsulConf `toml:"ServiceDiscovery"`
//metadataReporting captures which metadata to be registered with service into consul for use during discovery
MetadataReporting MetaDataConf `toml:"MetadataReporting"`
//awsTagsToLabels captures the aws tags that should be added to reported metrics as Labels
AwsTagsToLabels LabelConf `toml:"AwsTagsToLabels"`
//collectors captures the list of collectors to use
Collectors CollectorConf `toml:"Collectors"`
//service captures agent related configurations
Service ServiceConf `toml:"Service"`
}
//ConsulConf captures configuration parameters needed for service discovery registration with Consul
type ConsulConf struct {
Enabled    bool
Endpoint   string
Port       int
Datacenter string
ServiceID  string
}
//MetaDataConf captures which metadata to be registered with service into consul for use during discovery
type MetaDataConf struct {
Enabled   bool
Awsregion string
}
//LabelConf captures the aws tags that should be added to reported metrics as Labels
type LabelConf struct {
Enabled       bool
RefreshPeriod int
}
//CollectorConf captures the list of collectors to use
type CollectorConf struct {
GoCollectionEnabled       bool
ExporterCollectionEnabled bool
WmiCollectionEnabled      bool
AgentCollectionEnabled    bool
EnabledCollectors         string
MetricMap                 []MetricMap
}
//MetricMap captures a mapping between one or more WMI metrics and the name it should be reported with
type MetricMap struct {
WmiMetricName  []string
ExportName     string
DropMetric     bool
ComputedMetric bool
ComputeLogic   string
}
//ServiceConf captures agent related configurations
type ServiceConf struct {
ListenIP           string
ListenPort         int
MetricPath         string
CollectionInterval int
ServiceName        string
}

Also i'm not sure what this Collectors.MetricMap.0 syntax is supposed to represent but to unmarshal your toml values into the []MetricMap field
what you want to do is something like this instead:

[[Collectors.MetricMap]]
wmiMetricName = ["test"]
exportName = "export_test"

huangapple
  • 本文由 发表于 2017年4月5日 06:04:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/43218484.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定