cgroup-name.sh.in 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #!/usr/bin/env bash
  2. # netdata
  3. # real-time performance and health monitoring, done right!
  4. # (C) 2016 Costa Tsaousis <costa@tsaousis.gr>
  5. # SPDX-License-Identifier: GPL-3.0-or-later
  6. #
  7. # Script to find a better name for cgroups
  8. #
  9. export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
  10. export LC_ALL=C
  11. # -----------------------------------------------------------------------------
  12. PROGRAM_NAME="$(basename "${0}")"
  13. logdate() {
  14. date "+%Y-%m-%d %H:%M:%S"
  15. }
  16. log() {
  17. local status="${1}"
  18. shift
  19. echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}"
  20. }
  21. warning() {
  22. log WARNING "${@}"
  23. }
  24. error() {
  25. log ERROR "${@}"
  26. }
  27. info() {
  28. log INFO "${@}"
  29. }
  30. fatal() {
  31. log FATAL "${@}"
  32. exit 1
  33. }
  34. debug=0
  35. debug() {
  36. [ $debug -eq 1 ] && log DEBUG "${@}"
  37. }
  38. # -----------------------------------------------------------------------------
  39. [ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@"
  40. [ -z "${NETDATA_STOCK_CONFIG_DIR}" ] && NETDATA_STOCK_CONFIG_DIR="@libconfigdir_POST@"
  41. DOCKER_HOST="${DOCKER_HOST:=/var/run/docker.sock}"
  42. CGROUP="${1}"
  43. NAME=
  44. # -----------------------------------------------------------------------------
  45. if [ -z "${CGROUP}" ]
  46. then
  47. fatal "called without a cgroup name. Nothing to do."
  48. fi
  49. for CONFIG in "${NETDATA_USER_CONFIG_DIR}/cgroups-names.conf" "${NETDATA_STOCK_CONFIG_DIR}/cgroups-names.conf"
  50. do
  51. if [ -f "${CONFIG}" ]
  52. then
  53. NAME="$(grep "^${CGROUP} " "${CONFIG}" | sed "s/[[:space:]]\+/ /g" | cut -d ' ' -f 2)"
  54. if [ -z "${NAME}" ]
  55. then
  56. info "cannot find cgroup '${CGROUP}' in '${CONFIG}'."
  57. else
  58. break
  59. fi
  60. #else
  61. # info "configuration file '${CONFIG}' is not available."
  62. fi
  63. done
  64. function docker_get_name_classic {
  65. local id="${1}"
  66. info "Running command: docker ps --filter=id=\"${id}\" --format=\"{{.Names}}\""
  67. NAME="$( docker ps --filter=id="${id}" --format="{{.Names}}" )"
  68. return 0
  69. }
  70. function docker_get_name_api {
  71. local id="${1}"
  72. if [ ! -S "${DOCKER_HOST}" ]
  73. then
  74. warning "Can't find ${DOCKER_HOST}"
  75. return 1
  76. fi
  77. info "Running API command: /containers/${id}/json"
  78. JSON=$(echo -e "GET /containers/${id}/json HTTP/1.0\r\n" | nc -U ${DOCKER_HOST} | grep '^{.*')
  79. NAME=$(echo $JSON | jq -r .Name,.Config.Hostname | grep -v null | head -n1 | sed 's|^/||')
  80. return 0
  81. }
  82. function docker_get_name {
  83. local id="${1}"
  84. if hash docker 2>/dev/null
  85. then
  86. docker_get_name_classic "${id}"
  87. else
  88. docker_get_name_api "${id}" || docker_get_name_classic "${id}"
  89. fi
  90. if [ -z "${NAME}" ]
  91. then
  92. warning "cannot find the name of docker container '${id}'"
  93. NAME="${id:0:12}"
  94. else
  95. info "docker container '${id}' is named '${NAME}'"
  96. fi
  97. }
  98. if [ -z "${NAME}" ]
  99. then
  100. if [[ "${CGROUP}" =~ ^.*docker[-_/\.][a-fA-F0-9]+[-_\.]?.*$ ]]
  101. then
  102. # docker containers
  103. DOCKERID="$( echo "${CGROUP}" | sed "s|^.*docker[-_/]\([a-fA-F0-9]\+\)[-_\.]\?.*$|\1|" )"
  104. # echo "DOCKERID=${DOCKERID}"
  105. if [ ! -z "${DOCKERID}" -a \( ${#DOCKERID} -eq 64 -o ${#DOCKERID} -eq 12 \) ]
  106. then
  107. docker_get_name "${DOCKERID}"
  108. else
  109. error "a docker id cannot be extracted from docker cgroup '${CGROUP}'."
  110. fi
  111. elif [[ "${CGROUP}" =~ ^.*kubepods[_/].*[_/]pod[a-fA-F0-9-]+[_/][a-fA-F0-9]+$ ]]
  112. then
  113. # kubernetes
  114. DOCKERID="$( echo "${CGROUP}" | sed "s|^.*kubepods[_/].*[_/]pod[a-fA-F0-9-]\+[_/]\([a-fA-F0-9]\+\)$|\1|" )"
  115. # echo "DOCKERID=${DOCKERID}"
  116. if [ ! -z "${DOCKERID}" -a \( ${#DOCKERID} -eq 64 -o ${#DOCKERID} -eq 12 \) ]
  117. then
  118. docker_get_name "${DOCKERID}"
  119. else
  120. error "a docker id cannot be extracted from kubernetes cgroup '${CGROUP}'."
  121. fi
  122. elif [[ "${CGROUP}" =~ machine.slice[_/].*\.service ]]
  123. then
  124. # systemd-nspawn
  125. NAME="$(echo ${CGROUP} | sed 's/.*machine.slice[_\/]\(.*\)\.service/\1/g')"
  126. elif [[ "${CGROUP}" =~ machine.slice_machine.*-qemu ]]
  127. then
  128. # libvirtd / qemu virtual machines
  129. # NAME="$(echo ${CGROUP} | sed 's/machine.slice_machine.*-qemu//; s/\/x2d//; s/\/x2d/\-/g; s/\.scope//g')"
  130. NAME="qemu_$(echo ${CGROUP} | sed 's/machine.slice_machine.*-qemu//; s/\/x2d[[:digit:]]*//; s/\/x2d//g; s/\.scope//g')"
  131. elif [[ "${CGROUP}" =~ machine_.*\.libvirt-qemu ]]
  132. then
  133. # libvirtd / qemu virtual machines
  134. NAME="qemu_$(echo ${CGROUP} | sed 's/^machine_//; s/\.libvirt-qemu$//; s/-/_/;')"
  135. elif [[ "${CGROUP}" =~ qemu.slice_([0-9]+).scope && -d /etc/pve ]]
  136. then
  137. # Proxmox VMs
  138. FILENAME="/etc/pve/qemu-server/${BASH_REMATCH[1]}.conf"
  139. if [[ -f $FILENAME && -r $FILENAME ]]
  140. then
  141. NAME="qemu_$(grep -e '^name: ' "/etc/pve/qemu-server/${BASH_REMATCH[1]}.conf" | head -1 | sed -rn 's|\s*name\s*:\s*(.*)?$|\1|p')"
  142. else
  143. error "proxmox config file missing ${FILENAME} or netdata does not have read access. Please ensure netdata is a member of www-data group."
  144. fi
  145. elif [[ "${CGROUP}" =~ lxc_([0-9]+) && -d /etc/pve ]]
  146. then
  147. # Proxmox Containers (LXC)
  148. FILENAME="/etc/pve/lxc/${BASH_REMATCH[1]}.conf"
  149. if [[ -f ${FILENAME} && -r ${FILENAME} ]]
  150. then
  151. NAME=$(grep -e '^hostname: ' /etc/pve/lxc/${BASH_REMATCH[1]}.conf | head -1 | sed -rn 's|\s*hostname\s*:\s*(.*)?$|\1|p')
  152. else
  153. error "proxmox config file missing ${FILENAME} or netdata does not have read access. Please ensure netdata is a member of www-data group."
  154. fi
  155. fi
  156. [ -z "${NAME}" ] && NAME="${CGROUP}"
  157. [ ${#NAME} -gt 100 ] && NAME="${NAME:0:100}"
  158. fi
  159. info "cgroup '${CGROUP}' is called '${NAME}'"
  160. echo "${NAME}"