[jqコマンド] jsonデータログから発生順位ランキングを取得する方法

Pocket
LINEで送る
GREE にシェア
LinkedIn にシェア

こんにちわ。
 

コマンド・ワン・ライナーにかなりのこだわりがある、下駄です。
 

「サーバーコマンド」とかけまして、
 

「標準じゃない体格の人の着る服」と、ときます。
 

そのココロは・・・
 

“ls”が定番です。

難題は突然やってくる

SQLデータベースはなるべく利用したくないので、json形式でテキストログを追記形式にして溜め込んでいるんですが、
 

linuxの”/var/log/*”と、同じような状態になっている事は、理解しやすいかと思います。
 

そのjsonデータに、ログ取得した人(サイトにアクセスした人)のタイプが書き込まれてあり、タイプ別にアクセス数を取得したり、そのランキングを集計したいと、アクセス解析をやらなければいけなくなりました。
 

その際に、jsonデータは、jqコマンドに任せて、整形された集計データを返せばいいと考えていたのですが、思いの外この手の処理が難しい事がわかりました。
 

タイプ1つ1つの処理をjsonログから探して個数を出す処理はさほど難しくないのですが、
 

ログのボリュームが大きくなった時に、タイプ数分のjqコマンドを実行すると、単純に1回に5秒ぐらいかかってしまうと、タイプが10個あれば、10倍の処理速度が有してしまいます。
 

できれば、データをなめるのは、1回にとどめたいと思うのが、システムエンジニアであれば誰でもそう考えるはずです。
 

jqコマンドとの格闘

まず、元データは、こんな感じ。
 

 

そして、とりあえず、user_typeのみを抜き出してみる。
 

 

こんな書き方もできます。
 

 

配列で返すぐらいでこの2つはさほど差がありません。
 

ちなみに、nullの値は、ユーザータイプ0とマージしたいという、困難仕様。
 

分岐処理を使うとnull問題は解決しそうだ。
 

 

これをそれぞれの値のlengthを取得して、json形式に整形しようとしたのだが、jqコマンドでは、ここに限界があるようだ。
 

仕方なく、別コマンドと連携してみる。
 

 

左の数値が発生個数で、右の数値が、user_typeです。
 

レスのスペース文字も気になるし、なんだかjsonでも、csvでもない、この状態が気持ち悪いので、awkを使って整形
 

なんちゃってcsv形式での出力に成功です。そして、左側にuser_type、右側に発生数にして、key,valueっぽくしてみました。
 

でも、このままでは、ランキング結果が出せないので、ランキングに対応するには、以下のようにします。
 

 

これで完成!
 

コマンド・ワンライナーの活用方法

サンプルは6件しかデータがないのですが、数万件ぐらいであれば、結構すぐに結果がでるので、簡単にランキングを集計することができますね。
 

ちなみに、この方法を活用すると、通常のlinuxログに対して、nginxやapacheのログからIPアドレス別アクセスランキングなどを出すこともできて、不正に大量アクセスが会った場合など、すぐに割り出すことができます。
 

こうした、コマンド・ワンライナーって、覚えておくと非常に仕事がはかどる仕組みなんですね。

Leave a Reply

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です