GAミント至上主義

Web Monomaniacal Developer.

DjangoのAdminsにメールが送られない時のチェックリスト

Djangoではsettings.pyのADMINSにメールアドレスを指定しておくと、エラー時に通知を送ってくれるので便利。

でもこれまでの開発でもよくなぜか届かない問題があり、最近Templyの開発でも起きたので備忘録。

temply.bizocean.jp


まず、メールサーバーの設定が済んでいて、django.core.mail.send_mailで送れることは前提として話を進める。

ADMINSの設定

名前、メールアドレスのタプルのリストを設定
https://docs.djangoproject.com/en/2.0/ref/settings/#admins

DEBUG=False

これは本番では間違えないと思うし当たり前だけど一応。

LOGGINGの設定

今回の原因1つ目
ログを受け取ってメールにしているので設定に追加が必要。

下記抜粋

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'include_html': True,
            'filters': ['require_debug_false'],
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': os.environ.get('DJANGO_LOG_LEVEL', 'INFO'),
            'propagate': True,
        },
    },
}

SERVER_EMAILの設定

今回の原因2つ目

似たようなメールの送信元としてDEFAULT_FROM_EMAILがあるが、ADMINSとMANAGERSはこれを使わない。
代わりにSERVER_EMAILを使っており、設定しないとroot@localhostが使われてしまう。

自前のメールサーバーであれば問題ないかもしれないが、今回メールのbackendに使っていたsendgridでは問題があるようで、スパムにも入らず消えてしまっていた。

https://docs.djangoproject.com/en/2.0/ref/settings/#server-email

SERVER_EMAIL = 'admins@sample.jp'

1日で理解するDjango超基礎入門

1日で理解するDjango超基礎入門

Django1.10 QUICKSTART-BOOK with Python3: 作りながら学ぶDjangoアプリケーション開発

Django1.10 QUICKSTART-BOOK with Python3: 作りながら学ぶDjangoアプリケーション開発

GCPのバグでGoogleのIssue Trackerに投稿して直してもらうまでの流れ

oceanusで使っているGCPのプロジェクトで、Cloud Functionsの関数の作成時、削除時にエラーが出て何もできない状況になった。

Googleで検索しても解決策は見つからず、他のプロジェクトでは問題なくできる操作なので、明らかにバグだと判断して、Stack Overflowなどの質問サイトではなく、公開バグトラッカーに投稿することにした。

コミュニティサポートの詳細はこれ。まずはこれで解決するかどうか読んで調べる。
Community Support Overview  |  Support  |  Google Cloud Platform

issue trackerについてはここ。読んで検索してそれでもだめだったら投稿する。
Report Bugs and Request Features with Issue Trackers  |  Support  |  Google Cloud Platform

当該のスレッドはこれ。Googleのアカウントが必要かもしれない。
https://issuetracker.google.com/issues/67027944

当時も検索したつもりだったけど、今改めて検索してみると、自分が投稿する3週間ほど前に同じような投稿が1件見つかった。
やりとりが多く、若干おこの模様。ここにコメントできればよかったかもしれない。
https://issuetracker.google.com/issues/65368380

原因としては、1年以上前に作ったプロジェクトで、Cloud Functionsのalpha時に使ってたのが原因だったらしい。裏で直してくれたようで無事消すことができた。

Marked as Fixed
Hi,
Your project turned out to be very old, used during alpha testing, so some setup was incorrect. Please try deleting the functions now.
I'm closing the issue now, but please reopen if it still fails.

英語を読むのには慣れたけど、質問などには慣れていないので、Google翻訳そのままか中学レベルの英語しか使えなかった。

こういったやりとりをよく読むようにして、かっこいい慣用句なんかを使っていきたい。


今回のバグは、特定のプロジェクトでcloud functionsが使えないという結構状況によってはまずいバグだったけど、9月末に投稿して直ったのが12月初旬なのでこういったバグでも2か月以上かかった。

今後投稿する人は、よく検索してから投稿し、気長に待った方がいいと思う。

BigQueryに入れたアクセスログを調べたい時によく使うスニペットまとめ

よく忘れてDatalabの中を捜索するはめになるので、まとめておく

レガシーSQL

TABLE_DATE_RANGE

昔ながらの日付別テーブルに格納しているとき

FROM TABLE_DATE_RANGE(
  [project_name:dataset_name.table_name_],
  TIMESTAMP("2017-11-27"), 
  TIMESTAMP("2017-11-28")
)

JSON

SELECT
  JSON_EXTRACT(jsn, "$$.text") as string,
  JSON_EXTRACT_SCALAR(jsn, "$$.text") as scalar,

URLからID(数字)を取り出す

SELECT
  INTEGER(REGEXP_EXTRACT(url, r'/doc/detail/([0-9]+)/')) as product_id,

日時の文字列を9時間プラス(日本時間)して、日付だけを返す

dtには「2017-11-26 14:41:27.407015」な感じの日付が文字列で入っている

SELECT
  DATE(DATE_ADD(TIMESTAMP(dt), 9, "HOUR"))