명령어 옵션을 활용한 팁

1. 가독성을 좋게 출력
column
- mount (ls -al ...) | column -t

2. 메모리 많이 사용하는 프로세스 10개 출력
ps aux | sort -nr -k 4 | head -10 (-n 10 으로 써도 됨)

특정시간이 지나면 명령어를 자동 종료
timeout Ns 명령어
 -> timeout 5s top  (5초 후 top명령어 종료)


문법을 활용한 팁
1. 현재 위치 하위의 디렉토리별 파일 수 카운트
find . -xdev -type d -exec /bin/echo -n "{} :" \; -exec sh -c "ls {} | wc -l" \;
-xdev : 로컬에 있는 파일 시스템만 검색 (마운트한 디렉토리는 검색을 하지 않겠다.)
-exec : 다음에 나오는 명령어 실행
echo -n "{} :" : 디렉토리 검색한 이름과 콜론 출력
\; : 종료
ls {} | wc -l : ls 의 결과값을 wc로 넘겨서 라인수 출력

2. 어떤 프로세스가 io interrupt를 기다리고 있는지 확인 (실시간으로 모니터링할 때 유용)
- 1초마다 date를 찍으며 state code가 D(uninterruptible sleep (usually IO)) 인 프로세스를 출력
while tru; do date; ps auxf | awk '{if($8== "D") print $0;}'; sleep 1; done

3. 특정한 프로그램(프로세스명)이 전체 메모리의 몇 퍼센트를 사용하는지 확인
ps -eo pmem,comm | grep -i "프로세스이름" | awk '{sum+=$1} END {print sum "% fo MEMORY"}'
-> ps -eo pmem,comm | grep -i "nginx" | awk '{sum+=$1} END {print sum "% fo MEMORY"}'

쉘스크립트 점검 팁

https://www.shellcheck.net/

시나리오
 - 예상 불가능한 문제로 백업이 제대로 안됐을 경우에 알림 메세지를 받을 수 있도록 감시 쉘 스크립트를 작성

wc
- 라인 수 , 단어 수 , 바이트, 파일이름 출력
-  -l : 라인 수만 출력

grep
- grep 옵션 "찾을 문자열" 파일명
- -c : 지정한 문자열을 가진 라인이 몇 개 었는지 출력
- -i : 대소문자를 구분
- -r : 현재 디렉토리와 그 하위 디렉토리까지 검색
- -v : 지정한 문자열을 제외한 모든 라인을 출력

function
- 함수를 정의
- 주의할 점
- 쉘 스크립트는 순차적으로 위에서부터 실행, 함수 or 변수를 모아놓은 파일을 가져와 사용할 떄는 가장 상단에서 불러와야 한다. 
-  function 함수명 () {
              매개변수를 받아서 처리할 내용
              함수 처리 루틴
}

function readtest () {
read A
read B
echo ${A} ${B}
}
readtest

- read : 유저가 입력하면 지정한 변수에 넣음


vi backup_monitor.sh

##변수지정
TODAY=$(/bin/date +%Y.%m.%d)
PUSH="/root/SHELL/monitor/tel_push.sh"
LOG="/tmp/bak_report"
HOST=$(hostname)
WEB="/nfs/BACKUP/cent1/* .tgz"
DB1="/nfs/BACKUP/cent2/* cent2 .tgz"
DB2="/nfs/BACKUP/cent2/* DB .tgz"
STR="/nfs/BACKIP/cent3/* .tgz*"
WBK_CNT=$(/usr/bin/ls -1 ${WEB} | /usr/bin/wc -1)
DBK_CNT1=$(usr/bin/ls -1 ${DB1} | /usr/bin/wc -1)
DBK_CNT2=$(usr/bin/ls -1 ${DB1} | /usr/bin/wc -1)
SBK_CNT=$(/usr/bin/ls -1 ${STR} | /usr/bin/wc -1)

##함수정의
- 인자를 두개 받아 비교 메세지를 반환
- 인자1 : 백업이름
- 인자2 : 백업카운트
function chk_cnt(){
##인자를 변수에 할당
NAME="$1"
CNT="$2"
##백업카운트 (${CNT})가 8이 아닐 경우 확인하도록 메세지
##8이 맞을 경우 문제가 없다는 메세지를 출력
if [ "${CNT}" -eq 8 ]
then
/usr/bin/echo "${NAME} 백업파일 문제없음"
/usr/bin/echo
else
/usr/bin/echo "${NAME} 백업파일dl 8개가 아닙니다! 확인하세요 !"
/usr/bin/echo
fi
}

