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

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

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

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つけねーだろ普通,というツッコミは脇にのけてください

npmとかbowerとか使ってるプロジェクトでEclipse使うと破滅するんだけど〜って人

npmとかbowerとかによって大量のjsファイルがディレクトリ中に含まれているプロジェクトでEclipse使うと破滅するんです.わかるでしょう.破滅するんですよ.滅亡です.
何故かと言うと,EclipseはWorkspaceをビルドする時にその大量のjsファイルに対してvalidationを走らせるからです.このvalidationがマジで重くて容易くハングします.もう駄目だ.


最近のプロジェクトでここらへんのjsの便利ツールを使わないはずが無いのでなんとかする必要があります.
そこで僕ってばIntelliJを使うことにしたわけなんですが,ちゃんとなんとかする方法もあります.
どうするかというと,プロジェクトの.projectファイルをエディッタで開いて,

<buildCommand>
    <name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
    <arguments>
    </arguments>
</buildCommand>

となっている所をまるっと削除してやるとよろしい.どうせEclipseでjsをアレやコレやすることもないでしょう? することがある人は頑張ってください.

Eclipse building workspace hangs after importing existing maven project because of JavaScript validation - Stack Overflow

ここに書いてました.最高.

Jettyを使ったリバースプロキシ構成のときに本当のアクセス元の情報が知りたいんですけど〜って時

Jettyを使ったリバースプロキシ構成をやっている時に,プロキシではなく本当のアクセス元の情報を知りたいという事があります.例えばHttpServletRequest#getRemoteAddr()とかで取りたい,みたいな.というかほとんどの場合でそういった欲求があります.
そういった時にどうするか,みたいなのを調べたのでメモを記します.なおJettyのバージョンは9です.


プロキシの方は当然ながらX-Forwarded-*系のヘッダを正しく取り扱える様に編集しておきます.
Nginxとかだとこんな感じになるでしょう.

location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}


Jettyの設定の方は,デフォルトのjetty.xml

<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
    <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
-->

コメントアウトされている所のコメントアウトを外してやると良いです.でもってJettyを再起動.
このForwardedRequestCustomizerが何をする君かというと,

  • X-Forwarded-Host
  • X-Forwarded-Server
  • X-Forwarded-For
  • X-Forwarded-Proto

のヘッダを見て,それを処理して Servlet の Request ヘッダをよしなにしてくれる君です.
HttpServletRequest#getRemoteAddr() がリバースプロキシの IP アドレスではなく,リアルのリクエスト元の IP アドレスを返してくるようになったりします.
詳しくはこちらを参照して下さい.
http://download.eclipse.org/jetty/9.2.10.v20150310/apidocs/org/eclipse/jetty/server/ForwardedRequestCustomizer.html


あと,
Plack::Middleware::ReverseProxy でリモートホストを確認する理由 - blog.nomadscafe.jp
というような話題があり,こうした対応が必要となるかも知れません (とは言えJettyが使うポートが外に露出しているというケースはあまり無いと思いますが……).
そうした場合どうするかと言うと,jetty-http.xmlとjetty-https.xmlのそれぞれに

<Set name="host"><SystemProperty name="jetty.host" default="127.0.0.1" /></Set>

と書いてやると良い.こうすると,このJettyに対してはlocalhostからしかアクセス出来ないようになります.
まあ,やっとくと良いでしょうという感じはします.


なお余談ですが,Jettyのリバースプロキシ環境下でのフォワードについて調べると

<Call name="addConnector">
    <Arg>
        <New class="org.eclipse.jetty.nio.SelectChannelConnector">
            <Set name="port">8080</Set>
            <Set name="forwarded">true</Set>
        </New>
    </Arg>
</Call>

とすると良いというような情報に行き着くと思うんですが,これは古いJetty (6とか) のための情報で,
現時点で最新のJetty 9などでは利用不可能な情報です.ご注意ください.

Java でテストカバレッジを取る (JaCoCo編)

一種の指標になるので,なんだかんだでテストカバレッジは取りたくなります.

Javaでそれをどうやるかをサッと検索すると,Coberturaを使う方法とJaCoCoを使う方法が引っかかると思うんですが,Coberturaの方はJava8のコードが含まれているとJavaNCSSの兼ね合いで発狂して使えなくなったり,Mavenのtestライフサイクルにfindbugscheckstyleを含めると使えなくなったりと色々不便なので,JaCoCoを使う方法でやることになっていきます.

Mavenでどうやるかというと,pom.xml

<plugin>
	<groupId>org.jacoco</groupId>
	<artifactId>jacoco-maven-plugin</artifactId>
	<version>0.7.4.201502262128</version>
	<executions>
		<execution>
			<id>prepare-agent</id>
			<goals>
				<goal>prepare-agent</goal>
			</goals>
		</execution>
	</executions>
</plugin>

という風に追記してやると良いってcoveralls-maven-pluginに説明されていましたのでそのようにやります.

そして

$ mvn clear test jacoco:report

などとしてやると,target/site/jacoco 以下にカバレッジレポートが出力されます.

f:id:moznion:20150425164600p:plain

コードレベルのカバーレポートも出て可愛い.

f:id:moznion:20150425164624p:plain

そしてこの結果をcoveralls-maven-pluginを使ってcoverallsに送りつける事も可能です.便利ですね.

URIBuilderTinyというのを書いた

URIBuilderTinyというやつを書きました.Maven Centralにもあがっています.盛り上がってまいりました.

http://search.maven.org/#artifactdetails|net.moznion|uribuilder-tiny|2.0.1|


一般的なソフトウェアエンジニア諸氏におかれましてはJavaURIを組み立てたい! みたいな欲求が週に500回くらいあると思いますけれども,そういう時にはURIBuilderを使うかURI Objectを使うかという感じになるかと存じます.


で,URIBuilderはまあ便利なので使うモチベーションが生まれるわけなんですけど,このURIBuilderはApache HttpClientコンポーネントの1つなので,URIを組み立てたいだけなのになぜか俺はHTTP Clientをインストールしている! キエエ! という感じになる事があります*1

加えて,appendPaths(String... paths)のような便利メソッドが実はURIBuilderには存在しないのでウッとなる瞬間があったり,「これはあんま使わんやろ……」というメソッドがいくつかあるというのもあったり……


というわけでこの度URIBuilderTinyというライブラリを作成しました.
特徴としては

  • 依存が少ない (というか実行にあたっての他のライブラリへの依存が無い)
  • appendPaths()のようなチョイ便利なメソッドを足している
  • URIBuilderが実装しているけどあんま使わない(であろう)メソッドは省いている

という感じで自分が使いたいものだけを実装したというライブラリになります.
詳細はドキュメント等を参照ください.

余談ですが,「ホスト名の最後がスラッシュで終わっていたら生成されるURIもスラッシュで終わる」という世話焼き機能が搭載されているなどしています.これ地味に便利なので……


ご活用ください.

*1:とは言え,URIを組み立てたらHTTP Clientでリクエストを飛ばしたりするだろ普通は,というのはありますが