質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

4回答

2117閲覧

cronのように実行されたプログラムのログをメールで出力したい。

yuki_90453

総合スコア326

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/06/05 23:09

編集2017/11/05 08:21

いつもお世話になっております。
Rubyにてメール受信時に動くプログラムを作成しています。
crontabで動くプログラムと違い、実行結果や出力をメールで受け取れないのでエラーが発生した際に対応が遅くなってしまい大変、困っております。

現状、下記のようにloggerとmailのライブラリを使用し、ログを記録しメールで送信といった風に行っております。

require 'logger' def initialize $log = Logger.new("log/logger.log",10) $log.datetime_format = "%Y-%m-%d %H:%M:%S" $log.level = Logger::INFO $errors = [] end def logger(type="info", text) puts text $log.info (text) if type == "info" $log.warn (text) if type == "warn" if type == "error" $log.error (text) $errors << text end end def send_log_mail(type ="log") Mail.defaults do delivery_method :smtp, { :address => "smtp.gmail.com", :port => 587, :domain => 'gmail.com', :user_name => 'test@gmail.com', :password => 'password', :authentication => 'plain', :enable_starttls_auto => true } end if type == "log" && $logs.empty? == false m = Mail.new do from "test@gmail.com" to "info@example.com" subject "ログ" body $logs end m.charset = "UTF-8" m.content_transfer_encoding = "8bit" m.deliver elsif type == "error" && $errors.empty? == false m = Mail.new do from "test@gmail.com" to "info@example.com" subject "エラー" body $errors end m.charset = "UTF-8" m.content_transfer_encoding = "8bit" m.deliver end end send_log_mail("error") send_log_mail

しかし、上記の方法ではプログラムがエラーで動かなかった場合のエラーなど、ログ出力出来ません。
crontabであれば、エラーやputsなどすべてのログがメールで送信されるので、そのような形にしたいと考えております。

###質問
crontabのように標準でそのような機能はないのでしょうか?
どのようにすれば、プログラムで発生した標準出力を読み込めるのでしょうか?

よろしくお願い致します。

###追記

#!/bin/bash TEMP=/tmp/syncStock_temp$$ trap "rm -f $TEMP" 0 cd /var/www/html/Ruby/Application/ /usr/local/rbenv/shims/bundle exec /usr/local/rbenv/versions/2.3.1/bin/ruby mailTrigger.rb > $TEMP 2>&1 CC=$? if test $CC != 0 -o -s $TEMP then mail -s "ERROR CC=$CC" mail < $TEMP fi exit 0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

.forwardとかaliasesとかによるメール起動のプログラムで、エラーを差出人じゃなくて受取人ないし固定の別ユーザーが知りたいという事ですよね。

まずこけないと思われるシェルスクリプトを一枚かぶせるくらいですかね。

あるいは、Postfixに手を入れるか・・・・そっちの方が危ないか。

Bash

1#!/bin/sh 2TEMP=/tmp/hogehoge$$ 3trap "rm -f $TEMP" 0 4/path/to/ruby /path/to/script > $TEMP 2>&1 5CC=$? 6if test $CC != 0 -o -s $TEMP 7then mail -s "ERROR CC=$CC" me@example.com < $TEMP 8fi 9exit 0

#追記
シェルスクリプト不案内のようなので、解説しておきます。

  1. 一時ファイル名を決める($$はプロセスID)
  2. スクリプト終了時に一時ファイルを削除する
  3. プログラム起動。出力は一時ファイルにリダイレクト
  4. プログラムの終了コードを取得
  5. 終了コードがゼロでないか、または、一時ファイルが空でない時に
  6. 終了コードと一時ファイル内容をメールする
  7. 終わりは終了コードゼロで

投稿2017/06/06 01:16

編集2017/06/06 03:43
otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuki_90453

2017/06/06 02:16

回答頂きありがとうございます。 >.forwardとかaliasesとかによるメール起動のプログラムで、エラーを差出人じゃなくて受取人ないし固定の別ユーザーが知りたいという事ですよね。 はい、今回の場合、受取人がコマンドの実行結果を知りたいという状況です。 >まずこけないと思われるシェルスクリプトを一枚かぶせるくらいですかね。 shellスクリプトですか。。。調べながらやってみたいと思います。 メール受信時、本来は下記のようにスクリプトを指定しているのですが、 "| cd /var/www/html/Ruby/Application && /usr/local/rbenv/shims/bundle exec /usr/local/rbenv/versions/2.3.1/bin/ruby mailTrigger.rb" それを下記のように、最後にメールコマンドを入れれば上手く行きそうな気がします。 "| cd /var/www/html/Ruby/Application && /usr/local/rbenv/shims/bundle exec /usr/local/rbenv/versions/2.3.1/bin/ruby mailTrigger.rb 2>&1 | mail to@gmail.com" しかし、上記では空のメールが届いてしまいます。 もし上記の方法で修正するとしたら、どこを変更すればよいか教えて頂けないでしょうか?
otn

2017/06/06 03:38

シェルスクリプトにしてください。一時ファイルを作るので、ワンラインでは難しいかと。 test -s $TEMP のところで、出力を書き込んだファイルのサイズがゼロでないか調べてゼロでない時だけメールしています。
yuki_90453

2017/06/06 11:30 編集

