copy-logs.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #!/bin/bash
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. # implied.
  13. #
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. export PATH=$PATH:/usr/local/sbin:/usr/sbin
  17. # This script attempts to recover as much generic diagnostic logs as it can
  18. LOGROOT=${WORKSPACE:-/tmp}
  19. LOGDIR="${LOGROOT}/logs"
  20. DIAG_LOGDIR="${LOGDIR}/diag"
  21. CONF_LOGDIR="${LOGDIR}/etc"
  22. GIT_URL="http://git.openstack.org/cgit"
  23. PROJECTS_URL="${GIT_URL}/openstack/governance/plain/reference/projects.yaml"
  24. if [ $(id -u) != 0 ]; then
  25. SUDO='sudo'
  26. fi
  27. $SUDO mkdir -p "${DIAG_LOGDIR}"
  28. $SUDO mkdir -p "${CONF_LOGDIR}"
  29. function get_diag_commands {
  30. echo "Setting up list of diagnostic commands to run..."
  31. commands=(
  32. 'df -h'
  33. 'dmesg -T'
  34. 'fdisk -l'
  35. 'lsmod'
  36. 'iptables -vnL'
  37. 'iptables -vnL -t nat'
  38. 'iptables -vnL -t mangle'
  39. 'ifconfig -a'
  40. 'ip addr show'
  41. 'lsmod'
  42. 'timeout 15 lsof' # High potential of getting stuck
  43. 'lsof -Pni'
  44. 'netstat -ntlp'
  45. 'pstree -p'
  46. 'sysctl -a'
  47. 'yum repolist -v'
  48. 'rpm -qa'
  49. 'journalctl --no-pager'
  50. 'ulimit -n'
  51. )
  52. echo "Installing required RPM packages..."
  53. $SUDO yum -y install coreutils curl file lsof net-tools psmisc
  54. echo "Running diagnostic commands..."
  55. for ((i = 0; i < ${#commands[@]}; i++)); do
  56. # filenames have underscores instead of spaces or slashes
  57. filename="$(echo "${commands[$i]}" |sed -e "s%[ \/]%_%g").txt"
  58. # Run diagnostic commands but don't fail the whole thing if one command fails
  59. $SUDO bash -c "${commands[$i]} 2>&1 > ${DIAG_LOGDIR}/${filename}" || true
  60. done
  61. }
  62. function get_config_and_logs {
  63. echo "Setting up and discovering directories and files to recover..."
  64. # Paths we're interested in
  65. paths=(
  66. '/proc/cpuinfo'
  67. '/proc/meminfo'
  68. '/proc/mounts'
  69. '/etc/os-release'
  70. '/etc/sudoers'
  71. '/etc/sudoers.d'
  72. '/etc/hosts'
  73. '/etc/pip.conf'
  74. '/etc/libvirt'
  75. '/var/log/libvirt'
  76. '/etc/qemu'
  77. '/etc/qemu-kvm'
  78. '/etc/openvswitch'
  79. '/var/log/openvswitch'
  80. '/etc/openstack-dashboard'
  81. '/etc/aodh' # aodh is nested under telemetry in governance
  82. '/var/log/aodh'
  83. '/etc/ceilometer' # ceilometer is nested under telemetry in governance
  84. '/var/log/ceilometer'
  85. '/etc/gnocchi' # gnocchi is nested under telemetry in governance
  86. '/var/log/gnocchi'
  87. '/var/log/panko'
  88. '/etc/panko' # panko is nested under telemetry in governance
  89. '/etc/rabbitmq/'
  90. '/var/log/rabbitmq'
  91. '/etc/my.cnf.d'
  92. '/var/log/mariadb'
  93. '/etc/httpd/conf.d/'
  94. '/var/log/httpd'
  95. '/var/tmp/packstack/latest'
  96. '/var/tmp/packstack/latest/testrepository.subunit' # So we're copying it
  97. '/var/log/audit' # to the root of
  98. '/var/log/secure' # /logs
  99. '/var/log/messages'
  100. '/var/log/dstat.log'
  101. '/etc/puppet/puppet.conf'
  102. '/etc/puppet/hiera.yaml'
  103. )
  104. # Add discovered project directories from official governance
  105. # Optimistic parsing.. find a better way
  106. project_list=$(curl $PROJECTS_URL 2>&1 | egrep "^\S+:$" |cut -f1 -d :)
  107. for project in $project_list; do
  108. paths+=("/etc/${project}")
  109. paths+=("/var/log/${project}")
  110. done
  111. echo "Recovering files and directories..."
  112. # Send things to appropriate log directories if they exist
  113. for ((i = 0; i < ${#paths[@]}; i++)); do
  114. if [ -e ${paths[$i]} ]; then
  115. if [[ "${paths[$i]}" =~ /proc/ ]]; then
  116. $SUDO cp "${paths[$i]}" ${DIAG_LOGDIR}/
  117. elif [[ "${paths[$i]}" =~ /var/ ]]; then
  118. $SUDO cp -Lr "${paths[$i]}" ${LOGDIR}/
  119. elif [[ "${paths[$i]}" =~ /etc/ ]]; then
  120. $SUDO cp -Lr "${paths[$i]}" ${CONF_LOGDIR}/
  121. fi
  122. fi
  123. done
  124. }
  125. function ensure_log_properties {
  126. echo "Making sure directories and files have the right properties..."
  127. FIND="${SUDO} find ${LOGDIR} ! -path '*.git/*'"
  128. # Ensure files are readable by everyone
  129. $FIND -type d -execdir $SUDO chmod 755 '{}' \;
  130. $FIND -type f -execdir $SUDO chmod 644 '{}' \;
  131. # Ensure files are in .txt when possible (web mime type)
  132. for file in $($FIND -type f ! -name "*.txt"); do
  133. if [[ "$(file --mime-type ${file} |cut -f2 -d :)" =~ text ]]; then
  134. $SUDO mv ${file} ${file}.txt
  135. fi
  136. done
  137. echo "Compressing all text files..."
  138. # Compress all files
  139. $FIND -iname '*.txt' -execdir gzip -f -9 {} \+
  140. echo "Compressed log and configuration can be found in ${LOGDIR}."
  141. }
  142. function recover_default_logs {
  143. get_diag_commands
  144. get_config_and_logs
  145. ensure_log_properties
  146. }