らっちゃいブログ

日々の学びと気づきを発信するブログ

tailコマンドで対象ファイルがローテートされても自動で追随する方法

地味に便利だったのでメモしておきます。

ログファイルをリアルタイムで確認するときに利用する tail -f コマンドですが、ファイルサイズでローテートされるようなログだとすぐに止まってしまい、改めてコマンドを実行し直す必要があり、ストレスが溜まりますよね。

tail のオプションにはぜひ -F を与えてあげてください。たったそれだけで、リネームされたりローテートされても自動的に追随してくれるようになります。

本当でしょうか?tail の man を見てみましょう。

-F   The -F option implies the -f option, but tail will also check to see if the file being followed has been renamed or rotated.  The file is closed and reopened
     when tail detects that the filename being read from has a new inode number.  The -F option is ignored if reading from standard input rather than a file.

つまり、リネームやローテートが起きたら新しいinode番号を検知してオープンし直してくれるようです。

では試してみます。まずは -f オプションの挙動から見てみましょう。

以下のように tail.txt を作成し、tail -f しておきます。

$ echo "a" > tail.txt
$ tail -f tail.txt
a

この状態で tail.txt を tail2.txt にリネームし、tail.txt へ"b"を出力します。つまりローテートを発生させます。

$ mv tail.txt tail2.txt && echo "b" >> tail.txt

結果はこちら。

$ tail -f tail.txt
a

変化なしです。-f ではローテートに追随してくれませんでした。

それでは-Fの動きを確認してみましょう。

$ echo "a" > tail.txt
$ tail -F tail.txt
a

準備ができたところで、ローテートしてみます。

$ mv tail.txt tail2.txt && echo "b" >> tail.txt

結果はどうなっているかというと

$ tail -F tail.txt 
a
b

すばらしい。しっかりローテートに追随してくれていますね。

いまのところ -F オプションを使うことによる弊害はなさそうなので、今後は -f ではなく -F を使っていこうと思います。

curlに名前解決を操作できるオプションがあって超絶便利だった話

小ネタですが、初めて知って感動したので共有させてください。

例えば

  • ローカルサーバに本番のドメインでHTTPアクセスしたい
  • DNS を変更する前に変更後のドメインでHTTPアクセスしたい

のようなケースですが、通常 hosts ファイルを編集して解決することが多いと思います。

今回はなんと、curl を使って確認する場合に限り、いちいち hosts を編集しなくても名前解決を操作することができるオプションを見つけてしまいました。こちらです。

--resolve <host:port:address>

すごい解決してくれそうなオプション名ですね!

使い方はほとんど見たままなのですが、名前解決したいドメイン&ポートと、解決結果として使用するIPを指定するだけです。

例えば www.google.com へのアクセスをローカルアドレスに向ける場合は、以下のように実行します。

