| 1 | #!/usr/bin/env bash |
| 2 | # SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | # |
| 4 | # This plugin requires a latest version of ioping. |
| 5 | # You can compile it from source, by running me with option: install |
| 6 | |
| 7 | export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin:@sbindir_POST@" |
| 8 | export LC_ALL=C |
| 9 | |
| 10 | usage="$(basename "$0") [install] [-h] [-e] |
| 11 | |
| 12 | where: |
| 13 | install install ioping binary |
| 14 | -e, --env path to environment file (defaults to '/etc/netdata/.environment' |
| 15 | -h show this help text" |
| 16 | |
| 17 | INSTALL=0 |
| 18 | ENVIRONMENT_FILE="/etc/netdata/.environment" |
| 19 | |
| 20 | while :; do |
| 21 | case "$1" in |
| 22 | -h | --help) |
| 23 | echo "$usage" >&2 |
| 24 | exit 1 |
| 25 | ;; |
| 26 | install) |
| 27 | INSTALL=1 |
| 28 | shift |
| 29 | ;; |
| 30 | -e | --env) |
| 31 | ENVIRONMENT_FILE="$2" |
| 32 | shift 2 |
| 33 | ;; |
| 34 | -*) |
| 35 | echo "$usage" >&2 |
| 36 | exit 1 |
| 37 | ;; |
| 38 | *) break ;; |
| 39 | esac |
| 40 | done |
| 41 | |
| 42 | if [ "$INSTALL" == "1" ] |
| 43 | then |
| 44 | [ "${UID}" != 0 ] && echo >&2 "Please run me as root. This will install a single binary file: /usr/libexec/netdata/plugins.d/ioping." && exit 1 |
| 45 | |
| 46 | source "${ENVIRONMENT_FILE}" || exit 1 |
| 47 | |
| 48 | run() { |
| 49 | printf >&2 " > " |
| 50 | printf >&2 "%q " "${@}" |
| 51 | printf >&2 "\n" |
| 52 | "${@}" || exit 1 |
| 53 | } |
| 54 | |
| 55 | download() { |
| 56 | local git="$(which git 2>/dev/null || command -v git 2>/dev/null)" |
| 57 | [ ! -z "${git}" ] && run git clone "${1}" "${2}" && return 0 |
| 58 | |
| 59 | echo >&2 "Cannot find 'git' in this system." && exit 1 |
| 60 | } |
| 61 | |
| 62 | tmp=$(mktemp -d /tmp/netdata-ioping-XXXXXX) |
| 63 | [ ! -d "${NETDATA_PREFIX}/usr/libexec/netdata" ] && run mkdir -p "${NETDATA_PREFIX}/usr/libexec/netdata" |
| 64 | |
| 65 | run cd "${tmp}" |
| 66 | |
| 67 | if [ -d ioping-netdata ] |
| 68 | then |
| 69 | run rm -rf ioping-netdata || exit 1 |
| 70 | fi |
| 71 | |
| 72 | download 'https://github.com/netdata/ioping.git' 'ioping-netdata' |
| 73 | [ $? -ne 0 ] && exit 1 |
| 74 | run cd ioping-netdata || exit 1 |
| 75 | |
| 76 | INSTALL_PATH="${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" |
| 77 | |
| 78 | run make clean |
| 79 | run make |
| 80 | run mv ioping "${INSTALL_PATH}" |
| 81 | run chown root:"${NETDATA_GROUP}" "${INSTALL_PATH}" |
| 82 | run chmod 4750 "${INSTALL_PATH}" |
| 83 | echo >&2 |
| 84 | echo >&2 "All done, you have a compatible ioping now at ${INSTALL_PATH}." |
| 85 | echo >&2 |
| 86 | |
| 87 | exit 0 |
| 88 | fi |
| 89 | |
| 90 | # ----------------------------------------------------------------------------- |
| 91 | # logging |
| 92 | |
| 93 | PROGRAM_NAME="$(basename "${0}")" |
| 94 | |
| 95 | # these should be the same with syslog() priorities |
| 96 | NDLP_EMERG=0 # system is unusable |
| 97 | NDLP_ALERT=1 # action must be taken immediately |
| 98 | NDLP_CRIT=2 # critical conditions |
| 99 | NDLP_ERR=3 # error conditions |
| 100 | NDLP_WARN=4 # warning conditions |
| 101 | NDLP_NOTICE=5 # normal but significant condition |
| 102 | NDLP_INFO=6 # informational |
| 103 | NDLP_DEBUG=7 # debug-level messages |
| 104 | |
| 105 | # the max (numerically) log level we will log |
| 106 | LOG_LEVEL=$NDLP_INFO |
| 107 | |
| 108 | set_log_min_priority() { |
| 109 | case "${NETDATA_LOG_LEVEL,,}" in |
| 110 | "emerg" | "emergency") |
| 111 | LOG_LEVEL=$NDLP_EMERG |
| 112 | ;; |
| 113 | |
| 114 | "alert") |
| 115 | LOG_LEVEL=$NDLP_ALERT |
| 116 | ;; |
| 117 | |
| 118 | "crit" | "critical") |
| 119 | LOG_LEVEL=$NDLP_CRIT |
| 120 | ;; |
| 121 | |
| 122 | "err" | "error") |
| 123 | LOG_LEVEL=$NDLP_ERR |
| 124 | ;; |
| 125 | |
| 126 | "warn" | "warning") |
| 127 | LOG_LEVEL=$NDLP_WARN |
| 128 | ;; |
| 129 | |
| 130 | "notice") |
| 131 | LOG_LEVEL=$NDLP_NOTICE |
| 132 | ;; |
| 133 | |
| 134 | "info") |
| 135 | LOG_LEVEL=$NDLP_INFO |
| 136 | ;; |
| 137 | |
| 138 | "debug") |
| 139 | LOG_LEVEL=$NDLP_DEBUG |
| 140 | ;; |
| 141 | esac |
| 142 | } |
| 143 | |
| 144 | set_log_min_priority |
| 145 | |
| 146 | log() { |
| 147 | local level="${1}" |
| 148 | shift 1 |
| 149 | |
| 150 | [[ -n "$level" && -n "$LOG_LEVEL" && "$level" -gt "$LOG_LEVEL" ]] && return |
| 151 | |
| 152 | systemd-cat-native --log-as-netdata <<EOFLOG |
| 153 | INVOCATION_ID=${NETDATA_INVOCATION_ID} |
| 154 | SYSLOG_IDENTIFIER=${PROGRAM_NAME} |
| 155 | PRIORITY=${level} |
| 156 | THREAD_TAG=ioping.plugin |
| 157 | ND_LOG_SOURCE=collector |
| 158 | MESSAGE=${MODULE_NAME}: ${*//$'\n'/\\n} |
| 159 | |
| 160 | EOFLOG |
| 161 | # AN EMPTY LINE IS NEEDED ABOVE |
| 162 | } |
| 163 | |
| 164 | info() { |
| 165 | log "$NDLP_INFO" "${@}" |
| 166 | } |
| 167 | |
| 168 | warning() { |
| 169 | log "$NDLP_WARN" "${@}" |
| 170 | } |
| 171 | |
| 172 | error() { |
| 173 | log "$NDLP_ERR" "${@}" |
| 174 | } |
| 175 | |
| 176 | disable() { |
| 177 | log "${@}" |
| 178 | echo "DISABLE" |
| 179 | exit 1 |
| 180 | } |
| 181 | |
| 182 | fatal() { |
| 183 | disable "$NDLP_ALERT" "${@}" |
| 184 | } |
| 185 | |
| 186 | debug() { |
| 187 | log "$NDLP_DEBUG" "${@}" |
| 188 | } |
| 189 | |
| 190 | # ----------------------------------------------------------------------------- |
| 191 | |
| 192 | # store in ${plugin} the name we run under |
| 193 | # this allows us to copy/link ioping.plugin under a different name |
| 194 | # to have multiple ioping plugins running with different settings |
| 195 | plugin="${PROGRAM_NAME/.plugin/}" |
| 196 | |
| 197 | |
| 198 | # ----------------------------------------------------------------------------- |
| 199 | |
| 200 | # the frequency to send info to netdata |
| 201 | # passed by netdata as the first parameter |
| 202 | update_every="${1-1}" |
| 203 | |
| 204 | # the netdata configuration directory |
| 205 | # passed by netdata as an environment variable |
| 206 | [ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@" |
| 207 | [ -z "${NETDATA_STOCK_CONFIG_DIR}" ] && NETDATA_STOCK_CONFIG_DIR="@libconfigdir_POST@" |
| 208 | |
| 209 | # the netdata directory for internal binaries |
| 210 | [ -z "${NETDATA_PLUGINS_DIR}" ] && NETDATA_PLUGINS_DIR="@pluginsdir_POST@" |
| 211 | |
| 212 | # ----------------------------------------------------------------------------- |
| 213 | # configuration options |
| 214 | # can be overwritten at /etc/netdata/ioping.conf |
| 215 | |
| 216 | # the ioping binary to use |
| 217 | # we need one that can output netdata friendly info (supporting: -N) |
| 218 | # if you have multiple versions, put here the full filename of the right one |
| 219 | ioping="${NETDATA_PLUGINS_DIR}/ioping" |
| 220 | |
| 221 | # the destination to ioping |
| 222 | destination="" |
| 223 | |
| 224 | # the request size in bytes to ping the disk |
| 225 | request_size="4k" |
| 226 | |
| 227 | # ioping options |
| 228 | ioping_opts="-T 1000000" |
| 229 | |
| 230 | # ----------------------------------------------------------------------------- |
| 231 | # load the configuration files |
| 232 | |
| 233 | for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/${plugin}.conf" "${NETDATA_USER_CONFIG_DIR}/${plugin}.conf"; do |
| 234 | if [ -f "${CONFIG}" ]; then |
| 235 | debug "Loading config file '${CONFIG}'..." |
| 236 | source "${CONFIG}" |
| 237 | [ $? -ne 0 ] && warn "Failed to load config file '${CONFIG}'." |
| 238 | elif [[ $CONFIG =~ ^$NETDATA_USER_CONFIG_DIR ]]; then |
| 239 | debug "Cannot find file '${CONFIG}'." |
| 240 | fi |
| 241 | done |
| 242 | |
| 243 | if [ -z "${destination}" ] |
| 244 | then |
| 245 | disable $NDLP_DEBUG "destination is not configured - nothing to do." |
| 246 | fi |
| 247 | |
| 248 | if [ ! -f "${ioping}" ] |
| 249 | then |
| 250 | disable $NDLP_ERR "ioping command is not found. Please set its full path in '${NETDATA_USER_CONFIG_DIR}/${plugin}.conf'" |
| 251 | fi |
| 252 | |
| 253 | if [ ! -x "${ioping}" ] |
| 254 | then |
| 255 | disable $NDLP_ERR "ioping command '${ioping}' is not executable - cannot proceed." |
| 256 | fi |
| 257 | |
| 258 | # the ioping options we will use |
| 259 | options=( -N -i ${update_every} -s ${request_size} ${ioping_opts} ${destination} ) |
| 260 | |
| 261 | # execute ioping |
| 262 | debug "starting ioping: ${ioping} ${options[*]}" |
| 263 | |
| 264 | exec "${ioping}" "${options[@]}" |
| 265 | |
| 266 | # if we cannot execute ioping, stop |
| 267 | error "command '${ioping} ${options[*]}' failed to be executed (returned code $?)." |