mirror of
https://github.com/ClusterCockpit/cc-metric-collector.git
synced 2025-12-20 06:06:16 +01:00
Compare commits
25 Commits
v0.7.2
...
diskstat_i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b77d9a6cf0 | ||
|
|
6b10797556 | ||
|
|
f964a9d065 | ||
|
|
8c5a3cc07b | ||
|
|
4804576ad6 | ||
|
|
623391d271 | ||
|
|
6af85fe52f | ||
|
|
dd62929b42 | ||
|
|
88588ca80b | ||
|
|
0cc01c93c1 | ||
|
|
412ae24b20 | ||
|
|
40fd936f48 | ||
|
|
a9b301b7d4 | ||
|
|
a5a0474573 | ||
|
|
c85c4eeb21 | ||
|
|
e03e21021d | ||
|
|
0e730c9720 | ||
|
|
eb452770a5 | ||
|
|
f060a1bb17 | ||
|
|
f8b2ac0d2c | ||
|
|
ec34b40295 | ||
|
|
8ccbb4f69c | ||
|
|
f90c2698e3 | ||
|
|
ee4e1baf5b | ||
|
|
94c80307e8 |
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "gomod"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
17
README.md
17
README.md
@@ -32,13 +32,15 @@ There is a main configuration file with basic settings that point to the other c
|
|||||||
|
|
||||||
``` json
|
``` json
|
||||||
{
|
{
|
||||||
"sinks": "sinks.json",
|
"sinks-file": "sinks.json",
|
||||||
"collectors" : "collectors.json",
|
"collectors-file" : "collectors.json",
|
||||||
"receivers" : "receivers.json",
|
"receivers-file" : "receivers.json",
|
||||||
"router" : "router.json",
|
"router-file" : "router.json",
|
||||||
|
"main": {
|
||||||
"interval": "10s",
|
"interval": "10s",
|
||||||
"duration": "1s"
|
"duration": "1s"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `interval` defines how often the metrics should be read and send to the sink. The `duration` tells collectors how long one measurement has to take. This is important for some collectors, like the `likwid` collector. For more information, see [here](./docs/configuration.md).
|
The `interval` defines how often the metrics should be read and send to the sink. The `duration` tells collectors how long one measurement has to take. This is important for some collectors, like the `likwid` collector. For more information, see [here](./docs/configuration.md).
|
||||||
@@ -52,11 +54,14 @@ See the component READMEs for their configuration:
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
Dependecies:
|
||||||
|
- golang
|
||||||
|
- hwloc
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone git@github.com:ClusterCockpit/cc-metric-collector.git
|
$ git clone git@github.com:ClusterCockpit/cc-metric-collector.git
|
||||||
|
$ export CGO_LDFLAGS="-L/path/to/hwloc/lib/dir"
|
||||||
$ make (downloads LIKWID, builds it as static library with 'direct' accessmode and copies all required files for the collector)
|
$ make (downloads LIKWID, builds it as static library with 'direct' accessmode and copies all required files for the collector)
|
||||||
$ go get (requires at least golang 1.16)
|
|
||||||
$ make
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information, see [here](./docs/building.md).
|
For more information, see [here](./docs/building.md).
|
||||||
|
|||||||
@@ -23,13 +23,22 @@ const MOUNTFILE = `/proc/self/mounts`
|
|||||||
|
|
||||||
type DiskstatCollectorConfig struct {
|
type DiskstatCollectorConfig struct {
|
||||||
ExcludeMetrics []string `json:"exclude_metrics,omitempty"`
|
ExcludeMetrics []string `json:"exclude_metrics,omitempty"`
|
||||||
ExcludeMounts []string `json:"exclude_mounts,omitempty"`
|
ExcludeDevices []string `json:"exclude_devices,omitempty"`
|
||||||
|
ExcludeMountpoints []string `json:"exclude_mountpoints,omitempty"`
|
||||||
|
IncludeDevices []string `json:"include_devices,omitempty"`
|
||||||
|
IncludeMountpoints []string `json:"include_mountpoints,omitempty"`
|
||||||
|
UseMountpoint bool `json:"mountpoint_as_stype,omitempty"`
|
||||||
|
UseIncludeConfig bool `json:"use_include_config,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiskstatCollector struct {
|
type DiskstatCollector struct {
|
||||||
metricCollector
|
metricCollector
|
||||||
config DiskstatCollectorConfig
|
config DiskstatCollectorConfig
|
||||||
allowedMetrics map[string]bool
|
allowedMetrics map[string]bool
|
||||||
|
includeDevices map[string]bool
|
||||||
|
includeMountpoints map[string]bool
|
||||||
|
excludeDevices map[string]bool
|
||||||
|
excludeMountpoints map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DiskstatCollector) Init(config json.RawMessage) error {
|
func (m *DiskstatCollector) Init(config json.RawMessage) error {
|
||||||
@@ -37,6 +46,7 @@ func (m *DiskstatCollector) Init(config json.RawMessage) error {
|
|||||||
m.parallel = true
|
m.parallel = true
|
||||||
m.meta = map[string]string{"source": m.name, "group": "Disk"}
|
m.meta = map[string]string{"source": m.name, "group": "Disk"}
|
||||||
m.setup()
|
m.setup()
|
||||||
|
m.config.UseIncludeConfig = false
|
||||||
if len(config) > 0 {
|
if len(config) > 0 {
|
||||||
if err := json.Unmarshal(config, &m.config); err != nil {
|
if err := json.Unmarshal(config, &m.config); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -52,12 +62,50 @@ func (m *DiskstatCollector) Init(config json.RawMessage) error {
|
|||||||
m.allowedMetrics[excl] = false
|
m.allowedMetrics[excl] = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(MOUNTFILE)
|
file, err := os.Open(MOUNTFILE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cclog.ComponentError(m.name, err.Error())
|
cclog.ComponentError(m.name, err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
availDevices := make(map[string]struct{})
|
||||||
|
availMpoints := make(map[string]struct{})
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if len(line) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
linefields := strings.Fields(line)
|
||||||
|
availDevices[linefields[0]] = struct{}{}
|
||||||
|
availMpoints[linefields[1]] = struct{}{}
|
||||||
|
}
|
||||||
|
m.includeDevices = make(map[string]bool)
|
||||||
|
for _, incl := range m.config.IncludeDevices {
|
||||||
|
if _, ok := availDevices[incl]; ok {
|
||||||
|
m.includeDevices[incl] = true
|
||||||
|
} else {
|
||||||
|
cclog.ComponentWarn(m.name, "Included Mount device ", incl, " does not exist")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.includeMountpoints = make(map[string]bool)
|
||||||
|
for _, incl := range m.config.IncludeMountpoints {
|
||||||
|
if _, ok := availMpoints[incl]; ok {
|
||||||
|
m.includeMountpoints[incl] = true
|
||||||
|
} else {
|
||||||
|
cclog.ComponentWarn(m.name, "Included Mount point ", incl, " does not exist")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.excludeMountpoints = make(map[string]bool)
|
||||||
|
for _, excl := range m.config.ExcludeMountpoints {
|
||||||
|
m.excludeMountpoints[excl] = true
|
||||||
|
}
|
||||||
|
m.excludeDevices = make(map[string]bool)
|
||||||
|
for _, excl := range m.config.ExcludeDevices {
|
||||||
|
m.excludeDevices[excl] = true
|
||||||
|
}
|
||||||
|
|
||||||
m.init = true
|
m.init = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -75,6 +123,8 @@ func (m *DiskstatCollector) Read(interval time.Duration, output chan lp.CCMessag
|
|||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
part_max_used := uint64(0)
|
part_max_used := uint64(0)
|
||||||
|
part_max_used_device := ""
|
||||||
|
part_max_used_mountpoint := ""
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(file)
|
||||||
mountLoop:
|
mountLoop:
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
@@ -82,9 +132,9 @@ mountLoop:
|
|||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(line, "/dev") {
|
// if !strings.HasPrefix(line, "/dev") {
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
linefields := strings.Fields(line)
|
linefields := strings.Fields(line)
|
||||||
if strings.Contains(linefields[0], "loop") {
|
if strings.Contains(linefields[0], "loop") {
|
||||||
continue
|
continue
|
||||||
@@ -95,8 +145,16 @@ mountLoop:
|
|||||||
|
|
||||||
mountPath := strings.Replace(linefields[1], `\040`, " ", -1)
|
mountPath := strings.Replace(linefields[1], `\040`, " ", -1)
|
||||||
|
|
||||||
for _, excl := range m.config.ExcludeMounts {
|
if m.config.UseIncludeConfig {
|
||||||
if strings.Contains(mountPath, excl) {
|
_, ok1 := m.includeDevices[linefields[0]]
|
||||||
|
_, ok2 := m.includeMountpoints[linefields[1]]
|
||||||
|
if !(ok1 || ok2) {
|
||||||
|
continue mountLoop
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, ok1 := m.excludeDevices[linefields[0]]
|
||||||
|
_, ok2 := m.excludeMountpoints[linefields[1]]
|
||||||
|
if ok1 || ok2 {
|
||||||
continue mountLoop
|
continue mountLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +167,10 @@ mountLoop:
|
|||||||
if stat.Blocks == 0 || stat.Bsize == 0 {
|
if stat.Blocks == 0 || stat.Bsize == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tags := map[string]string{"type": "node", "device": linefields[0]}
|
tags := map[string]string{"type": "node", "stype": "filesystem", "stype-id": linefields[0]}
|
||||||
|
if m.config.UseMountpoint {
|
||||||
|
tags["stype-id"] = linefields[1]
|
||||||
|
}
|
||||||
total := (stat.Blocks * uint64(stat.Bsize)) / uint64(1000000000)
|
total := (stat.Blocks * uint64(stat.Bsize)) / uint64(1000000000)
|
||||||
if m.allowedMetrics["disk_total"] {
|
if m.allowedMetrics["disk_total"] {
|
||||||
y, err := lp.NewMessage("disk_total", tags, m.meta, map[string]interface{}{"value": total}, time.Now())
|
y, err := lp.NewMessage("disk_total", tags, m.meta, map[string]interface{}{"value": total}, time.Now())
|
||||||
@@ -130,11 +191,17 @@ mountLoop:
|
|||||||
perc := (100 * (total - free)) / total
|
perc := (100 * (total - free)) / total
|
||||||
if perc > part_max_used {
|
if perc > part_max_used {
|
||||||
part_max_used = perc
|
part_max_used = perc
|
||||||
|
part_max_used_mountpoint = linefields[1]
|
||||||
|
part_max_used_device = linefields[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if m.allowedMetrics["part_max_used"] {
|
if m.allowedMetrics["part_max_used"] && len(part_max_used_mountpoint) > 0 {
|
||||||
y, err := lp.NewMessage("part_max_used", map[string]string{"type": "node"}, m.meta, map[string]interface{}{"value": int(part_max_used)}, time.Now())
|
tags := map[string]string{"type": "node", "stype": "filesystem", "stype-id": part_max_used_device}
|
||||||
|
if m.config.UseMountpoint {
|
||||||
|
tags["stype-id"] = part_max_used_mountpoint
|
||||||
|
}
|
||||||
|
y, err := lp.NewMessage("part_max_used", tags, m.meta, map[string]interface{}{"value": int(part_max_used)}, time.Now())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
y.AddMeta("unit", "percent")
|
y.AddMeta("unit", "percent")
|
||||||
output <- y
|
output <- y
|
||||||
|
|||||||
@@ -16,19 +16,38 @@ hugo_path: docs/reference/cc-metric-collector/collectors/diskstat.md
|
|||||||
"exclude_metrics": [
|
"exclude_metrics": [
|
||||||
"disk_total"
|
"disk_total"
|
||||||
],
|
],
|
||||||
"exclude_mounts": [
|
"exclude_devices": [
|
||||||
"slurm-tmpfs"
|
"slurm-tmpfs"
|
||||||
|
],
|
||||||
|
"exclude_mountpoints": [
|
||||||
|
"/tmp"
|
||||||
|
],
|
||||||
|
"mountpoint_as_stype": true,
|
||||||
|
"use_include_config": false,
|
||||||
|
"include_devices": [
|
||||||
|
"/dev/sda3"
|
||||||
|
],
|
||||||
|
"include_mountpoints" : [
|
||||||
|
"/home"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `diskstat` collector reads data from `/proc/self/mounts` and outputs a handful **node** metrics. If a metric is not required, it can be excluded from forwarding it to the sink. Additionally, any mount point containing one of the strings specified in `exclude_mounts` will be skipped during metric collection.
|
The `diskstat` collector reads data from `/proc/self/mounts` and outputs a handful **node** metrics with `stype=filesystem,stype-id=<mountdevice>`. If a metric is not required, it can be excluded from forwarding it to the sink.
|
||||||
|
|
||||||
Metrics per device (with `device` tag):
|
For sending the `mountpoint` instead of the `mountdevice` in the `stype-id`, use `mountpoint_as_stype`.
|
||||||
|
|
||||||
|
There are two ways to specify for which devices or mountpoints the collector generates metrics. It's "either ...or".
|
||||||
|
- Excluding devices and mount points using `exclude_devices` and `exclude_mountpoints`. All devices (*) will be read that are not explicitly excluded
|
||||||
|
- Include devices and mount points by setting `use_include_config:true` and using `include_devices` and `include_mountpoints`.
|
||||||
|
|
||||||
|
(*) File systems where the mount device (first column in `/proc/self/mounts`) contains `loop` are always excluded. Filesystems where the mount point (second column in `/proc/self/mounts`) contains `boot` are also always excluded.
|
||||||
|
|
||||||
|
Metrics per filesystem (with `stype=filesystem` tag and `stype-id` based on the configuration):
|
||||||
* `disk_total` (unit `GBytes`)
|
* `disk_total` (unit `GBytes`)
|
||||||
* `disk_free` (unit `GBytes`)
|
* `disk_free` (unit `GBytes`)
|
||||||
|
|
||||||
Global metrics:
|
Global metrics (with `stype=filesystem` tag and `stype-id` pointing to the max. used filesystem device or mount point based on the configuration):
|
||||||
* `part_max_used` (unit `percent`)
|
* `part_max_used` (unit `percent`)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,17 @@ import (
|
|||||||
const DEFAULT_GPFS_CMD = "mmpmon"
|
const DEFAULT_GPFS_CMD = "mmpmon"
|
||||||
|
|
||||||
type GpfsCollectorLastState struct {
|
type GpfsCollectorLastState struct {
|
||||||
|
numOpens int64
|
||||||
|
numCloses int64
|
||||||
|
numReads int64
|
||||||
|
numWrites int64
|
||||||
|
numReaddirs int64
|
||||||
|
numInodeUpdates int64
|
||||||
bytesRead int64
|
bytesRead int64
|
||||||
bytesWritten int64
|
bytesWritten int64
|
||||||
|
bytesTotal int64
|
||||||
|
iops int64
|
||||||
|
metaops int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type GpfsCollector struct {
|
type GpfsCollector struct {
|
||||||
@@ -39,6 +48,7 @@ type GpfsCollector struct {
|
|||||||
ExcludeFilesystem []string `json:"exclude_filesystem,omitempty"`
|
ExcludeFilesystem []string `json:"exclude_filesystem,omitempty"`
|
||||||
SendBandwidths bool `json:"send_bandwidths"`
|
SendBandwidths bool `json:"send_bandwidths"`
|
||||||
SendTotalValues bool `json:"send_total_values"`
|
SendTotalValues bool `json:"send_total_values"`
|
||||||
|
SendDerivedValues bool `json:"send_derived_values"`
|
||||||
}
|
}
|
||||||
skipFS map[string]struct{}
|
skipFS map[string]struct{}
|
||||||
lastTimestamp time.Time // Store time stamp of last tick to derive bandwidths
|
lastTimestamp time.Time // Store time stamp of last tick to derive bandwidths
|
||||||
@@ -185,6 +195,22 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if _, ok := m.lastState[filesystem]; !ok {
|
||||||
|
m.lastState[filesystem] = GpfsCollectorLastState{
|
||||||
|
numReads: -1,
|
||||||
|
numWrites: -1,
|
||||||
|
numOpens: -1,
|
||||||
|
numCloses: -1,
|
||||||
|
numReaddirs: -1,
|
||||||
|
numInodeUpdates: -1,
|
||||||
|
bytesTotal: -1,
|
||||||
|
iops: -1,
|
||||||
|
metaops: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// return code
|
// return code
|
||||||
rc, err := strconv.Atoi(key_value["_rc_"])
|
rc, err := strconv.Atoi(key_value["_rc_"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -278,7 +304,7 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
if m.config.SendBandwidths {
|
if m.config.SendBandwidths {
|
||||||
if lastBytesWritten := m.lastState[filesystem].bytesRead; lastBytesWritten >= 0 {
|
if lastBytesWritten := m.lastState[filesystem].bytesWritten; lastBytesWritten >= 0 {
|
||||||
bwWrite := float64(bytesWritten-lastBytesWritten) / timeDiff
|
bwWrite := float64(bytesWritten-lastBytesWritten) / timeDiff
|
||||||
if y, err :=
|
if y, err :=
|
||||||
lp.NewMessage(
|
lp.NewMessage(
|
||||||
@@ -296,13 +322,6 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.config.SendBandwidths {
|
|
||||||
m.lastState[filesystem] = GpfsCollectorLastState{
|
|
||||||
bytesRead: bytesRead,
|
|
||||||
bytesWritten: bytesWritten,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// number of opens
|
// number of opens
|
||||||
numOpens, err := strconv.ParseInt(key_value["_oc_"], 10, 64)
|
numOpens, err := strconv.ParseInt(key_value["_oc_"], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -314,6 +333,24 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
if y, err := lp.NewMessage("gpfs_num_opens", m.tags, m.meta, map[string]interface{}{"value": numOpens}, timestamp); err == nil {
|
if y, err := lp.NewMessage("gpfs_num_opens", m.tags, m.meta, map[string]interface{}{"value": numOpens}, timestamp); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastNumOpens := m.lastState[filesystem].numOpens; lastNumOpens >= 0 {
|
||||||
|
opensRate := float64(numOpens-lastNumOpens) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_opens_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": opensRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// number of closes
|
// number of closes
|
||||||
numCloses, err := strconv.ParseInt(key_value["_cc_"], 10, 64)
|
numCloses, err := strconv.ParseInt(key_value["_cc_"], 10, 64)
|
||||||
@@ -326,6 +363,24 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
if y, err := lp.NewMessage("gpfs_num_closes", m.tags, m.meta, map[string]interface{}{"value": numCloses}, timestamp); err == nil {
|
if y, err := lp.NewMessage("gpfs_num_closes", m.tags, m.meta, map[string]interface{}{"value": numCloses}, timestamp); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastNumCloses := m.lastState[filesystem].numCloses; lastNumCloses >= 0 {
|
||||||
|
closesRate := float64(numCloses-lastNumCloses) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_closes_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": closesRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// number of reads
|
// number of reads
|
||||||
numReads, err := strconv.ParseInt(key_value["_rdc_"], 10, 64)
|
numReads, err := strconv.ParseInt(key_value["_rdc_"], 10, 64)
|
||||||
@@ -338,6 +393,24 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
if y, err := lp.NewMessage("gpfs_num_reads", m.tags, m.meta, map[string]interface{}{"value": numReads}, timestamp); err == nil {
|
if y, err := lp.NewMessage("gpfs_num_reads", m.tags, m.meta, map[string]interface{}{"value": numReads}, timestamp); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastNumReads := m.lastState[filesystem].numReads; lastNumReads >= 0 {
|
||||||
|
readsRate := float64(numOpens-lastNumReads) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_reads_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": readsRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// number of writes
|
// number of writes
|
||||||
numWrites, err := strconv.ParseInt(key_value["_wc_"], 10, 64)
|
numWrites, err := strconv.ParseInt(key_value["_wc_"], 10, 64)
|
||||||
@@ -350,6 +423,24 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
if y, err := lp.NewMessage("gpfs_num_writes", m.tags, m.meta, map[string]interface{}{"value": numWrites}, timestamp); err == nil {
|
if y, err := lp.NewMessage("gpfs_num_writes", m.tags, m.meta, map[string]interface{}{"value": numWrites}, timestamp); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastNumWrites := m.lastState[filesystem].numWrites; lastNumWrites >= 0 {
|
||||||
|
writesRate := float64(numWrites-lastNumWrites) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_writes_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": writesRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// number of read directories
|
// number of read directories
|
||||||
numReaddirs, err := strconv.ParseInt(key_value["_dir_"], 10, 64)
|
numReaddirs, err := strconv.ParseInt(key_value["_dir_"], 10, 64)
|
||||||
@@ -362,6 +453,24 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
if y, err := lp.NewMessage("gpfs_num_readdirs", m.tags, m.meta, map[string]interface{}{"value": numReaddirs}, timestamp); err == nil {
|
if y, err := lp.NewMessage("gpfs_num_readdirs", m.tags, m.meta, map[string]interface{}{"value": numReaddirs}, timestamp); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastNumReaddirs := m.lastState[filesystem].numReaddirs; lastNumReaddirs >= 0 {
|
||||||
|
readdirsRate := float64(numReaddirs-lastNumReaddirs) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_readdirs_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": readdirsRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Number of inode updates
|
// Number of inode updates
|
||||||
numInodeUpdates, err := strconv.ParseInt(key_value["_iu_"], 10, 64)
|
numInodeUpdates, err := strconv.ParseInt(key_value["_iu_"], 10, 64)
|
||||||
@@ -374,10 +483,31 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
if y, err := lp.NewMessage("gpfs_num_inode_updates", m.tags, m.meta, map[string]interface{}{"value": numInodeUpdates}, timestamp); err == nil {
|
if y, err := lp.NewMessage("gpfs_num_inode_updates", m.tags, m.meta, map[string]interface{}{"value": numInodeUpdates}, timestamp); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastNumInodeUpdates := m.lastState[filesystem].numInodeUpdates; lastNumInodeUpdates >= 0 {
|
||||||
|
inodeUpdatesRate := float64(numInodeUpdates-lastNumInodeUpdates) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_inode_updates_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": inodeUpdatesRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Total values
|
// Total values
|
||||||
|
bytesTotal := int64(-1);
|
||||||
|
iops := int64(-1);
|
||||||
|
metaops := int64(-1);
|
||||||
if m.config.SendTotalValues {
|
if m.config.SendTotalValues {
|
||||||
bytesTotal := bytesRead + bytesWritten
|
bytesTotal = bytesRead + bytesWritten
|
||||||
if y, err :=
|
if y, err :=
|
||||||
lp.NewMessage("gpfs_bytes_total",
|
lp.NewMessage("gpfs_bytes_total",
|
||||||
m.tags,
|
m.tags,
|
||||||
@@ -390,7 +520,26 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
y.AddMeta("unit", "bytes")
|
y.AddMeta("unit", "bytes")
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
iops := numReads + numWrites
|
if m.config.SendBandwidths {
|
||||||
|
if lastBytesTotal := m.lastState[filesystem].bytesTotal; lastBytesTotal >= 0 {
|
||||||
|
bwTotal := float64(bytesTotal-lastBytesTotal) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_bw_total",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": bwTotal,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "bytes/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iops = numReads + numWrites
|
||||||
if y, err :=
|
if y, err :=
|
||||||
lp.NewMessage("gpfs_iops",
|
lp.NewMessage("gpfs_iops",
|
||||||
m.tags,
|
m.tags,
|
||||||
@@ -402,7 +551,26 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
); err == nil {
|
); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
metaops := numInodeUpdates + numCloses + numOpens + numReaddirs
|
if m.config.SendDerivedValues {
|
||||||
|
if lastIops := m.lastState[filesystem].iops; lastIops >= 0 {
|
||||||
|
iopsRate := float64(iops-lastIops) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_iops_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": iopsRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
metaops = numInodeUpdates + numCloses + numOpens + numReaddirs
|
||||||
if y, err :=
|
if y, err :=
|
||||||
lp.NewMessage("gpfs_metaops",
|
lp.NewMessage("gpfs_metaops",
|
||||||
m.tags,
|
m.tags,
|
||||||
@@ -414,9 +582,43 @@ func (m *GpfsCollector) Read(interval time.Duration, output chan lp.CCMessage) {
|
|||||||
); err == nil {
|
); err == nil {
|
||||||
output <- y
|
output <- y
|
||||||
}
|
}
|
||||||
|
if m.config.SendDerivedValues {
|
||||||
|
if lastMetaops := m.lastState[filesystem].metaops; lastMetaops >= 0 {
|
||||||
|
metaopsRate := float64(metaops-lastMetaops) / timeDiff
|
||||||
|
if y, err :=
|
||||||
|
lp.NewMessage(
|
||||||
|
"gpfs_metaops_rate",
|
||||||
|
m.tags,
|
||||||
|
m.meta,
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": metaopsRate,
|
||||||
|
},
|
||||||
|
timestamp,
|
||||||
|
); err == nil {
|
||||||
|
y.AddMeta("unit", "requests/sec")
|
||||||
|
output <- y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save last state
|
||||||
|
m.lastState[filesystem] = GpfsCollectorLastState{
|
||||||
|
bytesRead: bytesRead,
|
||||||
|
bytesWritten: bytesWritten,
|
||||||
|
numOpens: numOpens,
|
||||||
|
numCloses: numCloses,
|
||||||
|
numReads: numReads,
|
||||||
|
numWrites: numWrites,
|
||||||
|
numReaddirs: numReaddirs,
|
||||||
|
numInodeUpdates: numInodeUpdates,
|
||||||
|
bytesTotal: bytesTotal,
|
||||||
|
iops: iops,
|
||||||
|
metaops: metaops,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m *GpfsCollector) Close() {
|
func (m *GpfsCollector) Close() {
|
||||||
m.init = false
|
m.init = false
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ hugo_path: docs/reference/cc-metric-collector/collectors/gpfs.md
|
|||||||
"fs1"
|
"fs1"
|
||||||
],
|
],
|
||||||
"send_bandwidths": true,
|
"send_bandwidths": true,
|
||||||
"send_total_values": true
|
"send_total_values": true,
|
||||||
|
"send_derived_values": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -41,10 +42,19 @@ Metrics:
|
|||||||
* `gpfs_num_writes`
|
* `gpfs_num_writes`
|
||||||
* `gpfs_num_readdirs`
|
* `gpfs_num_readdirs`
|
||||||
* `gpfs_num_inode_updates`
|
* `gpfs_num_inode_updates`
|
||||||
|
* `gpfs_opens_rate` (if `send_derived_values == true`)
|
||||||
|
* `gpfs_closes_rate` (if `send_derived_values == true`)
|
||||||
|
* `gpfs_reads_rate` (if `send_derived_values == true`)
|
||||||
|
* `gpfs_writes_rate` (if `send_derived_values == true`)
|
||||||
|
* `gpfs_readdirs_rate` (if `send_derived_values == true`)
|
||||||
|
* `gpfs_inode_updates_rate` (if `send_derived_values == true`)
|
||||||
* `gpfs_bytes_total = gpfs_bytes_read + gpfs_bytes_written` (if `send_total_values == true`)
|
* `gpfs_bytes_total = gpfs_bytes_read + gpfs_bytes_written` (if `send_total_values == true`)
|
||||||
* `gpfs_iops = gpfs_num_reads + gpfs_num_writes` (if `send_total_values == true`)
|
* `gpfs_iops = gpfs_num_reads + gpfs_num_writes` (if `send_total_values == true`)
|
||||||
|
* `gpfs_iops_rate` (if `send_total_values == true` and `send_derived_values == true`)
|
||||||
* `gpfs_metaops = gpfs_num_inode_updates + gpfs_num_closes + gpfs_num_opens + gpfs_num_readdirs` (if `send_total_values == true`)
|
* `gpfs_metaops = gpfs_num_inode_updates + gpfs_num_closes + gpfs_num_opens + gpfs_num_readdirs` (if `send_total_values == true`)
|
||||||
|
* `gpfs_metaops_rate` (if `send_total_values == true` and `send_derived_values == true`)
|
||||||
* `gpfs_bw_read` (if `send_bandwidths == true`)
|
* `gpfs_bw_read` (if `send_bandwidths == true`)
|
||||||
* `gpfs_bw_write` (if `send_bandwidths == true`)
|
* `gpfs_bw_write` (if `send_bandwidths == true`)
|
||||||
|
* `gpfs_bw_total` (if `send_bandwidths == true` and `send_total_values == true`)
|
||||||
|
|
||||||
The collector adds a `filesystem` tag to all metrics
|
The collector adds a `filesystem` tag to all metrics
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ package collectors
|
|||||||
#cgo LDFLAGS: -Wl,--unresolved-symbols=ignore-in-object-files
|
#cgo LDFLAGS: -Wl,--unresolved-symbols=ignore-in-object-files
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <likwid.h>
|
#include <likwid.h>
|
||||||
|
|
||||||
|
int _HPMaddThread(int cpuid) {
|
||||||
|
return HPMaddThread(cpuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -233,6 +239,10 @@ func (m *LikwidCollector) Init(config json.RawMessage) error {
|
|||||||
os.Setenv("LIKWID_FORCE", "1")
|
os.Setenv("LIKWID_FORCE", "1")
|
||||||
}
|
}
|
||||||
m.setup()
|
m.setup()
|
||||||
|
major := C.likwid_getMajorVersion()
|
||||||
|
minor := C.likwid_getMinorVersion()
|
||||||
|
bugfix := C.likwid_getBugfixVersion()
|
||||||
|
cclog.ComponentDebug(m.name, fmt.Sprintf("Using LIKWID library %d.%d.%d at %s with %s access", major, minor, bugfix, m.config.LibraryPath, m.config.AccessMode))
|
||||||
|
|
||||||
m.meta = map[string]string{"group": "PerfCounter"}
|
m.meta = map[string]string{"group": "PerfCounter"}
|
||||||
cclog.ComponentDebug(m.name, "Get cpulist and init maps and lists")
|
cclog.ComponentDebug(m.name, "Get cpulist and init maps and lists")
|
||||||
@@ -327,7 +337,7 @@ func (m *LikwidCollector) Init(config json.RawMessage) error {
|
|||||||
for _, c := range m.cpulist {
|
for _, c := range m.cpulist {
|
||||||
m.measureThread.Call(
|
m.measureThread.Call(
|
||||||
func() {
|
func() {
|
||||||
retCode := C.HPMaddThread(c)
|
retCode := C._HPMaddThread(C.int(c))
|
||||||
if retCode != 0 {
|
if retCode != 0 {
|
||||||
err := fmt.Errorf("C.HPMaddThread(%v) failed with return code %v", c, retCode)
|
err := fmt.Errorf("C.HPMaddThread(%v) failed with return code %v", c, retCode)
|
||||||
cclog.ComponentError(m.name, err.Error())
|
cclog.ComponentError(m.name, err.Error())
|
||||||
@@ -428,9 +438,13 @@ func (m *LikwidCollector) takeMeasurement(evidx int, evset LikwidEventsetConfig,
|
|||||||
case e := <-watcher.Events:
|
case e := <-watcher.Events:
|
||||||
ret = -1
|
ret = -1
|
||||||
if e.Op != fsnotify.Chmod {
|
if e.Op != fsnotify.Chmod {
|
||||||
|
C.HPMfinalize()
|
||||||
|
C.HPMinit()
|
||||||
ret = C.perfmon_init(C.int(len(m.cpulist)), &m.cpulist[0])
|
ret = C.perfmon_init(C.int(len(m.cpulist)), &m.cpulist[0])
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
C.HPMfinalize()
|
||||||
|
C.HPMinit()
|
||||||
ret = C.perfmon_init(C.int(len(m.cpulist)), &m.cpulist[0])
|
ret = C.perfmon_init(C.int(len(m.cpulist)), &m.cpulist[0])
|
||||||
}
|
}
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
# Building the cc-metric-collector
|
# Building the cc-metric-collector
|
||||||
|
|
||||||
In most cases, a simple `make` in the main folder is enough to get a `cc-metric-collector` binary. It is basically a `go build` but some collectors require additional tasks. There is currently no Golang interface to LIKWID, so it uses `cgo` to create bindings but `cgo` requires the LIKWID header files. Therefore, it checks whether LIKWID is installed and if not it downloads LIKWID and copies the headers.
|
Dependencies:
|
||||||
|
- golang
|
||||||
|
- hwloc
|
||||||
|
|
||||||
|
```
|
||||||
|
$ export CGO_LDFLAGS="-L/path/to/hwloc/lib/dir"
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
In most cases, a simple `make` in the main folder is enough to get a `cc-metric-collector` binary as long as hwloc is in default locations. It is basically a `go build` but some collectors require additional tasks. There is currently no Golang interface to LIKWID, so it uses `cgo` to create bindings but `cgo` requires the LIKWID header files. Therefore, it checks whether LIKWID is installed and if not it downloads LIKWID and copies the headers.
|
||||||
|
|
||||||
## System integration
|
## System integration
|
||||||
|
|
||||||
|
|||||||
20
go.mod
20
go.mod
@@ -5,42 +5,42 @@ go 1.23.4
|
|||||||
toolchain go1.23.7
|
toolchain go1.23.7
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ClusterCockpit/cc-lib v0.2.0
|
github.com/ClusterCockpit/cc-lib v0.5.0
|
||||||
github.com/ClusterCockpit/go-rocm-smi v0.3.0
|
github.com/ClusterCockpit/go-rocm-smi v0.3.0
|
||||||
github.com/NVIDIA/go-nvml v0.12.4-1
|
github.com/NVIDIA/go-nvml v0.12.9-0
|
||||||
github.com/PaesslerAG/gval v1.2.2
|
github.com/PaesslerAG/gval v1.2.2
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.9.0
|
||||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf
|
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf
|
||||||
github.com/tklauser/go-sysconf v0.3.13
|
github.com/tklauser/go-sysconf v0.3.13
|
||||||
golang.design/x/thread v0.0.0-20210122121316-335e9adffdf1
|
golang.design/x/thread v0.0.0-20210122121316-335e9adffdf1
|
||||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0
|
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
||||||
golang.org/x/sys v0.32.0
|
golang.org/x/sys v0.33.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/expr-lang/expr v1.17.2 // indirect
|
github.com/expr-lang/expr v1.17.5 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.1 // indirect
|
github.com/gorilla/mux v1.8.1 // indirect
|
||||||
github.com/influxdata/influxdb-client-go/v2 v2.14.0 // indirect
|
github.com/influxdata/influxdb-client-go/v2 v2.14.0 // indirect
|
||||||
github.com/influxdata/line-protocol/v2 v2.2.1 // indirect
|
github.com/influxdata/line-protocol/v2 v2.2.1 // indirect
|
||||||
github.com/klauspost/compress v1.18.0 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/nats-io/nats.go v1.41.2 // indirect
|
github.com/nats-io/nats.go v1.43.0 // indirect
|
||||||
github.com/nats-io/nkeys v0.4.11 // indirect
|
github.com/nats-io/nkeys v0.4.11 // indirect
|
||||||
github.com/nats-io/nuid v1.0.1 // indirect
|
github.com/nats-io/nuid v1.0.1 // indirect
|
||||||
github.com/oapi-codegen/runtime v1.1.1 // indirect
|
github.com/oapi-codegen/runtime v1.1.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
github.com/prometheus/client_golang v1.22.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
github.com/prometheus/common v0.63.0 // indirect
|
github.com/prometheus/common v0.65.0 // indirect
|
||||||
github.com/prometheus/procfs v0.16.1 // indirect
|
github.com/prometheus/procfs v0.16.1 // indirect
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
||||||
github.com/shopspring/decimal v1.3.1 // indirect
|
github.com/shopspring/decimal v1.3.1 // indirect
|
||||||
github.com/stmcginnis/gofish v0.20.0 // indirect
|
github.com/stmcginnis/gofish v0.20.0 // indirect
|
||||||
github.com/tklauser/numcpus v0.7.0 // indirect
|
github.com/tklauser/numcpus v0.7.0 // indirect
|
||||||
golang.org/x/crypto v0.37.0 // indirect
|
golang.org/x/crypto v0.39.0 // indirect
|
||||||
golang.org/x/net v0.39.0 // indirect
|
golang.org/x/net v0.41.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.6 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
44
go.sum
44
go.sum
@@ -1,12 +1,12 @@
|
|||||||
github.com/ClusterCockpit/cc-lib v0.2.0 h1:4mEpppqWXkjS3PCHYSOxF3NisrKsbPjg17ftsFhEKPk=
|
github.com/ClusterCockpit/cc-lib v0.5.0 h1:DSKAD1TxjVWyd1x3GWvxFeEkANF9o13T97nirj3CbRU=
|
||||||
github.com/ClusterCockpit/cc-lib v0.2.0/go.mod h1:S6oZNtejBHu+ewmGRKYFqJmlrRReXv8J4D2UP8hmu50=
|
github.com/ClusterCockpit/cc-lib v0.5.0/go.mod h1:0zLbJprwOWLA+OSNQ+OlUKLscZszwf9J2j8Ly5ztplk=
|
||||||
github.com/ClusterCockpit/go-rocm-smi v0.3.0 h1:1qZnSpG7/NyLtc7AjqnUL9Jb8xtqG1nMVgp69rJfaR8=
|
github.com/ClusterCockpit/go-rocm-smi v0.3.0 h1:1qZnSpG7/NyLtc7AjqnUL9Jb8xtqG1nMVgp69rJfaR8=
|
||||||
github.com/ClusterCockpit/go-rocm-smi v0.3.0/go.mod h1:+I3UMeX3OlizXDf1WpGD43W4KGZZGVSGmny6rTeOnWA=
|
github.com/ClusterCockpit/go-rocm-smi v0.3.0/go.mod h1:+I3UMeX3OlizXDf1WpGD43W4KGZZGVSGmny6rTeOnWA=
|
||||||
github.com/NVIDIA/go-nvml v0.11.6-0/go.mod h1:hy7HYeQy335x6nEss0Ne3PYqleRa6Ct+VKD9RQ4nyFs=
|
github.com/NVIDIA/go-nvml v0.11.6-0/go.mod h1:hy7HYeQy335x6nEss0Ne3PYqleRa6Ct+VKD9RQ4nyFs=
|
||||||
github.com/NVIDIA/go-nvml v0.12.4-1 h1:WKUvqshhWSNTfm47ETRhv0A0zJyr1ncCuHiXwoTrBEc=
|
github.com/NVIDIA/go-nvml v0.12.9-0 h1:e344UK8ZkeMeeLkdQtRhmXRxNf+u532LDZPGMtkdus0=
|
||||||
github.com/NVIDIA/go-nvml v0.12.4-1/go.mod h1:8Llmj+1Rr+9VGGwZuRer5N/aCjxGuR5nPb/9ebBiIEQ=
|
github.com/NVIDIA/go-nvml v0.12.9-0/go.mod h1:+KNA7c7gIBH7SKSJ1ntlwkfN80zdx8ovl4hrK3LmPt4=
|
||||||
github.com/PaesslerAG/gval v1.2.2 h1:Y7iBzhgE09IGTt5QgGQ2IdaYYYOU134YGHBThD+wm9E=
|
github.com/PaesslerAG/gval v1.2.4 h1:rhX7MpjJlcxYwL2eTTYIOBUyEKZ+A96T9vQySWkVUiU=
|
||||||
github.com/PaesslerAG/gval v1.2.2/go.mod h1:XRFLwvmkTEdYziLdaCeCa5ImcGVrfQbeNUbVR+C6xac=
|
github.com/PaesslerAG/gval v1.2.4/go.mod h1:XRFLwvmkTEdYziLdaCeCa5ImcGVrfQbeNUbVR+C6xac=
|
||||||
github.com/PaesslerAG/jsonpath v0.1.0 h1:gADYeifvlqK3R3i2cR5B4DGgxLXIPb3TRTH1mGi0jPI=
|
github.com/PaesslerAG/jsonpath v0.1.0 h1:gADYeifvlqK3R3i2cR5B4DGgxLXIPb3TRTH1mGi0jPI=
|
||||||
github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8=
|
github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8=
|
||||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||||
@@ -21,14 +21,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/expr-lang/expr v1.17.2 h1:o0A99O/Px+/DTjEnQiodAgOIK9PPxL8DtXhBRKC+Iso=
|
github.com/expr-lang/expr v1.17.5 h1:i1WrMvcdLF249nSNlpQZN1S6NXuW9WaOfF5tPi3aw3k=
|
||||||
github.com/expr-lang/expr v1.17.2/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
github.com/expr-lang/expr v1.17.5/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||||
github.com/frankban/quicktest v1.11.0/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
|
github.com/frankban/quicktest v1.11.0/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
|
||||||
github.com/frankban/quicktest v1.11.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
|
github.com/frankban/quicktest v1.11.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
|
||||||
github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk=
|
github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk=
|
||||||
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
|
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
@@ -62,8 +62,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
|
|||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/nats-io/nats.go v1.41.2 h1:5UkfLAtu/036s99AhFRlyNDI1Ieylb36qbGjJzHixos=
|
github.com/nats-io/nats.go v1.43.0 h1:uRFZ2FEoRvP64+UUhaTokyS18XBCR/xM2vQZKO4i8ug=
|
||||||
github.com/nats-io/nats.go v1.41.2/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g=
|
github.com/nats-io/nats.go v1.43.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g=
|
||||||
github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0=
|
github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0=
|
||||||
github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE=
|
github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE=
|
||||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||||
@@ -77,8 +77,8 @@ github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/
|
|||||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
@@ -100,15 +100,15 @@ github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr
|
|||||||
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
|
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
|
||||||
golang.design/x/thread v0.0.0-20210122121316-335e9adffdf1 h1:P7S/GeHBAFEZIYp0ePPs2kHXoazz8q2KsyxHyQVGCJg=
|
golang.design/x/thread v0.0.0-20210122121316-335e9adffdf1 h1:P7S/GeHBAFEZIYp0ePPs2kHXoazz8q2KsyxHyQVGCJg=
|
||||||
golang.design/x/thread v0.0.0-20210122121316-335e9adffdf1/go.mod h1:9CWpnTUmlQkfdpdutA1nNf4iE5lAVt3QZOu0Z6hahBE=
|
golang.design/x/thread v0.0.0-20210122121316-335e9adffdf1/go.mod h1:9CWpnTUmlQkfdpdutA1nNf4iE5lAVt3QZOu0Z6hahBE=
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
||||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||||
golang.org/x/sys v0.0.0-20210122093101-04d7465088b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210122093101-04d7465088b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
Package: cc-metric-collector
|
Package: cc-metric-collector
|
||||||
|
Section: misc
|
||||||
|
Priority: optional
|
||||||
Version: {VERSION}
|
Version: {VERSION}
|
||||||
Installed-Size: {INSTALLED_SIZE}
|
Installed-Size: {INSTALLED_SIZE}
|
||||||
Architecture: {ARCH}
|
Architecture: {ARCH}
|
||||||
|
|||||||
Reference in New Issue
Block a user