Perl Hackers Hub

第25回cron周りのベストプラクティス(2)

 

1

cron


crontab100

100使crontabcrontab

crontab


crontab


crontab

crontab

crontab

crontab


crontabRubywheneverDSLDomain Specific Language使便cronDSLcrontabcrontab

crontab


crontab 12
1 crontab
37 2 * * * /opt/perl-5.18/bin/perl /home/app/proj/script/daily_partitition.pl > /dev/null 2>&1
7 2 * * * /opt/perl-5.18/bin/perl /home/app/proj/script/event_partition.pl > /dev/null 2>&1

1






/dev/null

2 crontab
PATH=/usr/local/bin:/usr/bin:/bin
MYPROJ_RUN="/home/app/myproj/env-exec runcron"
LOGGER="/path/to/fluent-agent-lite"

### db partitioning
37 2 * * * $MYPROJ_RUN -- script/batch.pl DailyPartition 2>&1 | $LOGGER cron.daily_partition -
7 2 * * * $MYPROJ_RUN -- script/batch.pl EventPartition 2>&1 | $LOGGER cron.event_partition -

2crontab






env-execruncron

perlbatch.pl

fluent-agent-lite












/usr/local/bin$PATH便

crontabcrontab2$MYPROJ_RUN$LOGGER

env-execruncron


$MYPROJ_RUN$MYPROJ_RUNenv-execruncron

env-exec
env-execの内容
#!/bin/sh
set -e
export USER=app
export HOME=/home/$USER
cd $(dirname $0)
export PATH="local/bin:/opt/perl-5.18/bin:$PATH"
export PERL5LIB="lib:local/lib/perl5"
export PLACK_ENV=production
exec "$@"




app

cd

perl-buildPerl$PATH



exec


cronPerl

runcron3

perlbatch.pl


script/batch.pl
batch.plの内容
#!/usr/bin/env perl
use strict;
use warnings;
use Module::Load;
my $name = shift @ARGV;
my $module = "MyApp::Batch::$name";
load $module;
$module->new_with_options->run;

2DailyPartitionMyApp::Batch::DailyPartitionrunMouseX::Getopt使new_with_options

pl

fluent-agent-lite


cron /dev/null$MAILTOloggersyslogfluent-agent-lite使2$LOGGERfluent-agent-lite

fluent-agent-liteFluentdPerl

fluent-agent-lite{"message":"hello"}JSONJavaScript Object NotationFluentdtail使

loggerFluentd使Fluentd


crontabcrontabcrontab

crontab


croncrontabcrontab




acrontab

b

c

d

e

ftypo

g



Parse::Crontab使crontab


crontabParse::Crontab便
use strict;
use warnings;
use Test::More;
use File::Which qw/which/;
use Parse::Crontab;
# 11 2 * * * $MYPROJ_RUN script/batch.pl \
# DailyPartition 2>&1 | $LOGGER cron.daily_partition -
# 上記のように指定されているか確認する

my $crontab = Parse::Crontab->new(
  file => 'data/crontab.txt'
);
# a crontab のシンタックスに誤りがないか
ok $crontab->is_valid
    or diag $crontab->error_messages;

# b 危険な指定の確認
ok !$crontab->warning_messages
  or diag $crontab->warning_messages;

# ジョブ一覧を取得する
for my $job ($crontab->jobs) {
  my $command = $job->command;
  # c $LOGGER でログを出力しているか
  like $command, qr!2>&1\s+\|\s+\$LOGGER!, 'logger ok';

  # d $MYPROJ_RUN を使う規約を守っているか
  ok $command =~ m!^\$MYPROJ_RUN!;
  my ($opt, $rest_command) =
    $command =~
    m!^\$MYPROJ_RUN\s*(*?)?\s*--\s*(.*)!;
  my $cmd = +(split /\s+/, $rest_command)[0];

  # e 実行権がちゃんと付与されているか
  ok -e $cmd or $cmd = which($cmd);
  ok -x $cmd;
  if (my ($module) =
    $rest_command =~
      m!^script/batch\.pl\s+([A-Za-z0-9]+)!
  ) {
    # f batch.pl への指定モジュールが存在するか
    my $module_file = "lib/MyApp/Batch/$module.pm";
    ok -e $module_file;
  }
  # g スケジュールオブジェクトを取り出して
  # 必要に応じて実行時間のテストをする
  my $schedule = $job->schedule;
  ok $schedule->match(hour => 2, minutes => 15 ...);
}
done_testing;

acrontabbcdeftypog

crontab


crontabcrontab

crontabcronssh
% ssh myproj-batch01
# 差分確認
% diff -u <(crontab -l) data/crontab.txt
# 反映
% crontab data/crontab.txt

crontab

crontabTips


crontab

crontabcrontab

3
 

おすすめ記事

記事・ニュース一覧