---
# System prepended metadata

title: node exporter 安裝

---

# node exporter 安裝
```
mkdir -p /mnt/storage/node_exporter
vi /mnt/storage/node_exporter/node_exporter_ctl
vi /mnt/storage/node_exporter/utils.sh

chmod 755 /mnt/storage/node_exporter/node_exporter_ctl
chmod 755 /mnt/storage/node_exporter/utils.sh

tar -zxvf node_exporter-0.17.0.linux-amd64.tar.gz
cp node_exporter-0.17.0.linux-amd64/node_exporter /mnt/storage/node_exporter/

vi /etc/systemd/system/nodeexporter.service
service nodeexporter status 
service nodeexporter start 
systemctl enable nodeexporter
```

node_exporter_ctl
```
#!/usr/bin/env bash

set -eu

RUN_DIR=/var/run/node_exporter
LOG_DIR=/var/log/node_exporter
TMP_DIR=/var/tmp/node_exporter
STORE_DIR=/mnt/storage/node_exporter
mkdir -p ${RUN_DIR} ${LOG_DIR} ${TMP_DIR} ${STORE_DIR}

PIDFILE=${RUN_DIR}/node_exporter.pid

source /mnt/storage/node_exporter/utils.sh
exec 1>> ${LOG_DIR}/$(basename "$0").stdout.log
exec 2>> ${LOG_DIR}/$(basename "$0").stderr.log

export PATH=/mnt/storage/node_exporter:${PATH}



case $1 in
  start)
    pid_guard ${PIDFILE} "node_exporter"
    echo $$ > ${PIDFILE}

    exec node_exporter \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
       \
      --collector.supervisord.url="http://localhost:9100/RPC2" \
       \
       \
       \
       --collector.arp \
       \
       \
       \
       --collector.bcache \
       \
       \
       \
       --collector.bonding \
       \
       \
       \
       --no-collector.buddyinfo \
       \
       \
       \
       --collector.conntrack \
       \
       \
       \
       --collector.cpu \
       \
       \
       \
       --collector.diskstats \
       \
       \
       \
       --no-collector.drbd \
       \
       \
       \
       --collector.edac \
       \
       \
       \
       --collector.entropy \
       \
       \
       \
       --collector.filefd \
       \
       \
       \
       --collector.filesystem \
       \
       \
       \
       --collector.hwmon \
       \
       \
       \
       --collector.infiniband \
       \
       \
       \
       --no-collector.interrupts \
       \
       \
       \
       --collector.ipvs \
       \
       \
       \
       --no-collector.ksmd \
       \
       \
       \
       --collector.loadavg \
       \
       \
       \
       --no-collector.logind \
       \
       \
       \
       --collector.mdadm \
       \
       \
       \
       --collector.meminfo \
       \
       \
       \
       --no-collector.meminfo_numa \
       \
       \
       \
       --no-collector.mountstats \
       \
       \
       \
       --collector.netdev \
       \
       \
       \
       --collector.netclass \
       \
       \
       \
       --collector.netstat \
       \
       \
       \
       --collector.nfs \
       \
       \
       \
       --collector.nfsd \
       \
       \
       \
       --no-collector.ntp \
       \
       \
       \
       --no-collector.processes \
       \
       \
       \
       --no-collector.qdisc \
       \
       \
       \
       --no-collector.runit \
       \
       \
       \
       --collector.sockstat \
       \
       \
       \
       --collector.stat \
       \
       \
       \
       --no-collector.supervisord \
       \
       \
       \
       --no-collector.systemd \
       \
       \
       \
       --no-collector.tcpstat \
       \
       \
       \
       --collector.textfile \
       \
       \
       \
       --collector.time \
       \
       \
       \
       --collector.timex \
       \
       \
       \
       --collector.uname \
       \
       \
       \
       --collector.vmstat \
       \
       \
       \
       --collector.wifi \
       \
       \
       \
       --collector.xfs \
       \
       \
       \
       --collector.zfs \
       \
       \
      --web.listen-address=":9100" \
       \
       \
       \
      >>  ${LOG_DIR}/node_exporter.stdout.log \
      2>> ${LOG_DIR}/node_exporter.stderr.log
    ;;

  stop)
    kill_and_wait ${PIDFILE}
    ;;

  *)
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;

esac
exit 0
```