詳しい回答、そして追記ありがとうございます。 サーバーのshellはfishを使っているですが、やはりfish用に書き換える必要がありますよね? 下記のようにbashを指定し、要所を書き換えて実行してみましたが、下記のような結果が帰ってきます。 ---------------------------------------------- #!/bin/bash TEMP=/tmp/syncStock_temp$$ trap "rm -f $TEMP" 0 cd /var/www/html/Ruby/Application/ /usr/local/rbenv/shims/bundle exec /usr/local/rbenv/versions/2.3.1/bin/ruby mailTrigger.rb > $TEMP 2>&1 CC=$? if test $CC != 0 -o -s $TEMP then mail -s "ERROR CC=$CC" hepp0k0.jani.win@gmail.com < $TEMP fi exit 0 ---------------------------------------------- <$TEMP@example.com> (expanded from <info@example.com>): unknown user: "$temp" <&1@example.com> (expanded from <info@example.com>): unknown user: "&1" <0@example.com> (expanded from <info@example.com>): unknown user: "0" 私の環境のようにbash以外のシェルを使用している環境で実行するシェルスクリプトは、対象のシェルスクリプトに書き換えるべきか、それともbashを指定の仕方が間違っているのでしょうか?
otn

2017/06/06 12:51

動かし方が間違っていると思いますが、どうやって動かそうとしていますか? Rubyスクリプトが起動できているのなら、それと入れ替えるだけですが。
yuki_90453

2017/06/06 12:59 編集

動かし方ですか。 /etc/aliasesを下記のようにし info:¦info,¦:include:/home/mail_trigger このmail_triggerというのがシェルスクリプトになります。 rubyのスクリプトまで辿り着けていないように思えます。 テストメールを送信すると、「<$TEMP@example.com> (expanded from <info@example.com>): unknown user: "$temp"」のプログラムがシェルの内容を間違って解釈し実行してるように見えます。
otn

2017/06/06 12:59

それでRubyスクリプトが起動できていましたか?
yuki_90453

2017/06/06 13:00

あ、すみません。もしかしたら間違った解釈をしてるかもしれません。 確認します。
yuki_90453

2017/06/06 13:18

今確認した所、私の勘違いがあり修正した所、無事問題なくログが送信されるようになりました。 /etc/aliasesに「info:¦info,¦:include:/home/mail_trigger」 このmail_triggerにシェルスクリプトを指定し、シェルスクリプトからRubyを実行という流れで上手く行きました。 シェルスクリプトを挟むとはこういう意味だったんですね。 ただ、メール文が文字化け?しており下記のようになります。 「"\u30C6\u30B9\u30C8"」 調べた所、これはUTF-16BEという形式のようです。これを読める形にするには、Rubyで文字コードを変えてしまうか、それともシェルスクリプトに修正を入れるべきか、どうすればよいでしょうか?
otn

2017/06/06 13:25

Rubyスクリプトがバグっているように思えます。
yuki_90453

2017/06/06 13:41

Ruby側では、「# -*- encoding: utf-8 -*-」という風にUTF-8を指定しています。 シェルスクリプト側で文字コードの変換を行おうと考え下記のように修正しましまたが、変化はありませんでした。 iconv -f UTF16 -t EUCJP $TEMP > $TEMP.test mail -s "ERROR CC=$CC" hepp0k0.jani.win@gmail.com < $TEMP.test
otn

2017/06/06 13:46

プログラムがバグっているので、文字コードをどうのこうのしても駄目です。文字化けじゃ無いです。バグです。 あるいは、そういう内容のメールが来てそのまま出力しているか。
yuki_90453

2017/06/06 13:55

そうですか。 ここから、今回の質問とは趣旨が変わってしまいそうなんで、別でまた質問させて頂きます。 ありがとうございます。
guest

0

私は昔からlogcheckと言うツールを愛用しています。

機能としてはシンプルで、
1時間毎にsyslogを監視し、
パターンにマッチしないログをメールで通知してくれます。

読む必要のないログは、
除外パターンを登録する事で届かなくなります。

監視対象のログも、任意に追加できますので、
ローテーションしてるようなものや、
日付毎にファイル名が変わるものでなければOKだと思います。
私はapacheのエラーログも監視しています。

1時間に1通なので、緊急対応には向きませんが、
落ちた時の警告には、monitと言うツールを利用しています。

いずれも昔からある枯れたツールなので、
もっと色々あるのかもしれませんが、
これらのツールで特に困らないので、
愛用しています。

エラーメッセージはシステム毎に異なるため、
最初はどうしても読む必要のないメッセージが多く届きます。
なので、それらを除外パターン登録するのは少々面倒ですが、
このやり方は、自分が想定しないエラーを確実に通知してくれるので、
慣れると手放せません。

投稿2017/06/06 06:24

chun

総合スコア324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

crontabのように標準でそのような機能はないのでしょうか?

cron(crontab)の環境変数設定 メール送信先(MAILTO) PATH

ログインした時にメールがある、というようなメッセージが出る場合は、mailやmuttなどのメールクライアントで読む事が出来ます。

投稿2017/06/06 02:50

yoorwm

総合スコア1305

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

やりたいこととしてはrubyのプログラムでエラーがあった時に、エラーをメールで検知したいということでしょうか?
もしそうだとしたらsentryの導入を検討してみてください。
https://sentry.io/welcome/

投稿2017/06/05 23:46

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問