LTSV に関する投稿を表示しています

LTSV なデータを SQL で探索する ltsvq を作った

sters/ltsvq: ltsvq is LTSV Queryer that written in Go

Labeled Tab-separated Values (LTSV) なアクセスログのデータをパースし、少しだけ複雑な条件で集計する必要があった。
ELKStackなんかで集計する仕組みを整えて構築するよりも、さくっとできるソリューションでよかった。
ぱっと調べても便利に使えそうなのはなさそうに見えたので、ぱっとひらめいたアイデアで行けるかどうか、おためし的に作った。

実装は GitHub - Songmu/go-ltsvGitHub - mattn/go-sqlite3: sqlite3 driver for go using database/sql がほぼすべて。
パースした結果を SQLite にオンメモリで入れて、リクエストされたクエリを実行し、取れたものを再び LTSV になおして出力する。
SQLite でできることはできるので、絞り込みも並び替えも、集計だってできる。

と、まあ作ること自体はすぐだったのだが GitHub - goreleaser/goreleaser: Deliver Go binaries as fast and easily as possible でリリースを作ろうとしたら数時間積んでいた。
色々調べた結果、必要なライブラリが詰まった Docker イメージを準備し、その上でスタティックリンクになるように ldflags を指定してビルドするのが正解らしい CGO も効いているはず、きいてないと mattn/go-sqlite3 が動かんのでは…?

このあたり cmd/go: build: add -static flag · Issue #26492 · golang/go

ストリーミングなデータの tail -f みたいなずっと流れてくるデータをパイプして使うようなものは、どうしたらいいのかわからなかったので諦めてしまった。また今度挑戦してみよう。

-----

追記: ググり方が悪かったようで lltsv なるものがすでにあることを教えてもらった。
GitHub - sonots/lltsv: List specified keys of LTSV (Labeled Tab Separated Values)

前後の記事

Next:
Prev:

nginx のアクセスログを LTSV にする

アクセスログ LTSV が便利だよって聞いたので設定するだけ設定した。
活用するのはこれから。

そもそも LTSV って? Labeled Tab-separated Values (LTSV)

Labeled な TSV だそうで、タブ区切りで処理するときにラベル付いてるので 1 番目が〜2 番目が〜みたいなことをしなくて便利。

そのサイトにもやり方がざっくり書いてあるが、いったん全部入りでこうした。
量多すぎて辛かったら一部捨てる感じで。

log_format main "time:$time_local"
    "\thost:$remote_addr"
    "\tforwardedfor:$http_x_forwarded_for"
    "\tuser:$remote_user"
    "\treq:$request"
    "\tmethod:$request_method"
    "\turi:$request_uri"
    "\tprotocol:$server_protocol"
    "\tstatus:$status"
    "\tsize:$body_bytes_sent"
    "\treqsize:$request_length"
    "\treferer:$http_referer"
    "\tua:$http_user_agent"
    "\tvhost:$host"
    "\treqtime:$request_time"
    "\tcache:$upstream_http_x_cache"
    "\truntime:$upstream_http_x_runtime"
    "\tapptime:$upstream_response_time"
    "\tmsec:$msec"
    "\tproxy_add_x_forwarded_for:$proxy_add_x_forwarded_for"
    "\tscheme:$scheme"
    "\tupstream_addr:$upstream_addr"
;
access_log  /var/log/nginx/access.log  main;