ChatGPTでプロセスを監視するシェルスクリプトを作成

2023-02-27

最近、話題になっている「ChatGPT」を利用して簡単なシェルスクリプトを作成してみました。
「ChatGPT」は、OpenAIが開発した対話型AIチャットボットです。対話型で質問をすればAIが回答してくれます。

試しに下記の質問をしました。

【質問】
ChatGPTの説明をブログに載せます。できるだけ簡素に教えてください

【回答】
ChatGPTとは、自然言語処理タスクを行うための深層学習モデルの一つで、OpenAIが開発した大規模な言語モデルです。ChatGPTは、トレーニングに使用されたコーパスに基づいて、自然言語で書かれた文章を生成したり、文の意味を理解するための質問応答タスクに利用されたりします。

ChatGPTは、膨大な量のテキストを学習しているため、多様な文脈で自然な文を生成することができます。さらに、大量のデータを学習するため、非常に高い精度で言語タスクを実行することができます。ChatGPTは、文の生成や応答の自然さが求められる場面で活用されることが多く、現在は様々なアプリケーションで利用されています。

また、OpenAIはChatGPTの開発において、オープンソースでコードや学習済みモデルを公開しており、研究者や開発者が自由に利用できるようになっています。

次に、Apacheのログからアクセスの多いIPアドレスを抽出するコマンドを質問してみました
【質問】
Apacheのアクセスログから、アクセスの多いIPアドレスを抽出して欲しい。要件は下記
・ アクセスの多い10個抽出
・ アクセスの回数も表示

【回答】
以下は、Apacheのアクセスログからアクセスの多いIPアドレスを抽出し、アクセス回数とともに表示するシェルスクリプトの例です。この例では、アクセスログファイルが access.log という名前であることを前提としています。

awk '{print $1}’ access.log | sort | uniq -c | sort -nr | head -n 10
このシェルスクリプトは、以下の手順で動作します。

1. awk '{print $1}’ access.log は、アクセスログファイルからIPアドレスを抽出します。ここでは、IPアドレスはアクセスログファイルの1列目にあるものと仮定しています。
2. sort コマンドは、IPアドレスを昇順にソートします。
3. uniq -c コマンドは、重複したIPアドレスを削除し、各IPアドレスが出現した回数をカウントします。
4. sort -nr コマンドは、IPアドレスの出現回数を降順にソートします。
5. head -n 10 コマンドは、上位10件のIPアド

実際にApacheのログで、アクセスの多いIPアドレスを抽出するか確認してみました

$ awk '{print $1}' /etc/httpd/logs/access.log | sort | uniq -c | sort -nr | head -n 10
   22403 x.x.x.x
   11089 x.x.x.x
    9556 x.x.x.x
    8279 x.x.x.x
    7272 x.x.x.x
    5268 x.x.x.x
    5257 x.x.x.x
    4247 x.x.x.x
    3233 x.x.x.x
    2223 x.x.x.x

次にプロセス監視をするシェルスクリプトを作るように問い合わせしてみました

【質問】
下記の要件のシェルスクリプトを作って欲しい

  • httpdのプロセスを監視して落ちていれば自動で起動する。
  • 落ちていればメールで通知もして欲しい。
  • サーバーのOSは、CentOS 8です
#!/bin/bash

while true; do
    if ps aux | grep httpd | grep -v grep > /dev/null
    then
        sleep 60
    else
        /etc/init.d/httpd start
        echo "httpd process restarted at $(date)" | mail -s "httpd process restarted" your_email_address@example.com
    fi
done

上記のシェルスクリプトだと、プロセスが落ちた場合に起動しますが、while文の場所が無限ループとなっていてシェルスクリプトを実行すると終わりません。
追加でかきの条件を追加しました

【質問】

下記の要件のシェルスクリプトを作って欲しい

  • httpdのプロセスを監視して落ちていれば自動で起動する。
  • 落ちていればメールで通知もして欲しい。
  • 無限ループとしないで、起動失敗してもシェルスクリプトは抜ける
  • サーバーのOSは、CentOS 8です
#!/bin/bash

# 変数の設定
SERVICE_NAME="httpd"
RETRY_COUNT=3
TO_ADDRESS="your.email@example.com"
FROM_ADDRESS="httpd.monitor@example.com"
SUBJECT="[httpd monitor] Service failure"
BODY="httpd service is down. Please check the server."

# プロセス監視と自動起動処理
while true; do
    if systemctl is-active --quiet $SERVICE_NAME; then
        echo "Service is running."
    else
        echo "Service is not running. Trying to start..."
        systemctl start $SERVICE_NAME
        sleep 5
        if systemctl is-active --quiet $SERVICE_NAME; then
            echo "Service is started successfully."
            break
        else
            ((RETRY_COUNT--))
            echo "Failed to start the service. Retrying in 10 seconds... ($RETRY_COUNT retries left)"
            if [ $RETRY_COUNT -eq 0 ]; then
                echo "Failed to start the service. Sending email notification..."
                echo "$BODY" | mailx -s "$SUBJECT" -r "$FROM_ADDRESS" "$TO_ADDRESS"
                break
            fi
            sleep 10
        fi
    fi
done

また、while文の場所が無限ループとシェルスクリプトが終わらないです。要件の細かく指定しないと駄目っぽい。再度、質問の内容を変更して依頼してみました

【質問】

下記の要件のシェルスクリプトを作って欲しい

  • httpdのプロセスを監視する
  • プロセスが落ちていれば、3回ほど起動するように指示して、シェルスクリプトを終了
  • プロセスが落ちていればメール連絡する
  • プロセスが起動している場合はシェルスクリプトは終了
  • サーバーのOSは、CentOS 8
#!/bin/bash

# 監視するプロセス名
process_name="httpd"

# リトライ回数
retry_count=3

# メールの送信先
email_address="user@example.com"

# メールのタイトル
mail_subject="httpd process is down on $(hostname)"

# 監視ループ
while true; do
    # プロセスの存在確認
    if pgrep $process_name > /dev/null; then
        echo "The process is running."
        break
    else
        echo "The process is not running. Starting the process."
        # 起動のリトライ
        for i in $(seq $retry_count); do
            systemctl start $process_name
            sleep 5
            if pgrep $process_name > /dev/null; then
                echo "The process has been started."
                break 2
            fi
        done

        # リトライ後も起動できない場合は、メールで通知
        echo "Failed to start the process after $retry_count attempts." | mail -s "$mail_subject" $email_address
        break
    fi
done

上記の質問の仕方で、意図したシェルスクリプトができました。

ネットでChatGPTを調べてみると簡単なコードだと動く場合は多いが、複雑なコードになると動かいない事が多いみたいです。
ある程度、プログラムの知識があれば、どの箇所の原因かはわかるので解決できるので、ChatGPTでコードを生成する場合は時間と手間は省けそうです。
ただ、あまり知識がないと、動かない原因・思ったことと違う処理になるとかは分からないので、使いにくいかも知れません。

ChatGPTだと間違った回答する場合もあるし、動作確認したコードでの回答ではない可能性があるので、プログラムの記事を書いている技術系ブログに置き換わっていくのは、まだ先のほうな気がします