- 投稿日:2020-02-05T13:33:28+09:00
Nginx Vhost Traffic Status のデータを ELK に取り込む
Nginx Vhost Traffic Status のデータを ELK に取り込む
Nginx Vhost Traffic Status(以降 Nginx VTS) のデータを取り込む準備
nginx-vts-exporter のインストール
Nginx VTS の JSONデータを Prometeus用に出力してくれる便利なやつ
git-clone$ git clone https://github.com/hnlq715/nginx-vts-exporter.git
golangのinstall$ wget https://dl.google.com/go/go1.13.7.linux-amd64.tar.gz $ sudo tar go1.13.7.linux-amd64.tar.gz -C /usr/local/go $ sudo cat <<EOF > /etc/profile.d/goenv.sh export GOROOT=/usr/local/go export GOPATH=$HOME/go export PATH=$PATH:$GOROOT/bin:$GOPATH/bin EOF $ source /etc/profile.d/goenv.shnginx-vts-exporterのCompile&Install$ cd nginx-vts-exporter $ make $ sudo cp nginx-vts-exporter /usr/bin $ sudo cp nginx_vts_exporter.default /etc/sysconfig/nginx_vts_exporter $ sudo cat <<EOF > /etc/sysconfig/nginx_vts_exporter NGINX_VTS_EXPORTER_OPTS='-telemetry.address="localhost:9913" -nginx.scrape_uri=http://localhost/status/json' EOF $ sudo cat <<EOF > /usr/lib/systemd/system/nginx_vts_exporter.service [Unit] Description=Prometheus exporter thar exports Nginx VTS stats. Documentation=https://github.com/hnlq715/nginx-vts-exporter After=network.target [Service] EnvironmentFile=-/etc/sysconfig/nginx_vts_exporter User=root ExecStart=/usr/bin/nginx-vts-exporter $NGINX_VTS_EXPORTER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF $ sudo systemctl enable nginx_vts_exporter $ sudo systemctl start nginx_vts_exporterデータを取得してみる
expoter の Lisner は localhost の port 9913 なので接続してみる。
port9913接続$ curl http://localhost:9913 <html> <head><title>Nginx Exporter</title></head> <body> <h1>Nginx Exporter</h1> <p><a href="/metrics">Metrics</a></p> </body> </html>おや?なんか変・・・・・
nginx-vts-exporterのoption$ nginx-vts-exporter -h Usage of nginx-vts-exporter: -insecure Ignore server certificate if using https (default true) -metrics.namespace string Prometheus metrics namespace. (default "nginx") -nginx.scrape_timeout int The number of seconds to wait for an HTTP response from the nginx.scrape_uri (default 2) -nginx.scrape_uri string URI to nginx stub status page (default "http://localhost/status") -telemetry.address string Address on which to expose metrics. (default ":9913") -telemetry.endpoint string Path under which to expose metrics. (default "/metrics") -version Print version information.ほう、endpoint が /metrics の模様なので再度試験
endpointに接続$ curl http://localhost:9913/metrics # HELP nginx_cache_bytes cache request/response bytes # TYPE nginx_cache_bytes counter nginx_cache_bytes{direction="in",zone="cache-zone"} 33366 nginx_cache_bytes{direction="out",zone="cache-zone"} 551016 # HELP nginx_cache_requests cache requests counter # TYPE nginx_cache_requests counter nginx_cache_requests{status="bypass",zone="cache-zone"} 65 nginx_cache_requests{status="expired",zone="cache-zone"} 0 nginx_cache_requests{status="hit",zone="cache-zone"} 4 nginx_cache_requests{status="miss",zone="cache-zone"} 7 nginx_cache_requests{status="revalidated",zone="cache-zone"} 0 nginx_cache_requests{status="scarce",zone="cache-zone"} 0 nginx_cache_requests{status="stale",zone="cache-zone"} 0 nginx_cache_requests{status="updating",zone="cache-zone"} 0 <snip>cache hit などは Virtual Server毎に観たいので以下のように取得してみる。
取得する内容をgrepで絞る$ /usr/bin/curl -s http://localhost:9913/metrics | grep -v ^# | grep -e "_server_requests" -e "_server_bytes" nginx_server_bytes{direction="in",host="*"} 1.1809658e+07 nginx_server_bytes{direction="in",host="elk.nakacya.jp"} 146149 nginx_server_bytes{direction="in",host="localhost"} 1.1582905e+07 nginx_server_bytes{direction="in",host="test1.nakacya.jp"} 46807 nginx_server_bytes{direction="in",host="www.nakacya.jp"} 33797 nginx_server_bytes{direction="out",host="*"} 2.554692267e+09 nginx_server_bytes{direction="out",host="elk.nakacya.jp"} 332947 nginx_server_bytes{direction="out",host="localhost"} 2.553677271e+09 nginx_server_bytes{direction="out",host="test1.nakacya.jp"} 597605 nginx_server_bytes{direction="out",host="www.nakacya.jp"} 84444 nginx_server_requests{code="1xx",host="*"} 0 nginx_server_requests{code="1xx",host="elk.nakacya.jp"} 0 nginx_server_requests{code="1xx",host="localhost"} 0 nginx_server_requests{code="1xx",host="test1.nakacya.jp"} 0 nginx_server_requests{code="1xx",host="www.nakacya.jp"} 0 nginx_server_requests{code="2xx",host="*"} 33502 nginx_server_requests{code="2xx",host="elk.nakacya.jp"} 73 nginx_server_requests{code="2xx",host="localhost"} 33309 nginx_server_requests{code="2xx",host="test1.nakacya.jp"} 83 nginx_server_requests{code="2xx",host="www.nakacya.jp"} 37 nginx_server_requests{code="3xx",host="*"} 14 nginx_server_requests{code="3xx",host="elk.nakacya.jp"} 14 nginx_server_requests{code="3xx",host="localhost"} 0 nginx_server_requests{code="3xx",host="test1.nakacya.jp"} 0 nginx_server_requests{code="3xx",host="www.nakacya.jp"} 0 nginx_server_requests{code="4xx",host="*"} 219 nginx_server_requests{code="4xx",host="elk.nakacya.jp"} 19 nginx_server_requests{code="4xx",host="localhost"} 133 nginx_server_requests{code="4xx",host="test1.nakacya.jp"} 33 nginx_server_requests{code="4xx",host="www.nakacya.jp"} 34 nginx_server_requests{code="5xx",host="*"} 2 nginx_server_requests{code="5xx",host="elk.nakacya.jp"} 0 nginx_server_requests{code="5xx",host="localhost"} 0 nginx_server_requests{code="5xx",host="test1.nakacya.jp"} 0 nginx_server_requests{code="5xx",host="www.nakacya.jp"} 2 nginx_server_requests{code="total",host="*"} 33737 nginx_server_requests{code="total",host="elk.nakacya.jp"} 106 nginx_server_requests{code="total",host="localhost"} 33442 nginx_server_requests{code="total",host="test1.nakacya.jp"} 116 nginx_server_requests{code="total",host="www.nakacya.jp"} 73データ加工
direction のin/out が「指数表記」になっているのは困るので加工します。
ここの 1行perl が優秀
データ加工#Server Metric GET /usr/bin/curl -s http://localhost:9913/metrics | grep -v ^# | grep -e "_server_requests" -e "_server_bytes" > /var/log/nginx/vts_status.log # an exponential -> real number cat /var/log/nginx/vts_status.log | perl -anle 'printf "%s %d\n",$F[0],$F[1]' > /var/log/nginx/vts_status_number.log mv -f /var/log/nginx/vts_status_number.log /var/log/nginx/vts_status.log加工後
/var/log/nginx/vts_status.lognginx_server_bytes{direction="in",host="*"} 11809961 nginx_server_bytes{direction="in",host="elk.nakacya.jp"} 146149 nginx_server_bytes{direction="in",host="localhost"} 11583208 nginx_server_bytes{direction="in",host="test1.nakacya.jp"} 46807 nginx_server_bytes{direction="in",host="www.nakacya.jp"} 33797 nginx_server_bytes{direction="out",host="*"} 2555083406 nginx_server_bytes{direction="out",host="elk.nakacya.jp"} 332947 nginx_server_bytes{direction="out",host="localhost"} 2554068410 nginx_server_bytes{direction="out",host="test1.nakacya.jp"} 597605 nginx_server_bytes{direction="out",host="www.nakacya.jp"} 84444 nginx_server_requests{code="1xx",host="*"} 0 nginx_server_requests{code="1xx",host="elk.nakacya.jp"} 0 nginx_server_requests{code="1xx",host="localhost"} 0 nginx_server_requests{code="1xx",host="test1.nakacya.jp"} 0 nginx_server_requests{code="1xx",host="www.nakacya.jp"} 0 nginx_server_requests{code="2xx",host="*"} 33505 nginx_server_requests{code="2xx",host="elk.nakacya.jp"} 73 nginx_server_requests{code="2xx",host="localhost"} 33312 nginx_server_requests{code="2xx",host="test1.nakacya.jp"} 83 nginx_server_requests{code="2xx",host="www.nakacya.jp"} 37 nginx_server_requests{code="3xx",host="*"} 14 nginx_server_requests{code="3xx",host="elk.nakacya.jp"} 14 nginx_server_requests{code="3xx",host="localhost"} 0 nginx_server_requests{code="3xx",host="test1.nakacya.jp"} 0 nginx_server_requests{code="3xx",host="www.nakacya.jp"} 0 nginx_server_requests{code="4xx",host="*"} 219 nginx_server_requests{code="4xx",host="elk.nakacya.jp"} 19 nginx_server_requests{code="4xx",host="localhost"} 133 nginx_server_requests{code="4xx",host="test1.nakacya.jp"} 33 nginx_server_requests{code="4xx",host="www.nakacya.jp"} 34 nginx_server_requests{code="5xx",host="*"} 2 nginx_server_requests{code="5xx",host="elk.nakacya.jp"} 0 nginx_server_requests{code="5xx",host="localhost"} 0 nginx_server_requests{code="5xx",host="test1.nakacya.jp"} 0 nginx_server_requests{code="5xx",host="www.nakacya.jp"} 2 nginx_server_requests{code="total",host="*"} 33740 nginx_server_requests{code="total",host="elk.nakacya.jp"} 106 nginx_server_requests{code="total",host="localhost"} 33445 nginx_server_requests{code="total",host="test1.nakacya.jp"} 116 nginx_server_requests{code="total",host="www.nakacya.jp"} 73出た出た
sedで再加工&Host名でソート$ cat /var/log/nginx/vts_status.log | sed -e s/\{/./g -e s/\}/" :"/g -e s/\"//g -e s/,/" "/g -e s/" host="/" "/g | sort -k2,2 > /tmp/temp.log $ cat /tmp/temp.log nginx_server_bytes.direction=in * : 11810163 nginx_server_bytes.direction=out * : 2555344161 nginx_server_requests.code=1xx * : 0 nginx_server_requests.code=2xx * : 33507 nginx_server_requests.code=3xx * : 14 nginx_server_requests.code=4xx * : 219 nginx_server_requests.code=5xx * : 2 nginx_server_requests.code=total * : 33742 nginx_server_bytes.direction=in elk.nakacya.jp : 146149 nginx_server_bytes.direction=out elk.nakacya.jp : 332947 nginx_server_requests.code=1xx elk.nakacya.jp : 0 nginx_server_requests.code=2xx elk.nakacya.jp : 73 nginx_server_requests.code=3xx elk.nakacya.jp : 14 nginx_server_requests.code=4xx elk.nakacya.jp : 19 nginx_server_requests.code=5xx elk.nakacya.jp : 0 nginx_server_requests.code=total elk.nakacya.jp : 106 nginx_server_bytes.direction=in localhost : 11583410 nginx_server_bytes.direction=out localhost : 2554329165 nginx_server_requests.code=1xx localhost : 0 nginx_server_requests.code=2xx localhost : 33314 nginx_server_requests.code=3xx localhost : 0 nginx_server_requests.code=4xx localhost : 133 nginx_server_requests.code=5xx localhost : 0 nginx_server_requests.code=total localhost : 33447 nginx_server_bytes.direction=in test1.nakacya.jp : 46807 nginx_server_bytes.direction=out test1.nakacya.jp : 597605 nginx_server_requests.code=1xx test1.nakacya.jp : 0 nginx_server_requests.code=2xx test1.nakacya.jp : 83 nginx_server_requests.code=3xx test1.nakacya.jp : 0 nginx_server_requests.code=4xx test1.nakacya.jp : 33 nginx_server_requests.code=5xx test1.nakacya.jp : 0 nginx_server_requests.code=total test1.nakacya.jp : 116 nginx_server_bytes.direction=in www.nakacya.jp : 33797 nginx_server_bytes.direction=out www.nakacya.jp : 84444 nginx_server_requests.code=1xx www.nakacya.jp : 0 nginx_server_requests.code=2xx www.nakacya.jp : 37 nginx_server_requests.code=3xx www.nakacya.jp : 0 nginx_server_requests.code=4xx www.nakacya.jp : 34 nginx_server_requests.code=5xx www.nakacya.jp : 2 nginx_server_requests.code=total www.nakacya.jp : 73filebeat用に微調整
改行が邪魔なのと日時がないと困るので
・日時追加
・改行コード削除$ date "+%Y/%m/%dT%H:%M:%S" |sed -z 's/\n/ /g' && cat /tmp/temp.log | sed -z 's/\n/ /g' |sed -e "s/\$/\n/" 2020/02/05T04:04:33 nginx_server_bytes.direction=in * : 11810163 nginx_server_bytes.direction=out * : 2555344161 nginx_server_requests.code=1xx * : 0 nginx_server_requests.code=2xx * : 33507 nginx_server_requests.code=3xx * : 14 nginx_server_requests.code=4xx * : 219 nginx_server_requests.code=5xx * : 2 nginx_server_requests.code=total * : 33742最後に
これを filebeat に食わせて ELK の Logstash で Grok に食わせればデータの完成
Grok はこんな感じGrok^%{DATA:Date} nginx_server_bytes.direction=in %{DATA:Host} : %{DATA:In-Byte} nginx_server_bytes.direction=out .*: %{DATA:Out_Byte} nginx_server_cache.status=bypass .*: %{NUMBER:Cache_Bypass} nginx_server_cache.status=expired .*: %{NUMBER:Cache_Expired} nginx_server_cache.status=hit .*: %{NUMBER:Cache_Hit} nginx_server_cache.status=miss .*: %{NUMBER:Cache_Miss} nginx_server_cache.status=revalidated .*: %{NUMBER:Cache_Revalidated} nginx_server_cache.status=scarce .*: %{NUMBER:Cache_Scarce} nginx_server_cache.status=stale .*: %{NUMBER:Cache_Stale} nginx_server_cache.status=updating .*: %{NUMBER:Cache_Updating} nginx_server_requests.code=1xx .*: %{NUMBER:Requests_Code_1xx} nginx_server_requests.code=2xx .*: %{NUMBER:Requests_Code_2xx} nginx_server_requests.code=3xx .*: %{NUMBER:Requests_Code_3xx} nginx_server_requests.code=4xx .*: %{NUMBER:Requests_Code_4xx} nginx_server_requests.code=5xx .*: %{NUMBER:Requests_Code_5xx} nginx_server_requests.code=total .*: %{NUMBER:Requests_Code_Total}
- 投稿日:2020-02-05T12:54:08+09:00
ローカル環境からCloud SQL(PostgreSQL)への接続
ローカル環境からCloud SQL(MySQL)への接続の「PostgreSQL」版です。
基本的には、MySQLと同じ設定をします。
差分のみ説明します。Cloud SQLの作成
テーブルの作成
MySQLの時は、作成したユーザを利用して
gcloud sql connect [インスタンス名] --user=appuser --quiet
で接続出来ましたが、Postgresの場合、以下のエラーになります。
psql: FATAL: database "appuser" does not exist
そのため、一旦
postgres
でログインします。
gcloud sql connect [インスタンス名] --user=postgres --quiet
利用するデータベースの切替えます
\c mydb
テスト用のテーブルの作成します
CREATE TABLE users (ID SERIAL PRIMARY KEY, Name VARCHAR(255) NOT NULL, date TIMESTAMP);MySQLと同様にデータをインサートします。
その後、テーブルのオーナーを変更します。ALTER TABLE users OWNER TO appuserローカル環境の作成
ソース
package main import ( "database/sql" "fmt" "log" "time" _ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres" ) func main() { if err := showRecords("インスタンス名", "データベース", "ユーザ名", "パスワード"); err != nil { log.Fatal(err) } } func showRecords(dbAddress, dbName, dbUser, dbPassword string) error { // sslmode は必ず disable にする必要があります。 dsn := fmt.Sprintf("host=%s user=%s dbname=%s password=%s sslmode=disable", dbAddress, dbUser, dbName, dbPassword) db, err := sql.Open("cloudsqlpostgres", dsn) if err != nil { return err } defer db.Close() rows, err := db.Query("SELECT * FROM users") if err != nil { return err } defer rows.Close() for rows.Next() { var Name string var date time.Time var ID int64 if err := rows.Scan(&ID, &Name, &date); err != nil { return err } fmt.Printf("%d\t%s\t%s\n", ID, Name, date.Format(time.RFC3339)) } return nil }参考
Cloud SQL Proxy を Golang のパッケージとして使用する
golang mysql driverで `this user requires mysql native password authentication.
GCPのCloud Shellを使ってCloud SQLインスタンスに接続する方法