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

その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

YAPC::Asia Tokyo 2015にて"Yet Another Perl Cooking"というタイトルで発表します

発表する運びとなりました.
主に上に書いてあるような事を話しますから,興味のある方は是非いらして下さい!!!


ところで,個人スポンサーのチケットが1枚余った風味なので誰か欲しい人いたら「YAPC行きたい!!!」というキーワードを添えてご連絡下さい.参加券だけ差し上げます(ノベルティは欲しいので……).

fluent-logger-mock-sender 書いた

fluentd (td-agent) をプロジェクトで使う際に,開発途中で「fluentd に対して正しい内容のログを飛ばせてるのかどうか」みたいな事をテストしたくなる瞬間というのがあると思います.

td-agent のモックサーバ的なものを立てて,そこに実際に payload を投げつけて内容を確認するというのでも良いとは思うんですが,もっとお手軽な感じで「送信自体しないで,インターナルなデータ構造に対してログをスタックしておく」という風にすることでテストやデバッグを簡単に出来るのではないか,ということでそういう動きをするSenderを書きました.Maven Central にも上げています.

使い方は synopsis に書いてある通りです.MockSender 経由で put したログについては fluentd に対して送信されず,代わりに MockSender 自体がメンバーとして保持している List に対してログが積まれていくという動作をします.そして然る後,MockSender#getFluentLogs() でそのリストを取ってきたり MockSender#clearFluentLogs() で全消去出来たり,ということができます.

Perl 時代は実行時に動的にFluent::Loggerのメソッドを書き換えることでこのような処理を実現していたのですが,Java ではそうした行いが困難なので書いた次第.

ところで fluent-logger-java の新しいバージョンでは logger が利用している Sender が簡単に取れるようになって便利ですね! ありがとうございます.

YAPC::Asia Tokyo 2015にトークを応募した

トークを応募しました.

Perl,というかプログラミング全般のテクニックを用いた料理の自動化を試みる話について議論をします.

最近料理に興味があり,併せてソフトウェアエンジニアリングには依然として興味があったので,それをうまく組み合わせた形になりました.

そのタイトルからネタだと思われるかもしれませんが,至って真面目な話をします.応用的な内容としては crontab や CI と組み合わせて料理を自動化することについても検討及び議論します.残念ながら,会場の都合からその場で調理を実演して皆さんに振舞う事は不可能だと思われますから,写真や動画をふんだんに使うことで臨場感を出していきたいと考えています.

みなさんどんどん投票等お願いします.


ところでこのトークをするにあたってかなり金がかかる事が分かってきました.nomikuを購入する事はもちろん,その他のデバイスやら食材やらをガンガン購入していく必要が出てきています.昨日は鴨を購入しました.これはコンフィになります.コンフィについては色々と検討する必要があり,その性能評価の結果についてもYAPCのトークで披露する予定です.というか実際に何度も調理を行って実験をしていく必要があるわけですが,とてもではありませんが僕1人で食べきれる量ではありませんし,下手を打つと破算する恐れも出てきました.我々はどうすれば良いのでしょうか,協力してくれる人を募集しています.
以上です.

gimei-java 作った

世は空前の gimei ブームです.この前 go 版が出ましたね.
というわけで,というわけではなく,業務で必要だったので gimei-java を作ってしかるべきところ (つまりmaven central) にあげました.


Ruby には gimei という gem があり,

gimei は、日本人の名前や、日本の住所をランダムに返すライブラリです。テストの時などに使います。似たようなライブラリにfakerがあります。fakerはとても優れたライブラリで、多言語対応もしていますが、ふりがな(フリガナ)は流石に対応していません。gimei ふりがな(及びフリガナ)に対応しています。

というやつで,強いんですが,Java には存在しておりませんでした (もちろん Faker はある).

そんな折,大量にテストデータを作る必要が出てきて,僕は「テスト太郎」や「テスト花子」などという架空人物の名前を心をこめて考えてやっていたのですがそんな生活にももちろん限界が来てしまいます.


というわけでこの度 Java 版の gimei を作成・リリース致しました.
快くオリジナルの人名・住所のデータを使わせてくださった @ さんありがとうございます.


gem の gimei と同等な機能はほぼ揃えています.
使い方は README 等を読んでもらうとして,gimei-java にはオリジナルにはない tarohanako,加えて noun という機能が追加されています.
それぞれ何かと言うと「○○太郎」「○○花子」 (○○にはそれぞれランダムな名詞が入る),そしてランダムな名詞を出力するという機能になっています.

こんな感じ:

Taro taro = Gimei.generateTaro();

taro.kanji();    // => "ハム 太郎"
taro.hiragana(); // => "はむ たろう"
taro.katakana(); // => "ハム タロウ"

Hanako hanako = Gimei.generateHanako();

hanako.kanji();    // => "パソコン 花子"
hanako.hiragana(); // => "ぱそこん はなこ"
hanako.katakana(); // => "パソコン ハナコ"

Noun noun = Gimei.generateNoun();