##레포팅파일 초기화
/usr/bin/rm -f "${LOG}"
/usr/bin/touch "${LOG}"

##레포팅 메세지 작성
{
/usr/bin/echo " ================= "
/usr/bin/echo "                  백업 확인           "
/usr/bin/echo " ================= "
/usr/bin/echo
/usr/bin/echo " 웹서버 백업파일"
/usr/bin/ls -1 ${WEB} | /usr/bin/grep " ${TODAY}"
/usr/bin/echo
/usr/bin/echo "DB서버 백업파일"
/usr/bin/ls -1 ${DB} | /usr/bin/grep " ${TODAY}"
/usr/bin/echo
/usr/bin/echo "Storage 서버 백업파일"
/usr/bin/ls -1 ${STR} | /usr/bin/grep " ${TODAY}"
/usr/bin/echo

##백업 별 파일숫자 확인
chk_cnt Web_System "${WBK_CNT}"
chk_cnt DB_System "${DBK_CNT1}"
chk_cnt DB_Dump "${DBK_CNT2}"
chk_cnt STORAGE_System "${SBK_CNT}"


}>|"${LOG}"


##텔레그램으로 레포트 메세지를 보냄
"${PUSH}" " ${HOST}"   " $(/usr/bin/cat " ${LOG}")"

crontab -e
30 10  * * * /root/SHELL/monitor/backup_monitor.sh >/dev/null 2>$1

시나리오
 - 스토리지 서버의 디스크가 풀로 찼다.

find
 - find (옵션) 찾기시작할패스 익스프레션
- find ./ -name tetsfile.txt   (이름으로 파일찾기)
- find ./ -mtime -10 ( 현재 시각으로부터 10일 이전에 수정이 이루어진 파일 찾기)
- find ./ -mtime +10 ( 현재 시각으로부터 10일 이후에 수정이 이루어진 파일 찾기)
 찾은 파일을 출력뿐만아니라 처리까지 할 수 있다.
 find ./ -mtime +3 -exec rm {} \ ; 
 - 역슬레시와 세미콜론으로 find 명령어를 끝냄
 - 명령어는 rm 말고도 여러가지 다 됨
 -  명령어 입력 후 -c 옵션을 주면 다른 명령어 사용 가능
 - find ./ -mtime +3 -exec sh -c "rm {}" \;  


예전에 만들었던 백업 정책에 내용 추가

vi web_backup.sh & db_backup.sh (cent1 cent2 서버) 

#!/bin/bash
set -exuo pipefail  <<--  cent1, 2 둘다 추가 , 완료 후 주석처리

##변수설정
HOST="$(/usr/bin/hostname)"  
LOG="/root/backup.log"
PUSH="/root/SHELL/monitor/tel_push.sh"
DATE="$(/bin/date +%Y.%m.%d)"

--- 중략 ---

