読者です 読者をやめる 読者になる 読者になる

Go で cronolog ライクにファイル作成・ログ出力するパッケージ

github.com

を書いてみた。似たものはあったけど、ピンポイントで欲しいものではなかったし、せっかくなので Go の勉強も兼ねて作った。

仕様

引数で受け取ったフォーマット文字列を、現在時刻に置き換えてファイルパスにする。
ファイルパスに含まれるディレクトリもなければ作成して、ファイルに文字列を出力する。

フォーマットは下記例のとおり。

入力フォーマット 出力パス
/path/to/example.log.%Y%m%d /path/to/example.log.20170205
/path/to/%Y/%m/%d/example.log /path/to/2017/02/05/example.log

だいたい cronolog にならっていて、時間をベースにファイル分割していく。

使い方

せっかくなので使い方も書いておく。
基本は、Logger と組み合わせて使う。
例えば、uber-go/zap と組み合わせるときは、👇🏼 のとおり Writer オブジェクトをつくって io.Writer の受け口に渡してあげるだけ。

package main

import (
    "github.com/uber-go/zap"
    "github.com/utahta/go-cronowriter" // 👈🏼
)

func main() {
    w1 := cronowriter.MustNew("/tmp/example.log.%Y%m%d") // 👈🏼
    w2 := cronowriter.MustNew("/tmp/internal_error.log.%Y%m%d") // 👈🏼
    l := zap.New(
        zap.NewJSONEncoder(),
        zap.Output(zap.AddSync(w1)),
        zap.ErrorOutput(zap.AddSync(w2)),
    )
    l.Info("test")
}

// Output:
// /tmp/example.log.20170204
// {"level":"info","ts":1486198722.1201255,"msg":"test"}

他の Logger と組み合わせるときも、同じように io.Writer に渡す。
interface 便利!

オプション

いろいろオプションも用意していて、たいていのものは揃えた。

WithLocation

タイムゾーンの設定。デフォルトはシステムロケール。

w := cronowriter.MustNew("/path/to/example.log.%Z", cronowriter.WithLocation(time.UTC))
// /path/to/example.log.UTC

WithSymlink

シンボリックリンクの設定。現在書き込み対象のファイルに対してシンボリックを貼る。

w := cronowriter.MustNew(
    "/path/to/example.log.%Y%m%d", 
    cronowriter.WithSymlink("/path/to/example.log")
)
// /path/to/example.log -> /path/to/example.log.20170218

WithMutex

排他制御する設定。大抵の Logger は write 前で mutex.Lock していることから writer はデフォルトで排他制御しなくした。

w := cronowriter.MustNew("/path/to/example.log.%Y%m%d", cronowriter.WithMutex())

WithDebug

デバッグ機能。ファイル書き込みと同時に標準出力する。

w := cronowriter.MustNew("/path/to/example.log.%Y%m%d", cronowriter.WithDebug())

WithInit

writer を New したときにファイルを作成する。デフォルトは Write が呼ばれたタイミングでファイルを作成している。
書き込み権限があるかどうか事前に知りたいとき使うと便利。

w := cronowriter.MustNew("/path/to/example.log.%Y%m%d", cronowriter.WithInit())

ももいろクローバーZ ももクロくらぶxoxo ~バレンタイン DE NIGHT だぁ~Z 2017 裏・表

に行ってきた。とても楽しかった。
忘れても思い出せるようにメモ。

二日間あるイベントの1日目は、例年のバレンタインイベントとは一味ちがう、ライブがメインではない裏と銘打たれたイベント。テーマは、ぐだぐだ is ファースト(トランプパロ…)

ももクロのメンバーが二人一組でドラマを即興して、その後ラジオ番組の体で内容を振り返る形式。組み合わせは、百田玉井、有安高城、あーりん。

一組目は百田・玉井ペア。
旅行中ホテルに到着した設定で演技が始まった直後、

百田「うわーすごい景色!たまさ〜ん、みてー」
玉井「えーなに?なにー?」
百田「何がみえる?
玉井「!!!??」

