[jqコマンド] ログデータを集計する時は"group_by"がめっちゃええ感じ

2020年4月21日

jq テクノロジー

SQLコマンドを覚えることよりも、JQコマンドを極めたほうが得と普通の人とは違うベクトルで考えている、ユゲタです。 「ログデータ」とかけまして、 「ストレス」と、ときます。 そのココロは・・・ トラブルがあるとどんどん溜まっていきます。

jqコマンドで集計するの難し〜〜〜

PODCASTラジオをスタートしてから、アクセス数が伸びるのが非常に面白く、ログデータシステムを構築する手間も惜しまない状態なんですが、 ナンチャッテ・ラジオ「聞くだけでプログラムが学べるラジオ」 そんなログデータの分析も、以下のような条件でログをためています。
1. PODCASTユーザーのmp3アクセス(RSS) 2. WEBサイトでのmp3再生 3. 管理画面でのmp3再生
そしてログはこんな感じ。 2020年4月9日の一部を抜粋 {"date":"20200409","time":"105400","file_id":"12","type":"2","ip":"1.1.1.1","ua":"***"} {"date":"20200409","time":"105400","file_id":"13","type":"2","ip":"2.2.2.2","ua":"***"} {"date":"20200409","time":"105402","file_id":"14","type":"2","ip":"3.3.3.3","ua":"***"} {"date":"20200409","time":"110325","file_id":"10","type":"0","ip":"4.4.4.4","ua":"Podcast/***"} IPアドレスと、UserAgentは、伏せ字にしてます。 余談ですが、UAにpodcastは、ちゃんと記述があるので、わかりやすいですね。 このログデータの中身は、次の通り。
date : アクセス日 time : アクセス時間(秒まで) file_id : 内部ファイル番号(エピソード番号) type : "0"がpodcast(rss)、"1"がwebサイト、"2"が管理画面
この状態で、日別、エピソード別、タイプ別のデータ集計をやるという事になります。

jqコマンドでTRY

以前に行ったタイプ別の判定で、初期仕様で"type"の箇所が無いログがあったので、その判定処理も入れた形にしたいので、 下記ページも参考にしてその続きになります。 [jqコマンド] jsonデータログから発生順位ランキングを取得する方法 そして、前回は単純に日別のアクセス数だけだったのに対して、今回は、エピソード別という要素も加わります。 出来上がりのソースから紹介しますね。 $ jq --slurp '[.[] | {"date":.date , "type":(.type | if . == "1" then 1 elif . == "2" then 2 else 0 end) , "file_id":.file_id}] | group_by(.) | map({"date":.[0].date , "type":.[0].type , "file_id":.[0].file_id , "count" : length})' mp3.log すげ〜長いんですが、これで返る値はこちら。 [ { "date": "20200409", "type": 0, "file_id": "10", "count": 1 }, { "date": "20200409", "type": 2, "file_id": "14", "count": 1 }, { "date": "20200409", "type": 2, "file_id": "15", "count": 2 } ] dateをデータに埋め込んでいる形ですが、読み込むファイルが日別データであれば、この値は割愛できます。 そのまま、dateをキーにした連想配列にぶっこむだけです。 そんなわけで、データをjqで集計できたら、javascriptでajaxアクセスしてこのデータを受け取り、少し整形して、chartシステムに受け流して上げれば、グラフ表示することができますね。

解説

今回のjqコマンドのポイントは、group_byという機能です。 任意に抽出した値(今回は、連想配列として値を作っています)、 {"date":"---" , "type":"---" , "file_id":"---"} このフォーマットでgroup_byをすると、同じ値を1つの配列にまとめてくれるという便利機能です。 あとは単純に最後にそれを呼び出して、countキーを作って、そこの作られた配列のlengthを入れているだけです。 少しややこしく感じるかもしれませんが、データベース集計などをやったことのある人であれば複数のキーに対しての集計値が取得できる、非常に便利な方法で有ることがわかると思います。 さて、JQコマンドを使って、次は何をしよか・・・

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。