##---로그 기록시작 ({중괄호}로 시작과 끝을 정의함)
{
##백업 시작 시간
/bin/echo
/bin/echo "=== 백업시작 시간"
/bin/date
/bin/echo

/bin/echo
/bin/echo "=== 이전 백업파일 삭제 : "
/usr/bin/find ${BAK_PATH} -mtime +7 -exec sh -c "ls -a {}; rm {}" \;
/bin/echo
--->> 추가

##백업
/usr/bin/tar czpPf "${BAK_FILE}" ${BAK_LIST} <-- ${BAK_LIST}에는 " "를 안붙인 이유 : 위에 변수선언할 때 이미  " "를 붙혀줬기때문에
p : 퍼미션유지  P : 절대경로유지

 

--- 생략 ---

시나리오
- 텔레그램으로 백업 레포팅이 도착하지 않은 것을 보고 서버에 접속해서 확인
- 디스크가 가득 차서 백업도 멈춰있고 서비스도 안되는 상황
- 다시 문제가 생긴 이유가 무엇일까?

기초지식
- 제한적인 쉘 스크립트 작성
 : 옵션을 통해 쉘이 동작하는 방식을 제어, 버그를 줄일 수 있음
- set -exuo pipefail
- -e : errexit, 첫번째 실행 실패(exit코드가 0이아닌 상태로 종료하는 명령어)시 쉘 스크립트를 종료
- -x : xtrace, 매 라인을 실행하기 전에 필요한 산술확장, 매개변수확장, 명령치환 변수대입 등을 화면에 출력
- -u : nounset, 정의가 안된 변수를 사용하면 에러 메세지를 출력하고 쉘 프로그램 강제 종료
- -o : 옵션을 on/off할 수 있다.
- set -o [옵션명] :옵션 on
- set +o [옵션명] : 옵션 off
- pipefail : 옵션명, 파이프로 ㅇ ㅕㄴ결된 명령이 전부 true일 때만 true를 봔환하도록 함


vi web_backup.sh & db_backup.sh (cent1, 2)

#!/bin/bash
set -exuo pipefail  <<--  cent1, 2 둘다 추가 , 완료 후 주석처리

##변수설정
HOST="$(/usr/bin/hostname)"  
LOG="/root/backup.log"
PUSH="/root/SHELL/monitor/tel_push.sh"
DATE="$(/bin/date +%Y.%m.%d)"

##백업할 디렉토리 /파일을 지정
BAK_LIST="/etc/nginx /usr/share/nginx/html/www"

##백업 디렉토리
BAK_PATH="/mnt/BACKUP/${HOST}"

##백업파일명
BAK_FILE="${BAK_PATH} / ${DATE}_ ${HOST}.tgz"

##스토리지에 마운트
/usr/bin/mount /mnt

##로그파일 생성
/usr/bin/touch "${LOG}"

--- 생략 ---

##텔레그램으로 백업 로그를 전송
"${PUSH}" " ${HOST}" " $(/usr/bin/cat " ${LOG}")"

##로그파일 삭제
/usrr/bin/rm -f "{LOG}" "{DB_BAK_PATH}"  <<-- db_backup.sh cent2 만 추가


트러블 재발 방지를 위한 처리
 - 데이터베이스(cent2), 스토리지(cent3) 서버에도 디스크 감시 스트립트 실행

 


vi  mnt_mon.sh

#!/bin/bash

하는 일 : /mnt 디렉토리의 용량을 감시
#1. /mnt 디렉토리의 크기를 확인
#2. 크기가 1기가 이상일 경우 관리자에게 알림
#3. 1기가 미만일 경우 아무것도 안함

DIR="/mnt"
SIZE="$(du -m ${DIR} | awk '{print $1}')"
HOST="$(hostname)"

if [ ${SIZE} -ge 1024 ]
then
  TEXT="${DIR} 사용량이 1기가가 넘었습니다. "
  /root/SHELL/monitor/tel_push.sh "${HOST}" " $ {TEXT}"
fi

저장후 scp 명령어를 이용하여 cent2로 복사
scp mnt_mon.sh cent2:/root/SHELL/monitor/

crontab에 등록하여 적용
디스크 감시 스크립트는 하루에 한번 백업이 끝난 이후 작동하도록함
1시간에 한번 하게 디스크감시 스크립트를 되면 안되는 이유는 백업 도중에는  스토리지를 마운트하고 있기 때문이다.

crontab -e
00 05 * * * /root/SHELL/BACKUP/monitor/mnt_mon.sh >/dev/null 2>$1

기존 스크립트(cent1) 카피해서사용

스토리지 서버 (cent3)에 백업 스크립트 만들기

cent1서버에서 ssh 명령어로 cnet3서버에 디렉토리 만들기
ssh cent3 "mkdir /root/SHELL"  
cent1에서 cent3으로 디렉토리 복사하기
scp -rp /root/SHELL/BACKUP cent3:root/SHELL/BACKUP
scp -rp /root/SHELL/monitor cent3:root/SHELL/monitor

-r : 하위 디렉토리까지 복사
-p : 퍼미션 복사

cent3으로 접속해서 vi web_backup.sh 를 storage_backup.sh 로 이름 바꾼 후 수정

vi storage_backup.sh

#!/bin/bash

##변수설정
HOST="$(/usr/bin/hostname)"  
LOG="/root/backup.log"
PUSH="/root/SHELL/monitor/tel_push.sh"
DATE="$(/bin/date +%Y.%m.%d)"

##백업할 디렉토리 /파일을 지정
BAK_LIST="/etc/exports /etc/nfs.conf /etc/nfsmount.conf"  <<-- 이 부분 수정

##백업 디렉토리
BAK_PATH="/mnt/BACKUP/${HOST}"

##백업파일명
BAK_FILE="${BAK_PATH} / ${DATE}_ ${HOST}.tgz"

나머지 내용은 동일하므로 생략

DB서버(cent2)에 백업 스크립트 만들기
ssh cent2 "mkdir -p /root/SHELL/BACKUP /root/SHELL/monitor"

scp -rp /root/SHELL/BACKUP/web_backup.sh cent2:root/SHELL/BACKUP/db_backup.sh
scp -rp /root/SHELL/monitor/tel_push.sh cent2:root/SHELL/monitor

cent2 접속

vi db_backup.sh

#!/bin/bash

##변수설정
HOST="$(/usr/bin/hostname)"  
LOG="/root/backup.log"
PUSH="/root/SHELL/monitor/tel_push.sh"
DATE="$(/bin/date +%Y.%m.%d)"

##백업할 디렉토리 /파일을 지정
BAK_LIST="/etc/my.cnf.d"  -> 수정

##백업 디렉토리
BAK_PATH="/mnt/BACKUP/${HOST}"

##백업파일명
BAK_FILE="${BAK_PATH} / ${DATE}_ ${HOST}.tgz"

##디비 백업디렉토리
DB_BAK_PATH="/root/SHELL/BACKUP/xtrabackup_backupfiles"
##디비백업파일명
DB_BAK_FILE="${BAK_PATH}/ ${DATE}_ ${HOST}_ DB.tgz"
-> 추가

##스토리지에 마운트
/usr/bin/mount /mnt

##로그파일 생성
/usr/bin/touch "${LOG}"

##백업 디렉토리 확인
if [ -e "${BAK_PATH}" ]
then
  ##백업 디렉토리가 존재한다면
/usr/bin/echo " 백업 디렉토리가 있어요. 문제 없음"
else
  ##백업 디렉토리가 없으면 생성
/usr/bin/mkdir -p "${BAK_PATH}"
fi
mkdir -p : 부모디렉토리와 함께 생성

##---로그 기록시작 ({중괄호}로 시작과 끝을 정의함)
{
##백업 시작 시간
/bin/echo
/bin/echo "=== 백업시작 시간"
/bin/date
/bin/echo

##백업
##DB dump
/usr/bin/mariabackup \
--backup \
--no-lock \
--target-dir="${DB_BAK_PATH}"
-->> 추가

##DB apply logs
/usr/bin/mariabackup \
--prepare \
--target-dir="${DB_BAK_PATH}"
-->> 추가

##p : 퍼미션유지  P : 절대경로유지
/usr/bin/tar czpPf "${BAK_FILE}" ${BAK_LIST} 
->>${BAK_LIIST}에는 ""를 안붙인 이유 : 위에 변수선언할 때 이미  ""를 붙혀줬기때문에
##db백업디렉토리 압축
**/usr/bin/tar czpPf "${DB_BAK_FILE}" ${DB_BAK_PATH}
-->> 추가


##백업파일 정보
NAME="${/usr/bin/ls -al  " ${BAK_FILE}" | awk '{print $9}'  }"
SIZE="${/usr/bin/ls -al  " ${BAK_FILE}" | awk '{print $5}'  }"
/bin/echo "=== 백업 파일 정보 : "
/bin/echo " | 파일명 : ${NAME}"
/bin/echo " | 파일크기 : ${SIZE}Byte"
/bin/echo

##DB 백업파일 정보
NAME="${/usr/bin/ls -al  " ${DB_BAK_FILE}" | awk '{print $9}'  }"
SIZE="${/usr/bin/ls -al  " ${BAK_FILE}" | awk '{print $5}'  }"
/bin/echo "=== DB 백업 파일 정보 : "
/bin/echo " | 파일명 : ${NAME}"
/bin/echo " | 파일크기 : ${SIZE}Byte"
/bin/echo

##백업 종료 시간
/bin/echo
/bin/echo "=== 백업종료 시간"
/bin/date
/bin/echo

} >|"${LOG}"
##---로그기록 끝

##스토리지에 언마운트
/usr/bin/umount /mnt

##텔레그램으로 백업 로그를 전송
"${PUSH}" " ${HOST}" " $(/usr/bin/cat " ${LOG}")"

##로그파일 삭제
/usrr/bin/rm -f "{LOG}"

crontab -e
00 04 * * * /root/SHELL/BACKUP/web_backup.sh >/dev/null 2>$1




vi 편집기에서 :! 를 쓰면 명령을 실행할 수 있음

웹서버(cent1)에 백업 쉘 스크립트 만들기
vi web_backup.sh

#!/bin/bash

##변수설정
HOST="$(/usr/bin/hostname)"  
-->때쉘스크립트는 ssh로 접속해서 실행을 할 적용되어있는 환경변수와 크론텝에서 읽어들이는 환경변수가 다르다.  패스라는 환경변수에 기본으로 등록되어있는 /bin/ 이나 /usr/bin이 있는데 크론텝에서 못읽어오는 경우가 있다. 그래서 풀패스를 작성해야한다.
LOG="/root/backup.log"
PUSH="/root/SHELL/monitor/tel_push.sh"
DATE="$(/bin/date +%Y.%m.%d)"

##백업할 디렉토리 /파일을 지정
BAK_LIST="/etc/nginx /usr/share/nginx/html/www"

##백업 디렉토리
BAK_PATH="/mnt/BACKUP/${HOST}"

##백업파일명
BAK_FILE="${BAK_PATH} / ${DATE}_ ${HOST}.tgz"

##스토리지에 마운트
/usr/bin/mount /mnt

##로그파일 생성
/usr/bin/touch "${LOG}"

##백업 디렉토리 확인
if [ -e "${BAK_PATH}" ]
then
  ##백업 디렉토리가 존재한다면
/usr/bin/echo " 백업 디렉토리가 있어요. 문제 없음"
else
  ##백업 디렉토리가 없으면 생성
/usr/bin/mkdir -p "${BAK_PATH}"
fi
mkdir -p : 부모디렉토리와 함께 생성

##---로그 기록시작 ({중괄호}로 시작과 끝을 정의함)
{
##백업 시작 시간
/bin/echo
/bin/echo "=== 백업시작 시간"
/bin/date
/bin/echo

##백업
/usr/bin/tar czpPf "${BAK_FILE}" ${BAK_LIST} <-- ${BAK_LIST}에는 ""를 안붙인 이유 : 위에 변수선언할 때 이미  ""를 붙혀줬기때문에
p : 퍼미션유지  P : 절대경로유지

##백업파일 정보
NAME="${/usr/bin/ls -al  " ${BAK_FILE}" | awk '{print $9}'  }"
SIZE="${/usr/bin/ls -al  " ${BAK_FILE}" | awk '{pprint $5}'  }"
/bin/echo "=== 백업 파일 정보 : "
/bin/echo " | 파일명 : ${NAME}"
/bin/echo " | 파일크기 : ${SIZE}Byte"
/bin/echo

##백업 종료 시간
/bin/echo
/bin/echo "=== 백업종료 시간"
/bin/date
/bin/echo

} >|"${LOG}"
##---로그기록 끝

##스토리지에 언마운트
/usr/bin/umount /mnt

##텔레그램으로 백업 로그를 전송
"${PUSH}" " ${HOST}" " $(/usr/bin/cat " ${LOG}")"

##로그파일 삭제
/usrr/bin/rm -f "{LOG}"

crontab -e
00 04 * * * /root/SHELL/BACKUP/web_backup.sh >/dev/null 2>$1



백업이란
- 서버는 언젠가는 장애를 일으키며 멈춘다
- 언제 일어날 지 모르는 장애에 대히하여 중요한 데이터를 다른 곳에 보관
- 장애 복구시 데이터 복원을 위해 사용
tar
tar -cvzf 압축할파일명 압축할디렉토리/파일
tar xvzf 압축파일명
-c :압축하기
-x : 압축풀기
-z : gzip으로 압축
-v : 상세내용 출력
-f :파일을 지정해주는 옵션

mariabackup - 온라인 백업
mariabackup \
--backup \
--no-lock\
--target-dir=백업파일을 저장할 디렉토리 경로

이 아래는 생략이 가능
--host=백업할호스트아이디 \
--port=3306 \
--user=유저명 \
--password='비밀번호' \

백업하는 동안에 업데이트 되는 트랜젝션들은
ib_logfile0 에 쌓이게됨

ib_logfile0 <--

mariabackup \
--prepare \
--target-dir=위에서 지정한 백업 디렉토리 경로

**복구**

mariabackup \
--move-back \ <-- --copy-back
--user=유저명 \
--password='패스워드' \
--target-dir=백업한 디렉토리 경로 \
--data-dir=복구할 디렉토리 경로

디스크 파티션 사용량 감시 스트립트
- 스크립트가 해야할 일 
- 파티션별 사용량을 확인해서 80%가 넘어가면 관리자에게 알림을 보냄
- 처리과정의 정리 및 명령어
- 파티션별 사용량 확인 (df)
- 크기를 비교해서 처리(if)
- 관리자에게 알림
- mail/slack/telegram
- 스크립트 작성
- 테스트

#!/bin/bash

##파티션별 사용량을 확인해서 80%가 넘어가면 관리자에게 알림을 보냄
##1. 파티션별 사용량을 확인
##2. 크기를 비교해서 처리
##3. use가 80%이상이면 관리자에게 메세지
##4. 80% 미만이면 아무것도 안함

##TEXT 변수에 보낼 메세지를 작성
TEXT="$(df -h | \
   awk '{
      gsub("%", " ")
     USE=$5;
     MNT=$6;
     if ( USE > 80 )
     print MNT, "파티션이 ",USE, "%를 사용 중입니다."
      }' |\
   grep -v "^[A-Z]")"
