Skip to content

Commit

Permalink
Merge pull request #736 from kongfei605/meta_up
Browse files Browse the repository at this point in the history
meta data report
  • Loading branch information
kongfei605 authored Dec 18, 2023
2 parents dc0650c + 4083676 commit 3b5d0a9
Show file tree
Hide file tree
Showing 32 changed files with 2,126 additions and 13 deletions.
10 changes: 7 additions & 3 deletions config/hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,13 @@ func InitHostInfo() error {
return err
}

ip, err := GetOutboundIP()
if err != nil {
return err
var ip string
if ip = os.Getenv("HOSTIP"); ip == "" {
nip, err := GetOutboundIP()
if err != nil {
return err
}
ip = fmt.Sprint(nip)
}

HostInfo = &HostInfoCache{
Expand Down
19 changes: 19 additions & 0 deletions heartbeat/cpu/cpu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This file is licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright © 2015 Kentaro Kuribayashi <kentarok@gmail.com>
// Copyright 2014-present Datadog, Inc.

package cpu

type Cpu struct{}

const name = "cpu"

func (self *Cpu) Name() string {
return name
}

func (self *Cpu) Collect() (result interface{}, err error) {
result, err = getCpuInfo()
return
}
44 changes: 44 additions & 0 deletions heartbeat/cpu/cpu_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// This file is licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright © 2015 Kentaro Kuribayashi <kentarok@gmail.com>
// Copyright 2014-present Datadog, Inc.

package cpu

import (
"os/exec"
"strconv"
"strings"
)

var cpuMap = map[string]string{
"machdep.cpu.vendor": "vendor_id",
"machdep.cpu.brand_string": "model_name",
"hw.physicalcpu": "cpu_cores",
"hw.logicalcpu": "cpu_logical_processors",
"hw.cpufrequency": "mhz",
"machdep.cpu.family": "family",
"machdep.cpu.model": "model",
"machdep.cpu.stepping": "stepping",
}

func getCpuInfo() (cpuInfo map[string]string, err error) {

cpuInfo = make(map[string]string)

for option, key := range cpuMap {
out, err := exec.Command("sysctl", "-n", option).Output()
if err == nil {
cpuInfo[key] = strings.Trim(string(out), "\n")
}
}

if len(cpuInfo["mhz"]) != 0 {
mhz, err := strconv.Atoi(cpuInfo["mhz"])
if err == nil {
cpuInfo["mhz"] = strconv.Itoa(mhz / 1000000)
}
}

return
}
90 changes: 90 additions & 0 deletions heartbeat/cpu/cpu_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// This file is licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright © 2015 Kentaro Kuribayashi <kentarok@gmail.com>
// Copyright 2014-present Datadog, Inc.

package cpu

import (
"bufio"
"os"
"regexp"
"strconv"
)

var cpuMap = map[string]string{
"vendor_id": "vendor_id",
"model name": "model_name",
"cpu cores": "cpu_cores",
"siblings": "cpu_logical_processors",
"cpu MHz\t": "mhz",
"cache size": "cache_size",
"cpu family": "family",
"model\t": "model",
"stepping": "stepping",
}

// Values that need to be multiplied by the number of physical processors
var perPhysicalProcValues = []string{
"cpu_cores",
"cpu_logical_processors",
}

func getCpuInfo() (cpuInfo map[string]string, err error) {
lines, err := readProcFile()
if err != nil {
return
}

cpuInfo = make(map[string]string)
// Implementation of a set that holds the physical IDs
physicalProcIDs := make(map[string]struct{})

for _, line := range lines {
pair := regexp.MustCompile("\t: ").Split(line, 2)

if pair[0] == "physical id" {
physicalProcIDs[pair[1]] = struct{}{}
}

key, ok := cpuMap[pair[0]]
if ok {
cpuInfo[key] = pair[1]
}
}

// Multiply the values that are "per physical processor" by the number of physical procs
for _, field := range perPhysicalProcValues {
if value, ok := cpuInfo[field]; ok {
intValue, err := strconv.Atoi(value)
if err != nil {
continue
}

cpuInfo[field] = strconv.Itoa(intValue * len(physicalProcIDs))
}
}

return
}

func readProcFile() (lines []string, err error) {
file, err := os.Open("/proc/cpuinfo")

if err != nil {
return
}

scanner := bufio.NewScanner(file)

for scanner.Scan() {
lines = append(lines, scanner.Text())
}

if scanner.Err() != nil {
err = scanner.Err()
return
}

return
}
192 changes: 192 additions & 0 deletions heartbeat/cpu/cpu_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// This file is licensed under the MIT License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright © 2015 Kentaro Kuribayashi <kentarok@gmail.com>
// Copyright 2014-present Datadog, Inc.

package cpu

import (
"fmt"
"regexp"
"strconv"
"strings"
"syscall"
"unsafe"

"golang.org/x/sys/windows/registry"
)

var getCpuInfo = GetCpuInfo

// Values that need to be multiplied by the number of physical processors
var perPhysicalProcValues = []string{
"cpu_cores",
"cpu_logical_processors",
}

const ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122
const registryHive = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"

type CACHE_DESCRIPTOR struct {
Level uint8
Associativity uint8
LineSize uint16
Size uint32
cacheType uint32
}
type SYSTEM_LOGICAL_PROCESSOR_INFORMATION struct {
ProcessorMask uintptr
Relationship int // enum (int)
// in the Windows header, this is a union of a byte, a DWORD,
// and a CACHE_DESCRIPTOR structure
dataunion [16]byte
}

// .const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_SIZE = 32

type GROUP_AFFINITY struct {
Mask uintptr
Group uint16
Reserved [3]uint16
}
type NUMA_NODE_RELATIONSHIP struct {
NodeNumber uint32
Reserved [20]uint8
GroupMask GROUP_AFFINITY
}
type CACHE_RELATIONSHIP struct {
Level uint8
Associativity uint8
LineSize uint16
CacheSize uint32
CacheType int // enum in C
Reserved [20]uint8
GroupMask GROUP_AFFINITY
}

type PROCESSOR_GROUP_INFO struct {
MaximumProcessorCount uint8
ActiveProcessorCount uint8
Reserved [38]uint8
ActiveProcessorMask uintptr
}
type GROUP_RELATIONSHIP struct {
MaximumGroupCount uint16
ActiveGroupCount uint16
Reserved [20]uint8
// variable size array of PROCESSOR_GROUP_INFO
}
type PROCESSOR_RELATIONSHIP struct {
Flags uint8
EfficiencyClass uint8
wReserved [20]uint8
GroupCount uint16
// what follows is an array of zero or more GROUP_AFFINITY structures
}

type SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX struct {
Relationship int
Size uint32
// what follows is a C union of
// PROCESSOR_RELATIONSHIP,
// NUMA_NODE_RELATIONSHIP,
// CACHE_RELATIONSHIP,
// GROUP_RELATIONSHIP
}

const RelationProcessorCore = 0
const RelationNumaNode = 1
const RelationCache = 2
const RelationProcessorPackage = 3
const RelationGroup = 4

type SYSTEM_INFO struct {
wProcessorArchitecture uint16
wReserved uint16
dwPageSize uint32
lpMinApplicationAddress *uint32
lpMaxApplicationAddress *uint32
dwActiveProcessorMask uintptr
dwNumberOfProcessors uint32
dwProcessorType uint32
dwAllocationGranularity uint32
wProcessorLevel uint16
wProcessorRevision uint16
}

type CPU_INFO struct {
numaNodeCount int // number of NUMA nodes
pkgcount int // number of packages (physical CPUS)
corecount int // total number of cores
logicalcount int // number of logical CPUS
l1CacheSize uint32 // layer 1 cache size
l2CacheSize uint32 // layer 2 cache size
l3CacheSize uint32 // layer 3 cache size
relationGroups int // number of cpu relation groups
maxProcsInGroups int // max number of processors
activeProcsInGroups int // active processors

}

func countBits(num uint64) (count int) {
count = 0
for num > 0 {
if (num & 0x1) == 1 {
count++
}
num >>= 1
}
return
}

func getSystemInfo() (si SYSTEM_INFO) {
var mod = syscall.NewLazyDLL("kernel32.dll")
var gsi = mod.NewProc("GetSystemInfo")

gsi.Call(uintptr(unsafe.Pointer(&si)))
return
}

// GetCpuInfo returns map of interesting bits of information about the CPU
func GetCpuInfo() (cpuInfo map[string]string, err error) {

cpuInfo = make(map[string]string)

cpus, _ := computeCoresAndProcessors()
si := getSystemInfo()

k, err := registry.OpenKey(registry.LOCAL_MACHINE,
registryHive,
registry.QUERY_VALUE)
defer k.Close()
dw, _, err := k.GetIntegerValue("~MHz")
cpuInfo["mhz"] = strconv.Itoa(int(dw))

s, _, err := k.GetStringValue("ProcessorNameString")
cpuInfo["model_name"] = s

cpuInfo["cpu_pkgs"] = strconv.Itoa(cpus.pkgcount)
cpuInfo["cpu_numa_nodes"] = strconv.Itoa(cpus.numaNodeCount)
cpuInfo["cpu_cores"] = strconv.Itoa(cpus.corecount)
cpuInfo["cpu_logical_processors"] = strconv.Itoa(cpus.logicalcount)

s, _, err = k.GetStringValue("VendorIdentifier")
cpuInfo["vendor_id"] = s

s, _, err = k.GetStringValue("Identifier")
cpuInfo["family"] = extract(s, "Family")

cpuInfo["model"] = strconv.Itoa(int((si.wProcessorRevision >> 8) & 0xFF))
cpuInfo["stepping"] = strconv.Itoa(int(si.wProcessorRevision & 0xFF))

cpuInfo["cache_size_l1"] = strconv.Itoa(int(cpus.l1CacheSize))
cpuInfo["cache_size_l2"] = strconv.Itoa(int(cpus.l2CacheSize))
cpuInfo["cache_size_l3"] = strconv.Itoa(int(cpus.l3CacheSize))

return
}

func extract(caption, field string) string {
re := regexp.MustCompile(fmt.Sprintf("%s [0-9]* ", field))
return strings.Split(re.FindStringSubmatch(caption)[0], " ")[1]
}
Loading

0 comments on commit 3b5d0a9

Please sign in to comment.