即興ならではだけど、始まってすぐコレは完全に意表をつかれて笑うより感心したし、きっと狙ってたんだろうけど、なんでも器用にこなす瞬発力抜群玉井さんの翻弄された姿がとても面白くて最高だった。

どちらが PPAP をうまくこなせるか勝負するいつものような展開になり、歌番組やももクロChanで何度もモノマネを披露している玉井さんが、自信満々で(やや噛みつつも)こなした後の百田さん。
同じことしても面白くないし、どうするんだろうな〜と思っていたら、

百田「アッポーペン〜パイナッポーペ〜ン。っぽい!ま〜きのっ

完全に予想していなかったし、もはや PPAP じゃないし、常識を打ち破る力が凄まじいし、照れも臆する様子もなくこなすし本当に凄い。見習えない。

二組目は有安・高城の推され隊コンビ。
ホテルで就寝する二人だけど、高城さんが寝つけず有安さんに助けを請う設定。

どうしたら眠れるか話しているだけなのに引き込まれたし、前の二人のようにそんな発想が?というインパクトはないけど、淡々と面白くて延々と聞いていたかった。伏線回収も良くてぐだぐだになると思いきや全然そんなことなくて最高だった。

最後はあーりん。
ホテルに到着したけどやることなくて暇という設定。

登場するやいなや「やっと着いたよーもう一時間待ったよー」と文句を言い、場内のモノノフを電話をかける体でイジりだし、黄色の女の子に電話をかけたと思いきや「あー電波わるいやーバイバイー」とバッサリ切り捨てたり、勝手気ままな感じが似合うし面白いしなにより嫌な空気にならないのでつよい。

その後も五人揃ってバイきんぐも加わって犯人探しコントをしつつ百田さんがバイきんぐの「ももいろクローバーAさんですよね?」のボケに対して「ももいろクローバーKだよっ!」と謎のツッコみ天然ボケをかまして会場騒然としたり色々あった。

ちょくちょくライブを挟みつつ、椅子に座ってのんびりコントドラマを鑑賞するゆるやかさは良いし、相変わらず百田さんは非凡だし、ぐだぐだ is ファーストというテーマだけどお客さんを飽きさせない意味では全くぐだぐだではないエンターテイメント素晴らしかった。

前日の裏とはうってかわり、ライブを軸にラジオドラマやお決まりのチョコレート争奪勝負を行う、例年どおりのイベント。

喉の調子がやや怪しげだったり一部曲の歌詞がおぼろげだったりした気もするけどパフォーマンス圧巻楽しい。
横浜アリーナを縦横無尽にかけめぐるし、アリーナという名のスタンド脇の通路をいったりきたりしていたし、通路席のひとたちセンター席にいる人よりよほど近くで見れたのでは。
イマジネーション・デモンストレーションでみた久しぶり百田さんのソロダンスはやっぱり良くて、ついでに目の前でガッツリ歌い上げるさまも目にすることが出来て多幸感凄くて良い思い出。
ラストの今宵ライブの下でではいつもの決め台詞を改変した「ハッピーバレンタイン」で天に召され最高だった。

今後も定期的にライブへ行けるように頑張っていくぞ。

echo で使われてる logger のベンチマークをとってみた

uber-go/zap との比較が目的なので、zap のベンチマークテストと同じようなコードを書いてとってみた。

元々あったテスト(BenchmarkLog-4)と大して変わらない結果。

uber-go/zap

uber-go/zap のベンチマークを同じマシンで実行した結果。

$ go test -bench .
...
BenchmarkNoContext-4                             5000000               283 ns/op
BenchmarkBoolField-4                             5000000               344 ns/op
BenchmarkFloat64Field-4                          3000000               403 ns/op
BenchmarkIntField-4                              5000000               359 ns/op
BenchmarkInt64Field-4                            5000000               361 ns/op
BenchmarkStringField-4                           5000000               346 ns/op
BenchmarkStringerField-4                         5000000               368 ns/op
BenchmarkTimeField-4                             5000000               363 ns/op
BenchmarkDurationField-4                         5000000               371 ns/op
BenchmarkErrorField-4                            5000000               361 ns/op
...

なんだか圧倒的に早い。