ラベル cron の投稿を表示しています。 すべての投稿を表示
ラベル cron の投稿を表示しています。 すべての投稿を表示

2024年6月25日火曜日

Python で指定の cron が一日何回実行されるかカウントするスクリプト

Python で指定の cron が一日何回実行されるかカウントするスクリプト

概要

前回指定の日時にcronが実行されるかどうかチェックするスクリプトを作成しました
今回は更にそれを応用して指定の cron が一日に何回実行されるのかカウントしてみました

環境

  • macOS 11.7.10
  • Python 3.11.7
  • croniter 2.0.5

インストール

  • pipenv install croniter

サンプルスクリプト

from datetime import datetime, timedelta

from croniter import croniter


def count_run_today(cron_expression, target_date: str):
    # 指定の日付の開始、指定の日付の明日の開始時刻を取得
    target_datetime = datetime.strptime(target_date, "%Y/%m/%d")
    today_start = datetime(
        target_datetime.year, target_datetime.month, target_datetime.day
    ) - timedelta(seconds=1)
    tomorrow_start = today_start + timedelta(days=1) + timedelta(seconds=1)
    # cron オブジェクトの作成
    cron = croniter(cron_expression, today_start)
    # 当日内に実行される日時の分だけカウントする
    run_count = 0
    while True:
        # 次に実行される日時を取得
        next_run = cron.get_next(datetime)
        if today_start < next_run < tomorrow_start:
            run_count += 1
        else:
            break
    return run_count


# テスト正常系
print("正常系テスト")
print(count_run_today("0 12 * * *", "2024/06/24"))  # => 1
print(count_run_today("0 12 24 6 *", "2024/06/24"))  # => 1
print(count_run_today("*/1 * * * *", "2024/06/24"))  # => 1440
print(count_run_today("*/5 * * * *", "2024/06/24"))  # => 288
print(count_run_today("*/30 * * * *", "2024/06/24"))  # => 48
print(count_run_today("*/30 1 * * *", "2024/06/24"))  # => 2

最後に

当日分の cron が正しく全件実行されるか確認したいときに使えるスクリプトです

2024年6月24日月曜日

Python で指定の cron が当日実行されるかチェックするスクリプト

Python で指定の cron が当日実行されるかチェックするスクリプト

概要

例えば */5 * * * * は本日実行される cron で 30 12 22 6 * は本日実行されない cron というのを判定することができるスクリプトを紹介します

環境

  • macOS 11.7.10
  • Python 3.11.7
  • croniter 2.0.5

インストール

  • pipenv install croniter

サンプルスクリプト

from datetime import datetime, timedelta

from croniter import croniter


def will_run_today(cron_expression):
    # 今日の日付と今日の開始、明日の開始時刻を取得
    now = datetime.now()
    today_start = datetime(now.year, now.month, now.day) - timedelta(seconds=1)
    tomorrow_start = today_start + timedelta(days=1) + timedelta(seconds=1)
    # cron オブジェクトの作成
    cron = croniter(cron_expression, today_start)
    # 次に実行される日時を取得
    next_run = cron.get_next(datetime)
    # 次に実行される日時が今日中であればTrueを返す
    return today_start < next_run < tomorrow_start


# テスト正常系(2024/06/21(木)に実行した想定)
print("正常系テスト")
print(will_run_today("0 12 * * *"))
print(will_run_today("*/5 * * * *"))
print(will_run_today("*/1 * * * *"))
print(will_run_today("*/30 * * * *"))
print(will_run_today("*/30 5 * * *"))
print(will_run_today("*/30 5 * 6 *"))
print(will_run_today("*/30 5 * 6 *"))
print(will_run_today("59 23 21 6 *"))
print(will_run_today("59 23 * * 5"))
print(will_run_today("59 23 21 6 5"))
print(will_run_today("1 0 21 6 5"))
print(will_run_today("0 0 * * *"))
print(will_run_today("0 0 21 6 5"))
print(will_run_today("*/30 * * * 1-5"))

# テスト異常系
print("異常系テスト")
print(will_run_today("0 12 3 2 *"))
print(will_run_today("0 12 22 6 *"))
print(will_run_today("*/5 * 22 6 *"))
print(will_run_today("*/1 * * * 4"))
print(will_run_today("*/1 * * * 0,1,2,3,4,6"))
print(will_run_today("30 12 22 * *"))

おまけ: 指定の日付に実行されたかどうかチェックするように修正する