utils.sh
```
#!/usr/bin/env bash

function pid_is_running() {
  declare pid="$1"
  ps -p "${pid}" >/dev/null 2>&1
}

# pid_guard
#
# @param pidfile
# @param name [String] an arbitrary name that might show up in STDOUT on errors
#
# Run this before attempting to start new processes that may use the same :pidfile:.
# If an old process is running on the pid found in the :pidfile:, exit 1. Otherwise,
# remove the stale :pidfile: if it exists.
#
function pid_guard() {
  declare pidfile="$1" name="$2"

  echo "------------ STARTING $(basename "$0") at $(date) --------------" | tee /dev/stderr

  if [ ! -f "${pidfile}" ]; then
    return 0
  fi

  local pid
  pid=$(head -1 "${pidfile}")

  if pid_is_running "${pid}"; then
    echo "${name} is already running, please stop it first"
    exit 1
  fi

  echo "Removing stale pidfile"
  rm "${pidfile}"
}

# wait_pid_death
#
# @param pid
# @param timeout
#
# Watch a :pid: for :timeout: seconds, waiting for it to die.
# If it dies before :timeout:, exit 0. If not, exit 1.
#
# Note that this should be run in a subshell, so that the current
# shell does not exit.
#
function wait_pid_death() {
  declare pid="$1" timeout="$2"

  local countdown
  countdown=$(( timeout * 10 ))

  while true; do
    if ! pid_is_running "${pid}"; then
      return 0
    fi

    if [ ${countdown} -le 0 ]; then
      return 1
    fi

    countdown=$(( countdown - 1 ))
    sleep 0.1
  done
}

# kill_and_wait
#
# @param pidfile
# @param timeout [default 25s]
#
# For a pid found in :pidfile:, send a `kill -15` TERM, then wait for :timeout: seconds to
# see if it dies on its own. If not, send it a `kill -9`. If the process does die,
# exit 0 and remove the :pidfile:. If after all of this, the process does not actually
# die, exit 1.
#
# Note:
# Monit default timeout for start/stop is 30s
# Append 'with timeout {n} seconds' to monit start/stop program configs
#
function kill_and_wait() {
  declare pidfile="$1" timeout="${2:-25}" sigkill_on_timeout="${3:-1}"

  if [ ! -f "${pidfile}" ]; then
    echo "Pidfile ${pidfile} doesn't exist"
    exit 0
  fi

  local pid
  pid=$(head -1 "${pidfile}")

  if [ -z "${pid}" ]; then
    echo "Unable to get pid from ${pidfile}"
    exit 1
  fi

  if ! pid_is_running "${pid}"; then
    echo "Process ${pid} is not running"
    rm -f "${pidfile}"
    exit 0
  fi

  echo "Killing ${pidfile}: ${pid} "
  kill "${pid}"

  if ! wait_pid_death "${pid}" "${timeout}"; then
    if [ "${sigkill_on_timeout}" = "1" ]; then
      echo "Kill timed out, using kill -9 on ${pid}"
      kill -9 "${pid}"
      sleep 0.5
    fi
  fi

  if pid_is_running "${pid}"; then
    echo "Timed Out"
    exit 1
  else
    echo "Stopped"
    rm -f "${pidfile}"
  fi
}

running_in_container() {
  # look for a non-root cgroup
  grep --quiet --invert-match ':/$' /proc/self/cgroup
}
```

nodeexporter.service
```
[Unit]
Description=node exporter
After=network.target
Documentation=node exporter

[Service]
Type=simple
ExecStart=/mnt/storage/node_exporter/node_exporter_ctl start
ExecStop=/mnt/storage/node_exporter/node_exporter_ctl stop
PIDFile=/var/run/node_exporter/node_exporter.pid
TimeoutStopSec=0

[Install]
WantedBy=multi-user.target
Alias=node_exporter.service

```
