mirror of
				https://github.com/ClusterCockpit/cc-metric-collector.git
				synced 2025-10-31 17:05:07 +01:00 
			
		
		
		
	Allow to send total values per core, socket and node
This commit is contained in:
		| @@ -41,11 +41,14 @@ const ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type LikwidCollectorMetricConfig struct { | type LikwidCollectorMetricConfig struct { | ||||||
| 	Name    string `json:"name"` // Name of the metric | 	Name               string `json:"name"` // Name of the metric | ||||||
| 	Calc    string `json:"calc"` // Calculation for the metric using | 	Calc               string `json:"calc"` // Calculation for the metric using | ||||||
| 	Type    string `json:"type"` // Metric type (aka node, socket, cpu, ...) | 	Type               string `json:"type"` // Metric type (aka node, socket, cpu, ...) | ||||||
| 	Publish bool   `json:"publish"` | 	Publish            bool   `json:"publish"` | ||||||
| 	Unit    string `json:"unit"` // Unit of metric if any | 	SendCoreTotalVal   bool   `json:"send_core_total_values,omitempty"` | ||||||
|  | 	SendSocketTotalVal bool   `json:"send_socket_total_values,omitempty"` | ||||||
|  | 	SendNodeTotalVal   bool   `json:"send_node_total_values,omitempty"` | ||||||
|  | 	Unit               string `json:"unit"` // Unit of metric if any | ||||||
| } | } | ||||||
|  |  | ||||||
| type LikwidCollectorEventsetConfig struct { | type LikwidCollectorEventsetConfig struct { | ||||||
| @@ -79,6 +82,8 @@ type LikwidCollector struct { | |||||||
| 	cpulist       []C.int | 	cpulist       []C.int | ||||||
| 	cpu2tid       map[int]int | 	cpu2tid       map[int]int | ||||||
| 	sock2tid      map[int]int | 	sock2tid      map[int]int | ||||||
|  | 	tid2core      map[int]int | ||||||
|  | 	tid2socket    map[int]int | ||||||
| 	metrics       map[C.int]map[string]int | 	metrics       map[C.int]map[string]int | ||||||
| 	groups        []C.int | 	groups        []C.int | ||||||
| 	config        LikwidCollectorConfig | 	config        LikwidCollectorConfig | ||||||
| @@ -309,24 +314,18 @@ func (m *LikwidCollector) Init(config json.RawMessage) error { | |||||||
| 	m.measureThread = thread.New() | 	m.measureThread = thread.New() | ||||||
| 	switch m.config.AccessMode { | 	switch m.config.AccessMode { | ||||||
| 	case "direct": | 	case "direct": | ||||||
| 		m.measureThread.Call( | 		C.HPMmode(0) | ||||||
| 			func() { |  | ||||||
| 				C.HPMmode(0) |  | ||||||
| 			}) |  | ||||||
| 	case "accessdaemon": | 	case "accessdaemon": | ||||||
| 		if len(m.config.DaemonPath) > 0 { | 		if len(m.config.DaemonPath) > 0 { | ||||||
| 			p := os.Getenv("PATH") | 			p := os.Getenv("PATH") | ||||||
| 			os.Setenv("PATH", m.config.DaemonPath+":"+p) | 			os.Setenv("PATH", m.config.DaemonPath+":"+p) | ||||||
| 		} | 		} | ||||||
| 		m.measureThread.Call( | 		C.HPMmode(1) | ||||||
| 			func() { | 		retCode := C.HPMinit() | ||||||
| 				C.HPMmode(1) | 		if retCode != 0 { | ||||||
| 				retCode := C.HPMinit() | 			err := fmt.Errorf("C.HPMinit() failed with return code %v", retCode) | ||||||
| 				if retCode != 0 { | 			cclog.ComponentError(m.name, err.Error()) | ||||||
| 					err := fmt.Errorf("C.HPMinit() failed with return code %v", retCode) | 		} | ||||||
| 					cclog.ComponentError(m.name, err.Error()) |  | ||||||
| 				} |  | ||||||
| 			}) |  | ||||||
| 		for _, c := range m.cpulist { | 		for _, c := range m.cpulist { | ||||||
| 			m.measureThread.Call( | 			m.measureThread.Call( | ||||||
| 				func() { | 				func() { | ||||||
| @@ -349,6 +348,21 @@ func (m *LikwidCollector) Init(config json.RawMessage) error { | |||||||
| 		C.free(unsafe.Pointer(cstr)) | 		C.free(unsafe.Pointer(cstr)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cpuData := topo.CpuData() | ||||||
|  | 	m.tid2core = make(map[int]int, len(cpuData)) | ||||||
|  | 	m.tid2socket = make(map[int]int, len(cpuData)) | ||||||
|  | 	for i := range cpuData { | ||||||
|  | 		c := &cpuData[i] | ||||||
|  | 		// Hardware thread ID to core ID mapping | ||||||
|  | 		if len(c.CoreCPUsList) > 0 { | ||||||
|  | 			m.tid2core[c.CpuID] = c.CoreCPUsList[0] | ||||||
|  | 		} else { | ||||||
|  | 			m.tid2core[c.CpuID] = c.CpuID | ||||||
|  | 		} | ||||||
|  | 		// Hardware thead ID to socket ID mapping | ||||||
|  | 		m.tid2socket[c.CpuID] = c.Socket | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	m.basefreq = getBaseFreq() | 	m.basefreq = getBaseFreq() | ||||||
| 	m.init = true | 	m.init = true | ||||||
| 	return nil | 	return nil | ||||||
| @@ -537,23 +551,126 @@ func (m *LikwidCollector) calcEventsetMetrics(evset LikwidEventsetConfig, interv | |||||||
| 				} | 				} | ||||||
| 				evset.metrics[tid][metric.Name] = value | 				evset.metrics[tid][metric.Name] = value | ||||||
| 				// Now we have the result, send it with the proper tags | 				// Now we have the result, send it with the proper tags | ||||||
| 				if !math.IsNaN(value) { | 				if !math.IsNaN(value) && metric.Publish { | ||||||
| 					if metric.Publish { | 					fields := map[string]interface{}{"value": value} | ||||||
| 						fields := map[string]interface{}{"value": value} | 					y, err := lp.New(metric.Name, map[string]string{"type": metric.Type}, m.meta, fields, time.Now()) | ||||||
| 						y, err := lp.New(metric.Name, map[string]string{"type": metric.Type}, m.meta, fields, time.Now()) | 					if err == nil { | ||||||
| 						if err == nil { | 						if metric.Type != "node" { | ||||||
| 							if metric.Type != "node" { | 							y.AddTag("type-id", fmt.Sprintf("%d", domain)) | ||||||
| 								y.AddTag("type-id", fmt.Sprintf("%d", domain)) |  | ||||||
| 							} |  | ||||||
| 							if len(metric.Unit) > 0 { |  | ||||||
| 								y.AddMeta("unit", metric.Unit) |  | ||||||
| 							} |  | ||||||
| 							output <- y |  | ||||||
| 						} | 						} | ||||||
|  | 						if len(metric.Unit) > 0 { | ||||||
|  | 							y.AddMeta("unit", metric.Unit) | ||||||
|  | 						} | ||||||
|  | 						output <- y | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		// Send per core aggregated values | ||||||
|  | 		if metric.SendCoreTotalVal { | ||||||
|  | 			now := time.Now() | ||||||
|  | 			totalCoreValues := make(map[int]float64) | ||||||
|  | 			for _, tid := range scopemap { | ||||||
|  | 				if tid >= 0 && len(metric.Calc) > 0 { | ||||||
|  | 					coreID := m.tid2core[tid] | ||||||
|  | 					value := evset.metrics[tid][metric.Name] | ||||||
|  | 					if !math.IsNaN(value) && metric.Publish { | ||||||
|  | 						totalCoreValues[coreID] += value | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			for coreID, value := range totalCoreValues { | ||||||
|  | 				y, err := lp.New( | ||||||
|  | 					metric.Name, | ||||||
|  | 					map[string]string{ | ||||||
|  | 						"type":    "core", | ||||||
|  | 						"type-id": fmt.Sprintf("%d", coreID), | ||||||
|  | 					}, | ||||||
|  | 					m.meta, | ||||||
|  | 					map[string]interface{}{ | ||||||
|  | 						"value": value, | ||||||
|  | 					}, | ||||||
|  | 					now, | ||||||
|  | 				) | ||||||
|  | 				if err != nil { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 				if len(metric.Unit) > 0 { | ||||||
|  | 					y.AddMeta("unit", metric.Unit) | ||||||
|  | 				} | ||||||
|  | 				output <- y | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Send per socket aggregated values | ||||||
|  | 		if metric.SendSocketTotalVal { | ||||||
|  | 			now := time.Now() | ||||||
|  | 			totalSocketValues := make(map[int]float64) | ||||||
|  | 			for _, tid := range scopemap { | ||||||
|  | 				if tid >= 0 && len(metric.Calc) > 0 { | ||||||
|  | 					socketID := m.tid2socket[tid] | ||||||
|  | 					value := evset.metrics[tid][metric.Name] | ||||||
|  | 					if !math.IsNaN(value) && metric.Publish { | ||||||
|  | 						totalSocketValues[socketID] += value | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			for socketID, value := range totalSocketValues { | ||||||
|  | 				y, err := lp.New( | ||||||
|  | 					metric.Name, | ||||||
|  | 					map[string]string{ | ||||||
|  | 						"type":    "socket", | ||||||
|  | 						"type-id": fmt.Sprintf("%d", socketID), | ||||||
|  | 					}, | ||||||
|  | 					m.meta, | ||||||
|  | 					map[string]interface{}{ | ||||||
|  | 						"value": value, | ||||||
|  | 					}, | ||||||
|  | 					now, | ||||||
|  | 				) | ||||||
|  | 				if err != nil { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 				if len(metric.Unit) > 0 { | ||||||
|  | 					y.AddMeta("unit", metric.Unit) | ||||||
|  | 				} | ||||||
|  | 				output <- y | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Send per node aggregated value | ||||||
|  | 		if metric.SendNodeTotalVal { | ||||||
|  | 			now := time.Now() | ||||||
|  | 			var totalNodeValue float64 = 0.0 | ||||||
|  | 			for _, tid := range scopemap { | ||||||
|  | 				if tid >= 0 && len(metric.Calc) > 0 { | ||||||
|  | 					value := evset.metrics[tid][metric.Name] | ||||||
|  | 					if !math.IsNaN(value) && metric.Publish { | ||||||
|  | 						totalNodeValue += value | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			y, err := lp.New( | ||||||
|  | 				metric.Name, | ||||||
|  | 				map[string]string{}, | ||||||
|  | 				m.meta, | ||||||
|  | 				map[string]interface{}{ | ||||||
|  | 					"value": totalNodeValue, | ||||||
|  | 				}, | ||||||
|  | 				now, | ||||||
|  | 			) | ||||||
|  | 			if err != nil { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			if len(metric.Unit) > 0 { | ||||||
|  | 				y.AddMeta("unit", metric.Unit) | ||||||
|  | 			} | ||||||
|  | 			output <- y | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user