HOST="$(hostname)"

##80% 이상 디스크를 사용하는 파티션이 있을 경우
##TEXT변수의 내용(메세지)를 관리자에게 보냄
if [ ${#TEXT} -gt 1 ]  <<-- ${#TEXT}는 TEXT라는 변수의 사이즈를 계산
then
/root/SHELL/monitor/tel_push.sh "${HOST}" "${TEXT}"

crontab 작성
- crontab -e 
crontab 확인
- crontab -l 
crontab 삭제
- crontab -r


##로그 디렉토리 감시 스크립트
1시간에 한번
00 * * * * /root/SHELL/monitor/log_mon.sh > /dev/null 2>&1
-->> 표준에러를 표준 출력을 하나로 모아서 리다이렉트로 deb/null로 보냄

##디스크 파티션 감시 스크립트
30분마다 한번
30 * * * * /root/SHELL/monitor/part_mon.sh > /dev/null 2>&1
-->> 표준에러를 표준 출력을 하나로 모아서 리다이렉트로 deb/null로 보냄

같은 문제가 발생하지 않도록 감시 스트립트를 만들기

기초지식
- 쉘스크립트 작서의 흐름
- 실행 후 얻을 결과를 구체적으로 결정
- 결과를 얻기 위해 필요한 과정을 나열
- 각 과정별 명령어들 나열
- 명령어를 순서대로 파일에 써주고 실행
- 명령어
- df -h
- du -sk :킬로바이트 단위로 표시
-sh : 킬로바이트 메가바이트 등 사람이 읽기 쉽게 표시
- crontab
-e : 스케쥴 수정
-r : 스케쥴 완전 삭제
분 시간 일 월 요일 실행할프로그램
00    *     *    *    *     shellscript.sh       -> 정각마다 서버가 꺼질때까지 계속 실행
- awk 응용
첫번째 세로줄만 출력 (구분자는 디폴트로 공백)
awk '{print $1}' txt13
첫번째 세로줄만 출력 (구분자가 :으로 되어있음)
awk -F: '{print$1}' colon_txt13
구분자 텝으로 변경(column -t)
df -h | awk '{print $1, $2, $3, $4, $5, $6}' | column -t

%를 $로 변경
df -h | awk '{gsub("바꿀문자","바뀔문자"); print $5}'
df -h | awk '{gsub("%","$"); print $5}'

작업흐름
발생한 문제를 정리
- 대량의 접속자로 로그 용량이 폭주
- 그 결과 디스크 풀


각 문제 별 처리 스크립트
로그 디렉토리 용량 감시 스크립트
- 스크립트가 해야 할 일
- 로그 디렉토리의 크기를 확인하고 지정한 용량보다 크면 관리자에게 알림을 보냄
- 처리 과정의 정리 및 명령어
- 로그 디렉토리의 크기를 확인 (du)
- 크기를 비교해서 처리 (if)
- 관리자에게 알림
- mail / slack / telegram
(실습으로 telegram 사용)
- 스크립트 작성
- 테스트

vi log_mon.sh

#!/bin/bash

#1. 로그 디렉토리의 크기를 확인
#2. 크기가 1기가 이상일 경우 관리자에게 알림
#3. 1기가 미만일 경우 아무것도 안함
SIZE=$(du -m /var/log/nginx | awk '{print $1}') <-- m을 사용하여 메가바이트로 디렉토리 크기 통일
echo ${SIZE}

if [ ${SIZE} -ge 1024 ]
then
echo "여기의 관리자에게 알리는 코드가 들어갑니다."
else
echo "여기에서는 아무것도 안해요."

텔레그램 메세지 봇 만들기


토큰값은 내가 만든 봇에 접근 가능하기 때문에 공개되어서는 안돼서 가림



vi log_mon.sh

#!/bin/bash
DIR="/var/log/nginx"
SIZE="$(du -m ${DIR} | awk '{print $1}')"
HOST="$(hostname)"

if [ ${SIZE} -ge 1024 ]
then
  TEXT="${DIR} 사용량이 1기가가 넘었습니다. "
  /root/SHELL/monitor/tel_push.sh "${HOST}" " ${TEXT}"
fi

vi tel_push.sh

#!/bin/bash

##telegram bot으로 메세지르르 보내는 쉘 스크립트
##2개의 파라미터가 필요함
##파라미터가 두개가 안될 경우 사용방법을 출력하고 스크립트를 종료
##1. 서버 호스트 이름
##2. 메세지
##실행 결과는 현재 날짜/시각, 서버이름, 지정한 메세지를 텔레그램으로 보냄

##파라미터확인
if [ $# -ne 2 ]
then
  echo 
  echo "$0 {HOSTNAME} {MESSAGES}"
  echo
  echo "example)"
  echo "$0  \"cent1 \"  \"/var/log/nginx 파티션을 확인하세요 \""
 echo
 exit 0
fi

##텔레그램 봇 관련정보
ID="nnnn"
API_TOKEN="nnnnnnnnn:xxxxxxxxxxxxxx"
URL="https://apitelegram/org/bot${API_TOKEN}/sendMessage"

##날짜
DATE="$(date "+%Y-%m-%d %H:%M")"

##보낼 메세지 작성
TEXT="${DATE}" [$1]  $2

##메세지 보내기
curl -s -d "chat_id=$ {ID}&text=${TEXT}" ${URL} > /dev/null 

 

참고사항
$(소괄호)는 괄호안의 명령어를 실행한다는 의미
${중괄호}는 변수명으로 인식

트러블 슈팅
 : 발생한 문제를 해결하는 것
웹서 
UI  uj버에서 자주 일어나는 장애 유형
 - 디스크풀
 - 로그를 기록하는 프로세스가 에러 또는 멈춘다.
 - 임시 파일을 생성해야 하는 명령어의 실행이 안되다.
 - 리눅스는 루트 유저만을 위한 예약 블록을 남겨두어 트러블슈팅이 가능하도록 설계
- 메모리 풀
- 메모리를 다쓰고 스왑 영역까지 사용하여 시스템이 느려져 유저에게 응답이 느려짐
- 시스템 부하
- 로드 에버리지가 cpu코어 개수보다 높은 경우 유저 요청에 대한 응답이 늦어짐
- 프로그램의 문제
- 프로그램 오동작


현재 위치를 확인
/ 로 이동
이동한 것을 확인
각 디렉토리별로 용량을 계산
그 중에서 큰 용량을 차지하는 디렉토리를 찾기

모니터링
로그 파일 크기 감시
watch -n 3 'ls -al /var/log/nginx | grep VWS.access.log'

+ Recent posts