from datetime import datetime, timedelta

from croniter import croniter


def will_run_today(cron_expression, target_date: str):
    # 指定の日付の開始、指定の日付の明日の開始時刻を取得
    target_datetime = datetime.strptime(target_date, "%Y/%m/%d")
    today_start = datetime(
        target_datetime.year, target_datetime.month, target_datetime.day
    ) - timedelta(seconds=1)
    tomorrow_start = today_start + timedelta(days=1) + timedelta(seconds=1)
    # cron オブジェクトの作成
    cron = croniter(cron_expression, today_start)
    # 次に実行される日時を取得
    next_run = cron.get_next(datetime)
    # 次に実行される日時が指定日時内であればTrueを返す
    return today_start < next_run < tomorrow_start


# テスト正常系(2024/06/21(木)に実行した想定)
print("正常系テスト")
print(will_run_today("0 12 * * *", "2024/06/21"))
print(will_run_today("0 12 3 2 *", "2024/02/03"))
print(will_run_today("*/1 * * * *", "2024/01/01"))
print(will_run_today("0 0 * * *", "2024/01/01"))

# テスト異常系
print("異常系テスト")
print(will_run_today("0 12 22 6 *", "2024/06/21"))

最後に

cron が大量にありその中で本日実行されるのが何個あるのかチェックしたりするのに使えます

2024年6月6日木曜日

cron 情報を可視化する cronv を試してみる

cron 情報を可視化する cronv を試してみる

概要

cronv は crontab の情報から html ファイルを生成してくれるツールです

環境

  • Ubuntu 22.04
  • golang 1.22.3
  • cronv 0.4.5

インストール

  • go install -v github.com/takumakanari/cronv/cronv@0.4.5

使ってみる

  • crontab -l | cronv -o ./my_cron_schedule.html

間隔を指定する

基本は6時間分しか出力しないので24時間を指定します
-d オプションを使います

  • crontab -l | cronv -o ./my_cron_schedule.html -d 24h

開始時間を指定する

--from-date オプションを使います

  • crontab -l | cronv -o ./my_cron_schedule.html -d 24h --from-date 2024/06/05

文字列から生成する

パイプで文字列を渡せば良いだけなので crontab -l でなくても OK です

  • echo "*/5 8 * * 0,1,2,3,4 ls" | cronv -o ./my_cron_schedule.html -d 24h --from-date 2024/06/05

タイトルを指定する

生成される html の先頭のタイトルを変更します

  • echo "*/5 8 * * 0,1,2,3,4 ls" | cronv -o ./my_cron_schedule.html -d 24h --from-date 2024/06/05 --title test

動作確認

バーの数が実行される数になります
横軸は1時間になるので1時間で何回実行されるのか確認できます

最後に

cronv で crontab 情報を可視化してみました
html を生成してくるだけなので動的に変更したい場合は何かしらの仕掛けが必要になりそうです

-d を使えば表示する間隔は変更できますが例えば毎月2日に実行するようなルールでもプロットはしてしまうので毎日実行するような cron 情報しかプロットできません

参考サイト

2022年4月19日火曜日

cron + mysqldump で定期バックアップする方法

cron + mysqldump で定期バックアップする方法

概要

mysqldump を cron に仕込む際のテクニックを紹介します

環境

  • Ubuntu 18.04

cron

30 5 * * * cd /home/user; /usr/bin/mysqldump -h 192.168.100.1 -u db_user --all-databases --skip-add-drop-table > /home/user/dump/`date +"\%Y\%m\%d"`_dump.sql

.my.cnf

  • vim /home/user/.my.cnf
[mysqldump]
user=db_user
password=xxxxxx

解説

ダンプ時のオプションは --all-databases と --skip-add-drop-table にしています
前者は全データベースのダンプで後者は発行されるダンプファイルに drop table 文を含めないようにするオプションです

ダンプファイルは毎日取得することを想定しているので日時情報をファイル名に含めています
その際に date コマンドを使用していますが date コマンドのフォーマット記法「% (パーセント)」は cron ないではエスケープしなければならないので注意しましょう

mysqldump を取得する際には必ずと言っていいほどパスワードが必要になります
コマンドに直接埋め込んでもいいのですが警告が出るのでファイルに記載します
その際に mysqldump コマンドを実行しているパスに「.my.cnf」という隠しファイルを置いておくと自動でそれを読み込んでくれます
ここに認証情報が記載できるので mysql のユーザ名とパスワードを記載しましょう