hardware_info.go 2.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.

package metricsinfo

import (
15 16
	"sync"

E
Enwei Jiao 已提交
17 18
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/mem"
19
	"go.uber.org/zap"
20 21 22 23 24 25 26 27

	"github.com/milvus-io/milvus/internal/log"
)

var (
	icOnce sync.Once
	ic     bool
	icErr  error
28 29
)

30
// GetCPUCoreCount returns the count of cpu core.
31 32 33 34 35 36 37 38 39 40 41
func GetCPUCoreCount(logical bool) int {
	c, err := cpu.Counts(logical)
	if err != nil {
		log.Warn("failed to get cpu counts",
			zap.Error(err))
		return 0
	}

	return c
}

42
// GetCPUUsage returns the cpu usage in percentage.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
func GetCPUUsage() float64 {
	percents, err := cpu.Percent(0, false)
	if err != nil {
		log.Warn("failed to get cpu usage",
			zap.Error(err))
		return 0
	}

	if len(percents) != 1 {
		log.Warn("something wrong in cpu.Percent, len(percents) must be equal to 1",
			zap.Int("len(percents)", len(percents)))
		return 0
	}

	return percents[0]
}

60
// GetMemoryCount returns the memory count in bytes.
61
func GetMemoryCount() uint64 {
62 63 64 65 66 67 68
	icOnce.Do(func() {
		ic, icErr = inContainer()
	})
	if icErr != nil {
		log.Error(icErr.Error())
		return 0
	}
69
	// get host memory by `gopsutil`
70 71 72 73 74 75
	stats, err := mem.VirtualMemory()
	if err != nil {
		log.Warn("failed to get memory count",
			zap.Error(err))
		return 0
	}
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	// not in container, return host memory
	if !ic {
		return stats.Total
	}

	// get container memory by `cgroups`
	limit, err := getContainerMemLimit()
	if err != nil {
		log.Error(err.Error())
		return 0
	}
	// in container, return min(hostMem, containerMem)
	if limit < stats.Total {
		return limit
	}
91 92 93
	return stats.Total
}

94
// GetUsedMemoryCount returns the memory usage in bytes.
95
func GetUsedMemoryCount() uint64 {
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
	icOnce.Do(func() {
		ic, icErr = inContainer()
	})
	if icErr != nil {
		log.Error(icErr.Error())
		return 0
	}
	if ic {
		// in container, calculate by `cgroups`
		used, err := getContainerMemUsed()
		if err != nil {
			log.Error(err.Error())
			return 0
		}
		return used
	}
	// not in container, calculate by `gopsutil`
113 114 115 116 117 118 119 120 121 122 123
	stats, err := mem.VirtualMemory()
	if err != nil {
		log.Warn("failed to get memory usage count",
			zap.Error(err))
		return 0
	}

	return stats.Used
}

// TODO(dragondriver): not accurate to calculate disk usage when we use distributed storage
124

125
// GetDiskCount returns the disk count in bytes.
126 127 128 129
func GetDiskCount() uint64 {
	return 100 * 1024 * 1024
}

130
// GetDiskUsage returns the disk usage in bytes.
131 132 133
func GetDiskUsage() uint64 {
	return 2 * 1024 * 1024
}