はじめに
nginxのアクセスログをfluentdでmysqlに流し込み、metabaseで解析・可視化できるようにします。
セットアップ
Metabase
$ sudo docker run -d -p 3000:3000 --name metabase metabase/metabase
$ sudo firewall-cmd --add-port=3000/tcp --permanent
$ sudo firewall-cmd --reload
docker起動してポート開けて終わりです。
dockerや配布jar版のmetabaseは、表示できる列数がデフォルトで2000になっています。
これはハードコードなのでコンフィグから変更することはできません。
自分でビルドする場合
まずgitからソースをクローンします。$ git clone https://github.com/metabase/metabase.git
$ cd metabase/
ソースをクローン後、列数制限している部分を変更します。
(ns metabase.query-processor.middleware.constraints
"Middleware that adds default constraints to limit the maximum number of rows returned to queries that specify the
`:add-default-userland-constraints?` `:middleware` option."
(:require
[metabase.models.setting :as setting]
[metabase.util.i18n :refer [deferred-tru]]))
(def ^:private ^:const default-max-results-bare-rows <任意の桁数に変更>)
;; NOTE: this was changed from a hardcoded var with value of 2000 (now moved to [[default-max-results-bare-rows]])
;; to a setting in 0.43 the setting, which allows for DB local value, can still be nil, so any places below that used
;; to reference the former constant value have to expect it could return nil instead
(setting/defsetting max-results-bare-rows
(deferred-tru "Maximum number of rows to return specifically on :rows type queries via the API.")
:visibility :authenticated
:type :integer
:database-local :allowed)
(def ^:private max-results
"General maximum number of rows to return from an API query."
<任意の桁数に変更>)
(defn default-query-constraints
DockerHubから、すでにClojure環境構築済みのコンテナイメージを使用します。
bashをコンテナ側に渡すことで、ターミナルから直接操作できるようになります。
$ sudo docker run -it --rm -v $(pwd):/tmp/metabase --workdir /tmp/metabase clojure:openjdk-11-tools-deps-slim-bullseye /bin/bash
必要なモジュールをインストールします。
# apt update && apt install -y curl gnupg
# curl -sL https://deb.nodesource.com/setup_lts.x | bash -
# apt update && apt install -y nodejs
# curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
# echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
# apt update && apt install -y yarn
モジュールをアップデートします。
# npx update-browserslist-db@latest
# npx browserslist@latest --update-db
# yarn upgrade
ビルドします。
# yarn
# ./bin/build.sh
Copyright © 2023 Metabase, Inc.
Metabase Enterprise Edition extensions are PRESENT.
Usage of Metabase Enterprise Edition features are subject to the Metabase Commercial License. See https://www.metabase.com/license/commercial/ for details.
Finished compilation in 74.0 seconds.
Copy resources
Copy src
Copy shared/src
Copy resources
Create uberjar
Building uber jar: /tmp/metabase/target/uberjar/metabase.jar
Created uberjar in 32.0 seconds.
Update META-INF/MANIFEST.MF
Built target/uberjar/metabase.jar in 110.8 seconds.
Uberjar built successfully.
All build steps finished.
/tmp/metabase/target/uberjar
にjarファイルが出力されるので、dockerコンテナからexitして
$ java -jar ./target/uberjar/metabase.jar
で実行できます。
Nginx
$ nginx -version
nginx version: nginx/1.24.0
ログファイル形式
http {
log_format main "time:$time_iso8601\t"
"client:$remote_addr\t"
"request_method:$request_method\t"
"status:$status\t"
"url:$scheme://$http_host$request_uri\t"
"referer:$http_referer\t"
"forwarded_for:$http_x_forwarded_for\t"
"request_body:$request_body\t"
"body_bytes_sent:$body_bytes_sent\t"
"user_agent:$http_user_agent\t"
"authorization:$http_authorization";
access_log /var/log/nginx/access.log main;
LTSVフォーマットで記述しています。
各値は"<key>:value\t"
の形式で、<key>
を後ほど使うのでメモでもしておいてください。
MariaDB
$ mysql --version
mysql Ver 15.1 Distrib 10.11.3-MariaDB, for Linux (x86_64) using readline 5.1
Fluentd
Fluentdは普通に検索して出てくる記事だとv1やv2など古いバージョンが出てきてインストールでコケます。
ここでは最新のv4をインストールします。
本体
$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent4.sh | sh
MariaDBライブラリ
これがないとFluentdとMySQLの連携でコケます。
$ sudo yum install mariadb-devel
FluentdとMySQLの連携ライブラリ
やたらインストールに時間がかかりますが、大人しく待ちましょう。
$ sudo td-agent-gem install fluent-plugin-mysql
ファイルディスクリプタ
ファイルディスクリプタの最大数設定を変更します。
$ vim /etc/security/limits.conf
末尾に追記
root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536
保存後、ulimit
で確認します。
$ ulimit -n
65536
ログアクセス設定
td-agent(fluentd)
がアクセスログを読み込めるように設定します。
$ sudo usermod -aG adm td-agent
td-agent.confの編集
td-agent
の動作を設定します。
以下を追記します
<source>
@type tail
path /var/log/nginx/access.log
pos_file /var/log/td-agent/nginx.access.log.pos
tag nginx.access
format ltsv
time_format %Y-%m-%dT%H:%M:%S%z
</source>
<match nginx.access>
@type mysql_bulk
host <DB_host>
port <DB_port>
database <DB_name>
username <DB_username>
password <DB_password>
column_names id,time,client,request_method,status,url,referer,forwarded_for,request_body,body_bytes_sent,user_agent,authorization
key_names id,${time},client,request_method,status,url,referer,forwarded_for,request_body,body_bytes_sent,user_agent,authorization
table <DB_table>
flush_interval 5s
</match>
####
## Examples:
##
<source>
ディレクティブのtailでログファイルの更新を監視し、新しい行が追加されるたびに取得します。
<match>
ディレクティブは、データを指定したMySQLデータベースのテーブルに格納します。
column_names
パラメータでカラム名を指定し、key_names
パラメータでnginxのログファイルに記述した<key>
に対応させる形で指定します。
${time}
パラメータでログ取得時刻を設定してdatetime
型のtime
カラムに挿入します。
イベント発生時刻ではなくログ取得時刻がtime
カラムに挿入されますが、SQLの更新を5秒単位で行っているのでここでの誤差は無視します。(datetime形式に整形してログ出力する方法がわからなかったとかではないです)
設定を変更したらサービスを起動します。
$ sudo systemctl enable td-agent
$ sudo systemctl start td-agent
出力先テーブルの作成
Fluentdにテーブルが存在しない場合の処理はないため、事前に出力したデータを格納するテーブルを作成します。
以下の仕様でSQLデータベースを作成してください。
>CREATE DATABASE <DB_name>;
>CREATE TABLE <DB_table> (
id INT AUTO_INCREMENT PRIMARY KEY,
time datetime,
client varchar(16),
request_method varchar(4),
status INT(11),
url TEXT,
referer TEXT,
forwarded_for TEXT,
request_body TEXT,
body_bytes_sent varchar(20),
user_agent TEXT,
authorization varchar(30)
);
データベースを作成したあとは適当なページにアクセスすればテーブルに値が入っているはずです。
metabase
http://<server address>:3000
にアクセスすると、metabaseの初期セットアップが始まるので、プロンプトに従って設定を完了してください。
日本語はやや怪レいですが、十分使えるレベルです。