noun.kanji();    // => "関東電化工業"
noun.hiragana(); // => "かんとうでんかこうぎょう"
noun.katakana(); // => "カントウデンカコウギョウ"

これらの機能は実は便利で,「○○太郎」や「○○花子」がテストデータに入っていると,それだけで役所感が出てくるのでカタい仕事をしているという気分に浸ることが可能です.あと男女の見分けが一瞬でできる.

名詞をランダムに出す機能は,個人的に架空の店舗名などを生成する必要があったため「<名詞> + 店」みたいな風に使えると便利かな〜と思って付け足しました.便利.

これらの機能で使っている名詞データのオリジナルはnaist-jdicで,そこから名詞・一般と名詞・固有名詞のみを抽出し,更にそこから1万件に絞り込んだというスタイルになっています.


もしも欲しい太郎や花子がございましたら,名詞のyamlにその名詞データを突っ込むだけなのでパッチを送って来てもらえればと思います.



以上です.ご利用下さい.

STDIN経由で入力を受け取って1秒あたりのスループットを取れるpersecというのを書いた

表題のやつです.便利っぽかったのと書きたかったという理由からgoで書いています.

例えばアクセスログのようなものがあった時,「1秒間に何行ログに書き込まれているか」が分かれば秒間のアクセス数を求めることが可能となります.これはそういうことをする為のツールとなります.
persecを一言で言うと,「1秒間に何行やってくるか」をカウントするコマンドです.

$ tail -F nankano.log | persec

という風に使ってやると,persecはteeの様にtail -Fの内容をそのまま出力しつつ,行数をカウントして一定周期ごとにそのスループットを出力します.末尾に雑に噛ませておくとスループットが取れる.

デフォルトだと,persecは60秒ごとのインターバルでスループットをSTDOUTに吐き出します.この場合は60秒間分の行数をカウントしておいて,それを60で割ったものを1秒間あたりのスループットとして扱います.
インターバルは--deltaスループットの出力先は--outというオプションでそれぞれ指定することが可能です.また,--noteeオプションを指定すると,受け取った内容をteeの様にフォワードしなくなります.

加えて--patternというオプションによって,カウントの対象とする行を絞り込むことが出来ます.ここにはgoで利用可能な正規表現を突っ込むことが出来ます.例えば,yyyy-mm-ddから始まる行だけをカウント対象にしたい場合は--pattern="^[0-9]{4}-[0-9]{2}-[0-9]{2}"というふうに指定してやるとそのような感じになります.

--helpで詳細が見れますから,そちらもご確認ください.


シェルスクリプトでも頑張ればこういうことが出来るような気もしたんですが僕にはその力が足りなかった!
というわけでどうぞ御利用ください.


余談ですがテストをどう書けば良いかわからなくて,結局シェルスクリプトによるE2Eテストになってしまった……

java-db-transaction-managerが出ていた

大昔の話ですが,java-db-transaction-managerというのを書いて,リリースしていました.

PerlのTransaction ManagerであるDBIx::TransactionManagerJava移植版です.シンプルなやつが欲しかったので.


機能としてはDBのtransactionに必要な機能であるbegin,commit,rollbackを提供しています.
入れ子になったtransaction内で既にrollbackされているのにも関わらずcommitが発行された時は例外が上がります.普通な感じですね.
try-with-resourcesを利用することも可能で,もし明示的にcommitもしくはrollbackが発行されないままそのスコープ外に出ると自動的にrollbackを発行するというような挙動になっています.

加えて,アクティブなtransactionのトレース (現在のtransactionのみ,あるいは全てのtransactionについて) を取るということも出来ます.便利!
ところでJavaでLLの様にカジュアルにスタックトレースの情報を取ろうとするとまあまあハイコストで困ってしまう,というかパフォーマンスに支障が出るわけですけれども,それを何とかすべくこのライブラリではJDKのprivateなAPIをリフレクションで呼び出すという力技で解決しています.そうすると速い.ここらへんは
tokuhirom/caller · GitHub
を参考にしました.


御利用ください.
あ,念のため言うとスレッドセーフではないです.

tinyormで任意のcolumn名を指定できるようになってた

MySQL の lower_case_table_names について,テーブル名とデータベース名の中の大文字小文字について - その手の平は尻もつかめるさ

こういう話があり,column名を小文字オンリーのsnake_caseでやりたかったりすることがあります.
今までのtinyormではRow Classのfield名がそのままcolumn名として扱われるため,Javaの一般的なコーディングスタイルではcamelCaseしか扱うことが出来ませんでした (field名をsnake_caseにすると回避可能ではありますが,不格好なスタイルになります).


というふうな背景からパッチを送った所,このあたりで取り込まれ,利用可能となりましたのでお知らせします.
以下のように使うことが出来ます *1

@Value
@Table("member")
@EqualsAndHashCode(callSuper = false)
public MemberRow extends Row<MemberRow> {
    @PrimaryKey
    @Column("member_id")
    private long memberId;
    @Column("member_name")
    private String memberName;
}

便利ですね.

*1:memberってテーブルなんだからcolumn名にmemberってprefixつけねーだろ普通,というツッコミは脇にのけてください