【发布时间】:2020-02-02 21:25:02
【问题描述】:
我正在使用 Go 来收集各种 perfmon 统计数据,并希望将它们标准化为类似 E-A-V 模型的东西,但我正在努力思考如何实现这一目标。
鉴于这些示例结构:
type Win32_PerfFormattedData_Counters_ProcessorInformation struct {
Name string
C1TransitionsPersec uint64
C2TransitionsPersec uint64
C3TransitionsPersec uint64
PercentUserTime uint64
PercentInterruptTime uint64
PercentPrivilegedTime uint64
PercentC1Time uint64
PercentC2Time uint64
PercentC3Time uint64
}
type Win32_PerfFormattedData_Tcpip_NetworkAdapter struct {
Name string
BytesSentPersec uint64
BytesReceivedPersec uint64
OffloadedConnections uint64
PacketsOutboundDiscarded uint64
PacketsOutboundErrors uint64
PacketsReceivedDiscarded uint64
PacketsReceivedErrors uint64
}
我想将它们标准化为:
type Counter struct {
counter_category string
counter_name string
counter_instance string
counter_value uint64
}
使用reflect我已经能够想出这个:
func pivot(cpu_info *[]Counter, cpu Win32_PerfFormattedData_Counters_ProcessorInformation, category string) {
e := reflect.ValueOf(&cpu).Ellem()
for i := 0; i < e.NumField(); i++ {
f_name := e.Type().Field(i).Name
f_value := e.Field(i).Interface()
if f_name != "Name" {
c := Counter {
counter_category: category,
counter_name: f_name,
counter_instance: cpu.Name,
counter_value: f_value.(uint64),
}
*cpu_info = append(*cpu_info,c)
}
}
}
但是,我正在收集 17 个计数器类别,我不认为编写其中的 17 个函数是最好的主意(除非它是并且我很高兴得到纠正)。
我已经用一个使用接口的函数走了这么远,但我只是不知道我是否走在正确的道路上:
func pivot_counter(counter interface{}, counter_info *[]Counter) {
var counter_category string
switch t := counter.(type) {
case []Win32_PerfFormattedData_Counters_ProcessorInformation:
counter_category = "Processor"
fmt.Printf("%T\r\n",t)
case []Win32_PerfRawData_Tcpip_NetworkAdapter:
counter_category = "Network Adapter"
fmt.Printf("%T\r\n",t)
default:
counter_category = "Unknown"
fmt.Printf("%T\r\n", t)
}
}
但这就是我卡住的地方,因为我仍然需要在这些案例中创建 17 个不同的案例语句,其中包含 17 个不同的“枢轴”逻辑块。我知道我做错了什么。我实际上是在尝试编写一个函数,该函数将接受结构/接口,通过类型断言确定类型,然后使用该对象迭代结构字段以将它们转换为同质格式。我该从我目前所在的地方去哪里?
【问题讨论】: