@cryptotaxi247 / netdata-1 / commits / db265d6f6

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.

Austin S. Hemmelgarn committed Jan 24, 2020 at 10:04 UTC db265d6f63182cd5ee58bf6f76cb50a5f41dd263
1 file changed +124
daemon/system-info.sh
+124
@@ -169,6 +169,123 @@ else
169 fi
170 fi
171
172 +# -------------------------------------------------------------------------------------------------
173 +# Detect information about the CPU
174 +
175 +LCPU_COUNT="unknown"
176 +CPU_MODEL="unknown"
177 +CPU_VENDOR="unknown"
178 +CPU_FREQ="unknown"
179 +CPU_INFO_SOURCE="none"
180 +
181 +possible_cpu_freq=""
182 +nproc="$(command -v nproc)"
183 +lscpu="$(command -v lscpu)"
184 +lscpu_output=""
185 +dmidecode="$(command -v dmidecode)"
186 +dmidecode_output=""
187 +
188 +if [ -n "${lscpu}" ] && lscpu >/dev/null 2>&1 ; then
189 + lscpu_output="$(LC_NUMERIC=C ${lscpu} 2>/dev/null)"
190 + CPU_INFO_SOURCE="lscpu"
191 + LCPU_COUNT="$(echo "${lscpu_output}" | grep "^CPU(s):" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
192 + CPU_VENDOR="$(echo "${lscpu_output}" | grep "^Vendor ID:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
193 + CPU_MODEL="$(echo "${lscpu_output}" | grep "^Model name:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
194 + 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"
195 +elif [ -n "${dmidecode}" ] && dmidecode -t processor >/dev/null 2>&1 ; then
196 + dmidecode_output="$(${dmidecode} -t processor 2>/dev/null)"
197 + CPU_INFO_SOURCE="dmidecode"
198 + LCPU_COUNT="$(echo "${dmidecode_output}" | grep -F "Thread Count:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
199 + CPU_VENDOR="$(echo "${dmidecode_output}" | grep -F "Manufacturer:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
200 + CPU_MODEL="$(echo "${dmidecode_output}" | grep -F "Version:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
201 + possible_cpu_freq="$(echo "${dmidecode_output}" | grep -F "Current Speed:" | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
202 +else
203 + if [ -n "${nproc}" ] ; then
204 + CPU_INFO_SOURCE="nproc"
205 + LCPU_COUNT="$(${nproc})"
206 + elif [ "${KERNEL_NAME}" = FreeBSD ] ; then
207 + CPU_INFO_SOURCE="sysctl"
208 + LCPU_COUNT="$(sysctl -n kern.smp.cpus)"
209 + elif [ -d /sys/devices/system/cpu ] ; then
210 + CPU_INFO_SOURCE="sysfs"
211 + # This is potentially more accurate than checking `/proc/cpuinfo`.
212 + LCPU_COUNT="$(find /sys/devices/system/cpu -mindepth 1 -maxdepth 1 -type d -name 'cpu*' | grep -cEv 'idle|freq')"
213 + elif [ -r /proc/cpuinfo ] ; then
214 + CPU_INFO_SOURCE="procfs"
215 + LCPU_COUNT="$(grep -c ^processor /proc/cpuinfo)"
216 + fi
217 +
218 + # If we have GNU uname, we can use that to get CPU info (probably).
219 + if unmae --version 2>/dev/null | grep -qF 'GNU coreutils' ; then
220 + CPU_INFO_SOURCE="${CPU_INFO_SOURCE} uname"
221 + CPU_MODEL="$(uname -p)"
222 + CPU_VENDOR="$(uname -i)"
223 + elif [ "${KERNEL_NAME}" = FreeBSD ] ; then
224 + if ( echo "${CPU_INFO_SOURCE}" | grep -qv sysctl ) ; then
225 + CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysctl"
226 + fi
227 +
228 + CPU_MODEL="$(sysctl -n hw.model)"
229 + elif [ -r /proc/cpuinfo ] ; then
230 + if ( echo "${CPU_INFO_SOURCE}" | grep -qv procfs ) ; then
231 + CPU_INFO_SOURCE="${CPU_INFO_SOURCE} procfs"
232 + fi
233 +
234 + CPU_MODEL="$(grep -F "model name" /proc/cpuinfo | head -n 1 | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
235 + CPU_VENDOR="$(grep -F "vendor_id" /proc/cpuinfo | head -n 1 | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
236 + fi
237 +fi
238 +
239 +if [ -r /sys/devices/system/cpu/cpu0/cpufreq/base_frequency ] ; then
240 + if ( echo "${CPU_INFO_SOURCE}" | grep -qv sysfs ) ; then
241 + CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysfs"
242 + fi
243 +
244 + CPU_FREQ="$(cat /sys/devices/system/cpu/cpu0/cpufreq/base_frequency)"
245 +elif [ -n "${possible_cpu_freq}" ] ; then
246 + CPU_FREQ="${possible_cpu_freq}"
247 +elif [ -r /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ] ; then
248 + if ( echo "${CPU_INFO_SOURCE}" | grep -qv sysfs ) ; then
249 + CPU_INFO_SOURCE="${CPU_INFO_SOURCE} sysfs"
250 + fi
251 +
252 + CPU_FREQ="$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)"
253 +fi
254 +
255 +freq_units="$(echo "${CPU_FREQ}" | cut -f 2 -d ' ')"
256 +
257 +case "${freq_units}" in
258 + GHz)
259 + value="$(echo "${CPU_FREQ}" | cut -f 1 -d ' ')"
260 + CPU_FREQ="$((value*1000*1000*1000))"
261 + ;;
262 + MHz)
263 + value="$(echo "${CPU_FREQ}" | cut -f 1 -d ' ')"
264 + CPU_FREQ="$((value*1000*1000))"
265 + ;;
266 + KHz)
267 + value="$(echo "${CPU_FREQ}" | cut -f 1 -d ' ')"
268 + CPU_FREQ="$((value*1000))"
269 + ;;
270 + *)
271 + ;;
272 +esac
273 +
274 +# -------------------------------------------------------------------------------------------------
275 +# Detect the total system RAM
276 +
277 +TOTAL_RAM="unknown"
278 +RAM_DETECTION="none"
279 +
280 +if [ "${KERNEL_NAME}" = FreeBSD ] ; then
281 + RAM_DETECTION="sysctl"
282 + TOTAL_RAM="$(sysctl -n hw.physmem)"
283 +elif [ -r /proc/meminfo ] ; then
284 + RAM_DETECTION="procfs"
285 + TOTAL_RAM="$(grep -F MemTotal /proc/meminfo | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | cut -f 1 -d ' ')"
286 + TOTAL_RAM="$((TOTAL_RAM*1024))"
287 +fi
288 +
289
290 echo "NETDATA_CONTAINER_OS_NAME=${CONTAINER_NAME}"
291 echo "NETDATA_CONTAINER_OS_ID=${CONTAINER_ID}"
@@ -189,4 +306,11 @@ echo "NETDATA_SYSTEM_VIRTUALIZATION=${VIRTUALIZATION}"
306 echo "NETDATA_SYSTEM_VIRT_DETECTION=${VIRT_DETECTION}"
307 echo "NETDATA_SYSTEM_CONTAINER=${CONTAINER}"
308 echo "NETDATA_SYSTEM_CONTAINER_DETECTION=${CONT_DETECTION}"
309 +echo "NETDATA_CPU_LOGICAL_CPU_COUNT=${LCPU_COUNT}"
310 +echo "NETDATA_CPU_VENDOR=${CPU_VENDOR}"
311 +echo "NETDATA_CPU_MODEL=${CPU_MODEL}"
312 +echo "NETDATA_CPU_FREQ=${CPU_FREQ}"
313 +echo "NETDATA_CPU_DETECTION=${CPU_INFO_SOURCE}"
314 +echo "NETDATA_TOTAL_RAM=${TOTAL_RAM}"
315 +echo "NETDATA_RAM_DETECTION=${RAM_DETECTION}"
316