Я использую Go для сбора различных характеристик perfmon и хотел бы привести их к чему-то похожему на модель EAV, но изо всех сил пытаюсь обернуть мой мозг вокруг того, как это сделать sh.
с учетом приведенных примеров структур:
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 различных операторов case с 17 различными блоками логики "pivot" c в этих случаях. Я знаю, что делаю что-то не так. По сути, я пытаюсь написать функцию, которая будет принимать структуру / интерфейс, определять тип через утверждение типа, а затем использовать этот объект для итерации полей структуры, чтобы преобразовать их в однородный формат. Где я go откуда я сейчас нахожусь?