$ curl -v --resolve www.google.com:80:127.0.0.1 http://www.google.com/
* Added www.google.com:80:127.0.0.1 to DNS cache
* Hostname was found in DNS cache
*   Trying 127.0.0.1...
* Connected to www.google.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: www.google.com
> Accept: */*
> 
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Thu, 02 Jun 2016 08:37:29 GMT
< Content-Type: text/html
< Content-Length: 612
< Last-Modified: Tue, 04 Mar 2014 11:46:45 GMT
< Connection: keep-alive
< ETag: "5315bd25-264"
< Accept-Ranges: bytes
< 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host www.google.com left intact

無事ローカルに立てている Nginx のウェルカム画面を取得することができました。

実際の名前解決ですが、こちらを見るとちゃんと127.0.0.1として解決してくれていることがわかります。

* Added www.google.com:80:127.0.0.1 to DNS cache
* Hostname was found in DNS cache
*   Trying 127.0.0.1...

もちろん、Host ヘッダーは www.google.com が指定されます。

> Host: www.google.com

これでDNS変更前のAPI試験が捗るぜ!

魚の旨い店で三食丼を食べてきた

毎週恒例となりました食べてきたシリーズです。

今回のお店はこちら。魚の旨い店です。

いやいや、魚が旨いかはどうでもいいから店名を書けよって思われそうですが、これが店名なんです。なんとも紛らわしい。

それでは入店します。まずはレジで先に注文とお支払いを済ませる形式でした。レジ前のメニューを見ながら悩む。

焼き魚の定食いいなあ。さばの塩焼き大好きなんですよね。あれ、肉系の定食もあるのか。魚の旨い店なのに。そう、ここは魚の旨い店なんだから、新鮮な刺身が食べれるに違いない。

ということで三色丼に決定。

追加料金を払えばご飯の量を増やすこともできたのですが、具が増えないとバランスが悪くなりそうなので今回は普通盛りにしました。

ちなみに、いま思えばまぐろまぐろまぐろ丼にしておけばよかったと若干後悔してます。名物らしいので。今回、文字が小さくて名物だと気付けなかったので、もしお店の関係者が見てくれてたらぜひ大きくしてほしいです。

注文が終わって席で冷たいお茶を飲んでいると、ほんの数分で三色丼が到着しました。

見た目はなかなかですね。玉子、大葉、わさびあたりでご飯が見えないように隠してる感は否めませんが、美味しそうです。

三色の内訳は

  • ネギトロ
  • カンパチ
  • サーモン

でした。

それではいただきます。

なるほど、お刺身はどれも新鮮で美味しいですね。ネギトロも安っぽくない、ちゃんとしたネギトロでした。さすが魚の旨い店。

心配していたご飯の量も、結果的にはちょうどよかったです。丼ぶりが深くて、ぎりぎりまでご飯が盛られていたので結構な量でした。大盛りにしてたら食べきれなかったかも。

値段もそんなに高くないですし、味も満足だったので、ぜひまた来たいですね。

ちなみにこちらのお店、夜は日本酒の飲み放題コースがあるみたいです。4500円でコース料理付きということで、この内容にしてはお安く設定されています。銘柄を見る限りだとなかなかのラインナップですし、夜に来るのも悪くないお店ですね。

というところで、今回のレポートはこれで終了です。また来週!

DjangoでDBのフィールドに選択肢を設定する

概要

やりたいこととしては、特定のフィールドに指定できる値をEnum化するようなイメージです。

選択肢リストを設定する

フィールドに choices を指定することで選択肢を設定することができます。

choices の中身ですが『2要素のタプルからなる iterable(リストまたはタプル)』と定義されています。

つまりはこんな感じ。

GENDER_CHOICES = (
    (1, 'Male'),
    (2, 'Female'),
)
class Person(models.Model):
    gender = models.IntegerField(choices=GENDER_CHOICES)

見てわかる通り、一つ目の要素がDBに格納する値で二つ目が表示名です。

選択肢を利用するメリット/デメリット

メリットとしては、そのフィールドに格納され得るデータがプログラム上で定義できるため、追加変更が楽です。

また、以下のようにして設定値に対応する表示名を得ることができます。個人的にはこれがやりたくて使ってるところもあります。

person = Person(gender=1)
person.get_gender_display()
'Male'

デメリットですが、定義した選択肢の値が格納されることを強制できません。つまり設定した選択肢以外の値も保存され得ます。ですので、自分で入力チェックなりビジネスロジックを書いて意図しない値が入らないことを保証する必要があります。

MySQLENUM型でいいじゃん

という方もいそうなので、この話題にも言及しておきましょう。

ENUMを実際に使うとこんな感じでしょうか。

CREATE TABLE person (
  gender ENUM('Male', 'Female')
);

MySQLENUM型を使っても良いのですが、選択肢を増減するためにテーブル定義を変更する必要が出てくるため、運用を考えると使いたくないのです。また、DBに格納される値と同じEnum定数をプログラム上にも定義するケースが多く、定数の二重管理になりやすい点も無視できませんね。

ちなみにENUM型はSQLアンチパターン本でも扱われていますので、世間的にもよろしくないものと認知されていると思います。

SQLアンチパターン

SQLアンチパターン

SQLアンチパターンによると、ENUM型を使ってよいとされているのは、ON/OFFのように変更されることのない相互排他的な値を扱う場合だけとのことです。

今回例として挙げた性別はこれに該当するでしょうか?

いいえ、該当しません。依頼人の要望で『内緒』を保存したいということもあり得ます。もはや、ENUMは封印してしまうべきでしょう。

定数を管理するテーブルを作ればいいじゃん

ENUM を使わない場合は、以下のように参照テーブルを作る方法が一般的ですね。Django 以外を使うときは私もそうします。

CREATE TABLE gender (
  id VARCHAR(20),
  name VARCHAR(20)
);
INSERT INTO gender (key, name) VALUES (1, '男性'), (2, '女性');
 
CREATE TABLE person (
  gender_id INT(11),
  FOREIGN KEY (gender_id) REFERENCES gender(id) ON UPDATE CASCADE
);

確かにこれならやりたいことは実現できます。しかし、いつも思うのですが、表示名を取得するの面倒じゃないですか?わざわざ gender テーブルをジョインして name フィールドを引っ張ってくる必要がありますよね。それを避けるためには、結局プログラム上にIDと表示名を管理する Enum を定義することになり、定数の二重管理に逆戻りです。

結局、どうやってもプログラム上に Enum を定義することになるのですから、それだけで全部管理できるようにするのがベストだとは思いませんか?

本記事にて『入力チェックなりビジネスロジックを書いて意図しない値が入らないことを保証する必要がある』というデメリットをお伝えしましたが、そんなに難しいことではありませんよね。選択肢にない値を保存しようとしたらエラーにするだけで良いのですから、一か所に簡単なロジックを書くだけで済みます。

結論

ENUM型を使うのはやめてフィールドに選択肢を設定しよう!

子供が産まれて激変した日常を語ってみる

6:00

まず朝が早い。6時には子供に叩き起こされる。ここ10年は8時近くに起きる生活を続けていたため、非常につらい。とはいえ、寝起きの子供はご機嫌でマジ天使なので10分ほどいちゃつく。

6:10

朝起きたらまずやること。それは子供の体温を測ることだ。熱があったら保育園に預けられないし、病院に連れていかなければならない。

6:20

体温を測ったら子供にごはんを食べさせる。朝食は私より早起きしている妻が作ってくれている。朝食を食べさせるのには平均して30分はかかる。地味に大変な作業だ。最近は自分が食べる時間がないので、食べさせながらコップ一杯の野菜ジュースを飲んで済ませることが多い。ご飯をゆっくり食べれない、またはそもそも食べる時間がないというのは育児あるあるだろう。

6:50

朝食が終わったら、オムツ替えと着替えだ。大抵ご飯を食べながら力んでいるので、保育園に行く前に必ず替えておく必要がある。個人差はあると思うが、暴れるのでそうやすやすとは替えさせてくれない。少しでもおとなしくしてくれるよう、おもちゃで気を引くが気持ちの強さで起き上がってくる。頻繁にまだ拭いていない生のお尻が床についてしまうのが悩みだ。

7:00

朝食の後片付けと洗い物をする。特に子供の食器類は帰宅してすぐ使うものなので、このタイミングで洗っておかないと後が大変になる。

7:20

ここから自分の準備をするわけだが、保育園の都合もあり7:30には出発する必要がある。以前は朝シャワーを浴びるのが日課だったが、もうそんなものは夢のまた夢だ。ささっと着替えて髪を整える程度で準備を終える。トイレに行く暇はなくはないが、しゃがんでいるほどは時間はない。朝にお腹を下すことの多い私にとって、これは地獄だ。

妻はこのあたりで家を出るのでここからは完全に一人での対応となる。

7:35

満身創痍で準備を終えるも、家を出るのは結局7:35になってしまうことが多い。出発が遅れた分は保育園までの移動で取り戻すしかない。息つく暇もないのだ。保育園に着く頃には、満身創痍を通り越して燃えカスになっている。


これが我が家の朝の日常だ。雨が降った日はもっと深刻な事態となることは想像できるだろうか。考えたくもないのでここで詳しく書くことはやめておこうと思う。

次は夜の話に移る。

保育園のお迎えは妻の仕事だ。17時にお迎えにいき、帰宅後子供に夕食を食べさせ、その後遊んでほしいと泣き叫び暴れる子供とケンカしながら自分たちの夕食を用意してくれている。正直、どうやって作っているのか自分には理解できない。密室殺人なみのトリックがないと不可能だと思う。

19:00

帰宅すると、そうやって苦労して作った夕食が待っている。が、その前に手洗いうがいをして着替えを済ます。

19:15

ようやく夕食にありつける。しかし、ここでもゆっくりは食べていられない。ささっと食べないと、次は子供のお風呂が待っているのだ。

なぜそこまで急ぐのかわからない方のために言っておくと、ここでゆっくりしてしまうとどんどん寝る時間が遅くなっていくのだ。次の日も6時起床が約束されているので早く寝ないとやってられない。

19:45

お風呂は前日の夜に洗ってあり、夕食開始とともに湯沸かしボタンを押す運用になっている。そうすることで、食べ終わったら即入浴可能状態となる。

お風呂は入れる係と外でサポートする係に分けられる。それぞれでノウハウがあるため、役割はどちらかに固定されるのが一般的だと思う。私はお風呂に入れる担当だ。二人でこなす分にはそこまで大変ではないが、これを一人でやろうとすると一気に難易度が上がる。一人で子供二人をお風呂に入れているという話を聞くと、神を見たような気持ちになるのは私だけだろうか。

お風呂から上がったら全身にベビーワセリンを塗り、着替えさせ、水分を取らせる。そして必要に応じて爪を切る。この辺りは妻の仕事だ。

20:15

ここから、いろいろと仕上がった子供を預かり、寝かしつけ始める。絵本を読んだりオルゴールを流したりして、なんだかんだで入眠するのは21時近い時間になる。

20:50

ようやく自由時間だ。

とはならない。ここから保育園で出た洗濯物を洗い始める。お風呂のお湯を使うのでどうしてもスタートがこの時間になってしまう。

洗濯機を待つ間、洗い物をする。これをやっておかないと次の日の子供の朝ごはんに支障が出るのだ。洗い物が終わったら、洗濯が終わるまでしばしの休憩が許される。

21:20

休憩もそこそこに、洗濯物をほす。この作業はテレビを見ながらできるので娯楽に近い。洗濯物をほし終わり、前日の乾いた洗濯物をたたんだところで、一日のタスクが完了となる。

21:40

ここからが自由時間だ。ブログを書いたりメールやFacebookメッセージ等に着信している仕事の連絡に返事をするのはこの時間を利用している。結局仕事をしているので自由時間という自覚はほぼない。

23:00

いろいろ片付いたところで就寝となる。

??:??

ここで終わらないのが育児の大変なところで、このあと数時間おきに子供が泣くのでその対応をする。この時間が最も辛い。

こうして何度か起こされつつ、まとまった睡眠時間を取れないまま朝を迎える。この睡眠不足感を想像しながら、本記事のスタートに戻ってみてほしい。ようやく深い眠りについたタイミングで天使が顔の上を歩いてくるのだ。寝起きのつらさがわかっていただけると思う。

ひとこと

育児は大変だと聞いてはいたが、実際自分がやってみると大変どころの話ではない。本当に過酷だ。

そういえば母は毎日日付が変わるまで家事していた。フルタイムで仕事した上で育児と家事をすべて一人でやっていたのだから、そうなるか。実際の苦労を知り、母への感謝と、父の怠惰さに怒りがわいてきた。

なんて書いていたらもうこんな時間か。明日も早いのでもう寝るとしますおやすみなさい。

NginxにDoS攻撃が可能となる脆弱性!

朝起きたら脆弱性情報がメーリングリストにてアナウンスされていました。JSTだと本日(2016/6/1)の公開となります。

[nginx-announce] nginx security advisory (CVE-2016-4450)

A problem was identified in nginx code responsible for saving client request body to a temporary file. A specially crafted request might result in worker process crash due to a NULL pointer dereference while writing client request body to a temporary file (CVE-2016-4450).

これによると、リクエストボディを一時ファイルへ保存する際の処理に問題があり、ワーカープロセスがクラッシュしてしまうケースがあるそうです。具体的な攻撃方法については記載されていません。

この脆弱性の影響を受けるバージョンは、1.3.9 - 1.11.0 で、修正版として 1.11.1 と 1.10.1 がすでにリリース済みです。

一応変更内容も記載しておきます。

http://nginx.org/en/CHANGES

Changes with nginx 1.11.1                                        31 May 2016

*) Security: a segmentation fault might occur in a worker process while
   writing a specially crafted request body to a temporary file
   (CVE-2016-4450); the bug had appeared in 1.3.9.

1.11.1/1.10.1 にアップデートできない方は、バージョン毎にパッチが提供されていますので、自身で適用しましょう。

Patch for nginx 1.9.13 - 1.11.0 can be found here:

http://nginx.org/download/patch.2016.write.txt

Patch for older nginx versions (1.3.9 - 1.9.12):

http://nginx.org/download/patch.2016.write2.txt

普通口座で驚愕の金利0.12%!噂のイオン銀行で口座を作ってきた

昨今話題のマイナス金利のおかげで、メガバンクでも金利0.001%の時代ですね。定期預金で1000万以上預けたところで0.010%。困ったものです。

そんな中、イオン銀行は驚愕の 0.12% の金利を誇ります。しかも普通預金で。

10万円預けたら120円

100万円預けた1,200円

1000万円預けたら 12,000円

1億円預けたらなんと 120,000円にもなります。

すごいぞイオン銀行

ただ、無条件でとはいきません。イオンカードセレクトに申し込む必要があります。まあクレジットカードを一つ増やすくらい、大した話ではないですよね。それだけで金利0.12%の口座を作れてしまうのなら安いものです。

ちなみに私はメインのクレジットカードを別で用意していますので、発行はしますが一切使うつもりはありません。なので、イオンカードセレクトを使う場合の特典やメリット等は何も調べてません。気になる方はこのあたりを見るといいんじゃないかと思います。(適当ですみません)

前置きが長くなりましたが、最寄りのイオンで口座開設手続きをしてきました。

持ち物は免許証など、身分を証明できるものがあればOK。印鑑は不要です。私は手ぶらでいきました。

手続きはタブレット機を使って必要事項を入力するだけでした。最近はペンと紙を使う機会がどんどん減っていきますね。

必要事項を入力したら、あとは軽く説明を受けて手続き終了です。大体15分程度で終わったと思います。一瞬でした。

当日はカードや口座情報は何ももらえず、後日郵送で届くそうです。待ち遠しいですね。

そういえば、手続き終了後に粗品をいただけました。何個入りだったかは忘れましたが、トイレットペーパーを2つほど。実用的なものをいただけるのは助かるんですが、徒歩だから重いし両手が使えなくなるんで別なのがよかったなあ。ひとまず当分トイレットペーパーは買わなくてよさそうです。