summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
authorAustin S. Hemmelgarn <austin@netdata.cloud>2020-01-24 10:04:27 -0500
committerGitHub <noreply@github.com>2020-01-24 10:04:27 -0500
commitdb265d6f63182cd5ee58bf6f76cb50a5f41dd263 (patch)
tree701ae3611ae122c6cd54f5febc981c3254f89c77 /daemon
parentd1eafad8b02fdef2f4ddcbfa6c35ec5594b248b3 (diff)
Improve the system-info.sh script to report CPU and RAM meta-data. (#7815)
* Add CPU information collection for Linux and FreeBSD. This adds logic to system.info.sh to collect info about the system's CPU. It adds the following keys to the output of the script: * NETDATA_CPU_LOGICAL_CPU_COUNT: This reports the number of logical CPU cores the system is actually using (including offline ones). This may differ from the CPU's advertised core count, but is what most people actually care about. * NETDATA_CPU_VENDOR: This reports the CPU manufacturer. This is needed because some systems do not include the manufacturer name in the CPU model name. * NETDATA_CPU_MODEL: This reports the CPU model. It may or may not include any of a model number, intended operating frequency, and manufacturer name. * NETDATA_CPU_FREQ: This reports a best guess at the design frequency for the CPU. It may instead be the max boost frequency. This is reported as a number with associated units, which will usually be either hertz or megahertz. * NETDATA_CPU_DETECTION: This reports the method used to detect the CPU information, It will be either 'none' if no detection was successful, or a space-separated list of detection methods. This may potentially use any of the following detection methods: * lscpu: Uses a mix of information from across the system. Requires the `lscpu` command to be installed. * dmidecode: Uses the information from the DMI tables. Requires hardware support as well as the `dmidecode` command. * nproc: Uses the `nproc` command from the GNU coreutils to get a count of logical processors. * sysctl: Uses the `sysctl` command on FreeBSD to fetch information. * sysfs: Uses /sys on Linux to fetch information. * procfs: Uses /proc/cpuinfo on Linux to fetch information. * uname: Uses the `uname` command from the GNU coreutils to get CPU model and vendor information. All values tht were not successfully detected should read back as 'unknown'. Some values may have spaces present, and thus are quoted in the output. * Collect total system RAM info in system-info.sh This collects info about the total usable system RAM in the system-info.sh script. It adds the following two keys to the output of the script: * NETDATA_TOTAL_RAM: Reports the total usable system RAM as a number with an associated unit, usually as bytes or kilobytes. Reports 'unknown' if this couldn't be determined. * NETDATA_RAM_DETECTION: Indicates how we detected the total RAM, or 'none' if we couldn't figure out the total RAM. * Make lscpu output parsing more robust. * Remove extra quotes. The output is not parsed as shell variables, but using a special parser that just reads everything from the `=` to EOL as the value. * Coerce output to base units. This properly converts the output for CPU frequencies and RAM sizes to use base units of Hertz or bytes, allowing for simpler parsing of the output. * Fix incorrect number handling in total RAM parsing. * Correctly fix incorrect number handling in total RAM parsing. * Fix parsing of `lscpu` output. This properly recognizes the CPU frequency value as MHz and truncates the value to an integer.
Diffstat (limited to 'daemon')
-rwxr-xr-xdaemon/system-info.sh124
1 files changed, 124 insertions, 0 deletions
diff --git a/daemon/system-info.sh b/daemon/system-info.sh
index cd3fc6ee97..3ffb3863aa 100755
--- a/daemon/system-info.sh
+++ b/daemon/system-info.sh
@@ -169,6 +169,123 @@ else
fi
fi
+# -------------------------------------------------------------------------------------------------
+# Detect information about the CPU
+
+LCPU_COUNT="unknown"
+CPU_MODEL="unknown"
+CPU_VENDOR="unknown"
+CPU_FREQ="unknown"
+CPU_INFO_SOURCE="none"
+
+possible_cpu_freq=""
+nproc="$(command -v nproc)"
+lscpu="$(command -v lscpu)"
+lscpu_output=""
+dmidecode="$(command -v dmidecode)"
+dmidecode_output=""
+
+if [ -n "${lscpu}" ] && lscpu >/dev/null 2>&1 ; then
+ lscpu_output="$(LC_NUMERIC=C ${lscpu} 2>/dev/null)"
+ CPU_INFO_SOURCE="lscpu"
+ LCPU_COUNT="$(echo "${lscpu_output}" | grep "^CPU(s):" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ CPU_VENDOR="$(echo "${lscpu_output}" | grep "^Vendor ID:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ CPU_MODEL="$(echo "${lscpu_output}" | grep "^Model name:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ possible_cpu_freq="$(echo "${lscpu_output}" | grep -F "CPU max MHz:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | grep -o '^[0-9]*') MHz"
+elif [ -n "${dmidecode}" ] && dmidecode -t processor >/dev/null 2>&1 ; then
+ dmidecode_output="$(${dmidecode} -t processor 2>/dev/null)"
+ CPU_INFO_SOURCE="dmidecode"
+ LCPU_COUNT="$(echo "${dmidecode_output}" | grep -F "Thread Count:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ CPU_VENDOR="$(echo "${dmidecode_output}" | grep -F "Manufacturer:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ CPU_MODEL="$(echo "${dmidecode_output}" | grep -F "Version:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ possible_cpu_freq="$(echo "${dmidecode_output}" | grep -F "Current Speed:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+else
+ if [ -n "${nproc}" ] ; then
+ CPU_INFO_SOURCE="nproc"
+ LCPU_COUNT="$(${nproc})"
+ elif [ "${KERNEL_NAME}" = FreeBSD ] ; then
+ CPU_INFO_SOURCE="sysctl"
+ LCPU_COUNT="$(sysctl -n kern.smp.cpus)"
+ elif [ -d /sys/devices/system/cpu ] ; then
+ CPU_INFO_SOURCE="sysfs"
+ # This is potentially more accurate than checking `/proc/cpuinfo`.
+ LCPU_COUNT="$(find /sys/devices/system/cpu -mindepth 1 -maxdepth 1 -type d -name 'cpu*' | grep -cEv 'idle|freq')"
+ elif [ -r /proc/cpuinfo ] ; then
+ CPU_INFO_SOURCE="procfs"
+ LCPU_COUNT="$(grep -c ^processor /proc/cpuinfo)"
+ fi
+
+ # If we have GNU uname, we can use that to get CPU info (probably).
+ if unmae --version 2>/dev/null | grep -qF 'GNU coreutils' ; then
+ CPU_INFO_SOURCE="${CPU_INFO_SOURCE} uname"
+ CPU_MODEL="$(uname -p)"
+ CPU_VENDOR="$(uname -i)"
+ elif [ "${KERNEL_NAME}" = FreeBSD ] ; then
+ if ( echo "${CPU_INFO_SOURCE}" | grep -qv sysctl ) ; then
+ CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysctl"
+ fi
+
+ CPU_MODEL="$(sysctl -n hw.model)"
+ elif [ -r /proc/cpuinfo ] ; then
+ if ( echo "${CPU_INFO_SOURCE}" | grep -qv procfs ) ; then
+ CPU_INFO_SOURCE="${CPU_INFO_SOURCE} procfs"
+ fi
+
+ CPU_MODEL="$(grep -F "model name" /proc/cpuinfo | head -n 1 | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ CPU_VENDOR="$(grep -F "vendor_id" /proc/cpuinfo | head -n 1 | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+ fi
+fi
+
+if [ -r /sys/devices/system/cpu/cpu0/cpufreq/base_frequency ] ; then
+ if ( echo "${CPU_INFO_SOURCE}" | grep -qv sysfs ) ; then
+ CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysfs"
+ fi
+
+ CPU_FREQ="$(cat /sys/devices/system/cpu/cpu0/cpufreq/base_frequency)"
+elif [ -n "${possible_cpu_freq}" ] ; then
+ CPU_FREQ="${possible_cpu_freq}"
+elif [ -r /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ] ; then
+ if ( echo "${CPU_INFO_SOURCE}" | grep -qv sysfs ) ; then
+ CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysfs"
+ fi
+
+ CPU_FREQ="$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)"
+fi
+
+freq_units="$(echo "${CPU_FREQ}" | cut -f 2 -d ' ')"
+
+case "${freq_units}" in
+ GHz)
+ value="$(echo "${CPU_FREQ}" | cut -f 1 -d ' ')"
+ CPU_FREQ="$((value*1000*1000*1000))"
+ ;;
+ MHz)
+ value="$(echo "${CPU_FREQ}" | cut -f 1 -d ' ')"
+ CPU_FREQ="$((value*1000*1000))"
+ ;;
+ KHz)
+ value="$(echo "${CPU_FREQ}" | cut -f 1 -d ' ')"
+ CPU_FREQ="$((value*1000))"
+ ;;
+ *)
+ ;;
+esac
+
+# -------------------------------------------------------------------------------------------------
+# Detect the total system RAM
+
+TOTAL_RAM="unknown"
+RAM_DETECTION="none"
+
+if [ "${KERNEL_NAME}" = FreeBSD ] ; then
+ RAM_DETECTION="sysctl"
+ TOTAL_RAM="$(sysctl -n hw.physmem)"
+elif [ -r /proc/meminfo ] ; then
+ RAM_DETECTION="procfs"
+ TOTAL_RAM="$(grep -F MemTotal /proc/meminfo | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | cut -f 1 -d ' ')"
+ TOTAL_RAM="$((TOTAL_RAM*1024))"
+fi
+
echo "NETDATA_CONTAINER_OS_NAME=${CONTAINER_NAME}"
echo "NETDATA_CONTAINER_OS_ID=${CONTAINER_ID}"
@@ -189,4 +306,11 @@ echo "NETDATA_SYSTEM_VIRTUALIZATION=${VIRTUALIZATION}"
echo "NETDATA_SYSTEM_VIRT_DETECTION=${VIRT_DETECTION}"
echo "NETDATA_SYSTEM_CONTAINER=${CONTAINER}"
echo "NETDATA_SYSTEM_CONTAINER_DETECTION=${CONT_DETECTION}"
+echo "NETDATA_CPU_LOGICAL_CPU_COUNT=${LCPU_COUNT}"
+echo "NETDATA_CPU_VENDOR=${CPU_VENDOR}"
+echo "NETDATA_CPU_MODEL=${CPU_MODEL}"
+echo "NETDATA_CPU_FREQ=${CPU_FREQ}"
+echo "NETDATA_CPU_DETECTION=${CPU_INFO_SOURCE}"
+echo "NETDATA_TOTAL_RAM=${TOTAL_RAM}"
+echo "NETDATA_RAM_DETECTION=${RAM_DETECTION}"