Nginxエラー調査 「duplicate MIME type 'text/html' in /etc/nginx/nginx.conf」

概要

エラーログをslackに通知させるようにしてるとほんと便利。

時たまなんですが、なんだこれ?というのが送られてくる。

その一つが掲題のエラー。

1
duplicate MIME type "text/html" in /etc/nginx/nginx.conf

nginx.confを見てみると
gzip_typesで設定した text/html でした。

直訳すると

1
/etc/nginx/nginx.confでMIMEタイプ「text/html」が重複しています。

じゃ、消せばいいかなってことなので消せば解決しました。

/etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gzip              on;
gzip_static on;
gzip_http_version 1.0;
gzip_types text/plain
text/html
text/xml
text/css
application/xml
application/xhtml+xml
application/rss+xml
application/atom_xml
application/javascript
application/x-javascript;
gzip_disable "MSIE [1-11]\.(?!.*SV1)";
gzip_disable "Mozilla/4";
gzip_comp_level 9;
gzip_vary on;

別にどこかで指定されているの?

結論を言うと

  • ngx_http_gzip_moduleをインストールしており
  • gzip on としている
    と、デフォルトでtext/htmlがMIMEタイプが指定されます。

以下公式サイトを見るとわかります。

gzip_types

text/htmlタイプは常に圧縮対象としているそうです。

なので、gzip で圧縮処理をする場合は
text/htmlが不要です。

ということでした。

NginxでGeoIP設定しアクセスログにアクセスポイントを追加する

概要

GeoIP Libraryを設定後、access.logにアクセスポイントを表示

GeoIP データファイル取得

GeoIPライブラリを提供しているMaxMindサイトから取得可能です。
有料版もありますが、取り急ぎは無料版で試します。

1
2
3
4
5
6
# mkdir -p /usr/share/GeoIP/
# cd /usr/share/GeoIP/
# wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
# wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
# gunzip GeoIP.dat.gz
# gunzip GeoLiteCity.dat.gz

nginx.conf設定

※ログのフォーマットはltsvにしています。

1
# vim /etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
http {

...
...

geoip_country /usr/share/GeoIP/GeoIP.dat;
geoip_city /usr/share/GeoIP/GeoLiteCity.dat;

log_format ltsv 'time:$time_iso8601\t'
'remote_addr:$remote_addr\t'
'request_method:$request_method\t'
'request_length:$request_length\t'
'request_uri:$request_uri\t'
'https:$https\t'
'uri:$uri\t'
'query_string:$query_string\t'
'status:$status\t'
'bytes_sent:$bytes_sent\t'
'body_bytes_sent:$body_bytes_sent\t'
'referer:$http_referer\t'
'useragent:$http_user_agent\t'
'forwardedfor:$http_x_forwarded_for\t'
'request_time:$request_time\t'
'upstream_response_time:$upstream_response_time\t'
'host:$host\t'

# geoIP setting --- start ---
'geoip_country_name:$geoip_city_country_name\t' # 国名
'geoip_country_code3:$geoip_city_country_code3\t' # JPNとかUSAとか
'geoip_city:$geoip_city\t' # 都市名
'geoip_latitude:$geoip_latitude\t' # 緯度
'geoip_longitude:$geoip_longitude'; # 経度
# geoIP setting --- end ---


access_log /var/log/nginx/access.log ltsv;
...
...

include /etc/nginx/conf.d/*.conf;
}

Nginx再起動

1
# systemctl restart nginx

アクセスログ確認

1
2
3
# tail -f /var/log/nginx/access.log

time:2015-10-01T18:01:48+09:00 remote_addr:xxx.xxx.xx.xx request_method:GET request_length:882 request_uri:/public/img/icon/favicon.ico https: uri:/public/img/icon/favicon.ico query_string:- status:200 bytes_sent:4791 body_bytes_sent:4096 referer:http://theflag.jp/ useragent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 forwardedfor:- request_time:0.001 upstream_response_time:0.001 host:theflag.jp geoip_country_name:Japan geoip_country_code3:JPN geoip_city:Tokyo geoip_latitude:35.6850 geoip_longitude:139.7514

取得できました♪

これをfluentdで流してKibanaでかっこよく表示しましょう。

以上です。

インストール済みNginx にgeoIP Library追加

概要

元々yumでNignxをインストールしていましたが
IP制限やfluentdでip情報を割り出す必要があり
geoIPが必要になりました。

その為には
新たにNginxをソースからダウンロードしLibrary追加しコンパイルし直す必要があります。

geoIPインストール理由

  • ログにip情報を付加しfluentdで解析する。
  • IP許可制限が可能になる。
    • 海外から不正アクセスがあった為対応しました。

環境

  • CentOS7
  • Nginx1.8
  • EC2

現状のNginxの利用可能モジュール確認

1
2
3
4
5
6
7
# nginx -V

nginx version: nginx/1.8.0
built by gcc 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'

--with-http_geoip_moduleがない!

ので geoIPをインストールしてNginxをコンパイルし直します。

GeoIP Libraryインストール

1
$ sudo yum install -y GeoIP GeoIP-devel

同バージョンのNginxのtar.gzをダウンロード

※今回はNginxは1.8.0なのでnginx-1.8.0.tar.gzをダウンロードします。

1
2
3
4
$ cd /usr/local/src
$ wget http://nginx.org/download/nginx-1.8.0.tar.gz
$ tar zxvf nginx-1.8.0.tar.gz
$ cd nginx-1.8.0

先ほどnginx -Vで確認したconfigure argumentsをコピって
そこに--with-http_geoip_moduleを追加してコンパイルする。

Nginx再コンパイル

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ cd /usr/local/src/nginx-1.8.0

$ ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-http_geoip_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'

...
checking for GeoIP library ... found ← ちゃんとインストール済み!
checking for GeoIP IPv6 support ... found ← ちゃんとインストール済み!
...
Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library

nginx path prefix: "/etc/nginx"
nginx binary file: "/usr/sbin/nginx"
nginx configuration prefix: "/etc/nginx"
nginx configuration file: "/etc/nginx/nginx.conf"
nginx pid file: "/var/run/nginx.pid"
nginx error log file: "/var/log/nginx/error.log"
nginx http access log file: "/var/log/nginx/access.log"
nginx http client request body temporary files: "/var/cache/nginx/client_temp"
nginx http proxy temporary files: "/var/cache/nginx/proxy_temp"
nginx http fastcgi temporary files: "/var/cache/nginx/fastcgi_temp"
nginx http uwsgi temporary files: "/var/cache/nginx/uwsgi_temp"
nginx http scgi temporary files: "/var/cache/nginx/scgi_temp"


$ make
$ make install

再度Nginxモジュール確認

1
2
3
4
5
6
7
nginx -V

nginx version: nginx/1.8.0
built by gcc 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-http_geoip_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'

--with-http_geoip_module
利用可能なモジュールとして設定されていることが確認できました。

以下設定ファイルも特に変更することなく
systemctl restart nginxしても問題なかったです。

1
2
/etc/nginx/nginx.conf
/etc/nginx/conf.d/*.conf

以上です。

エラーログをSlack通知する

環境

  • CentOS Linux release 7.1.1503 (Core)
  • td-agent: 0.12.12
  • Nginx: 1.8.0

概要

社内でSlackによる連携が進み
ログ管理もfluentdにまとめつつあるので
エラーログで何かあったらSlack通知させようと思いチャレンジ♪

以下のような流れを想定しています。

Nginx error.log —> fluentd —> slack

gemでも作るか!と思ったら既にSlack Pluginは豊富なので
あやからせていただきます!

準備

fluentdが/var/log/nginx/error.log にアクセスできるようにしておいてください。

ログがtailできないなんてときは以下参照♪

利用するfluentd Plugin

td-agent.conf設定

error.logフォーマット設定

  • Nginxのエラーログが以下のようにフォーマットされ出力されているとします。
1
2015/11/18 18:01:47 [error] 23029#0: *9086 open() "/var/golang/src/img/tmp.png" failed (2: No such file or directory), client: ***.**.**.****, server: hogehoge.jp, request: "GET /img/tmp.png HTTP/2.0", host: "hogehoge.jp", referrer: "http://hogehoge.jp"
  • fluentdのformat設定
1
format /^(?<time>.+) \[(?<level>[^\]]+)\] *(?<message>.*)$/

上記fomat設定によって以下のように key : value 構成で取得できます。

1
2
3
time : 2015/11/18 18:01
level : error
message : or] 23029#0: *9086 open() "/var/www/html/img/tmp.png" failed (2: No such file or directory), client: ***.**.**.****, server: hogehoge.jp, request: "GET /img/tmp.png HTTP/2.0", host: "hogehoge.jp", referrer: "http://hogehoge.jp"

設定によってはうまく通知させずハマりました汗

tag名をリライト

上記 で取得した key:value を元に tagを書き換えます。

以下の例だと、
levelerror の場合、 slack.error.${tag} (slack.error.nginx.error) にタグを書き換えてます。
他、warn, fatal も同様です。

1
2
3
4
5
6
<match nginx.error>
type rewrite_tag_filter
rewriterule1 level error slack.error.${tag}
rewriterule2 level warn slack.warn.${tag}
rewriterule3 level fatal slack.fatal.${tag}
</match>

また message で取得した値の中に

特定文字列が含まれている場合等も可能です。

例) message に 「PHP Fatal Error」 で始まる文字列が含まれている場合にslack.fatal.${tag}に書き換える。

1
2
3
4
5
6
7
8
<match nginx.error>
type rewrite_tag_filter
rewriterule1 level error slack.error.${tag}
rewriterule2 level warn slack.warn.${tag}
rewriterule3 level fatal slack.fatal.${tag}

rewriterule4 message ^PHP Fatal Error.*$ slack.fatal.${fatal} # 追加
</match>

フィールド追加

  • source_id 追加

time, level, message 以外に source_id を追加してます。
以下の例では source_id` に tag_suffix[1] を指定しています。

1
2
3
4
5
6
7
<match slack.**>
type record_reformer
tag reformed.${tag}
<record>
source_id ${tag_suffix[1]}
</record>
</match>

tag_suffix について

tag が reformed.slack.error.nginx.error とすると
以下のような仕様です。

1
2
3
4
5
6
tag_suffix[0] → reformed.slack.error.nginx.error
tag_suffix[1] → slack.error.nginx.error
tag_suffix[2] → error.nginx.error

tag_suffix[-1] → error
tag_suffix[-2] → nginx.error

slack通知

  • incoming WebhookからWebhookURLを設定
1
2
3
4
5
6
7
8
9
10
<match reformed.slack.**>
type slack
webhook_url https://hooks.slack.com/services/xxxxxxxxx/xxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxx
channel flag_production
username fluentd
title_keys source_id
title %s
color danger
flush_interval 5s
</match>

通知結果

余談

Slackに通知しても休日で業務連絡を見ないということは往々にしてあるので
Twillioで電話通知するpluginもあります。

y-ken/fluent-plugin-twilio

株式会社KDDIウェブコミュニケーションズが提供する有料サービスです。
比較的安価なので導入検討してみてください。

Twillio 料金表

twilio price

かつての「メール見てませんでした💦」
なんてことがなくなりそうなのは良いですね

以上です。

3分で出来る! AWS EC2(CentOS7)に td-agent2インストール

環境

  • AWS EC2
  • CentOS Linux release 7.1.1503 (Core)

td-agent2 インストール

1
$ sudo curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh

起動/サービス登録

1
2
$ sudo systemctl start td-agent
$ sudo chkconfig td-agent on

systemctl enableするとchkconfig使ってと怒られます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo systemctl enable td-agent

td-agent.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig td-agent on
The unit files have no [Install] section. They are not meant to be enabled
using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
[root@ip-172-31-19-253 log]#

試験

設定ファイル (/etc/td-agent/td-agent.conf)を見ると
デフォルト設定では、
httpプロトコルport:8888からLoggingしtd-agent.log(/var/log/td-agent/td-agent.log)に流すようにしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# HTTP input
# POST http://localhost:8888/<tag>?json=<json>
# POST http://localhost:8888/td.myapp.login?json={"user"%3A"me"}
# @see http://docs.fluentd.org/articles/in_http
<source>
type http
port 8888
</source>

## live debugging agent
<source>
type debug_agent
bind 127.0.0.1
port 24230
</source>

以下のようにコマンドを実行してtd-agent.logを確認してみる。

1
2
3
4
5
$ curl -X POST -d 'json={"json":"TEST!!"}' http://localhost:8888/debug.test

$ sudo tail -f /var/log/td-agent/td-agent.log

2015-09-19 17:34:50 +0900 debug.test: {"json":"TEST!!"}

上記のように正しくロギングされていることが確認できました。

Nginx ssl.conf設定 特定ページのみhttpsへリダイレクトさせる設定

概要

Go RevelフレームをNginx上で利用しています。

その際に設定したssl設定、及び、
特定ページのみhttpsへリダイレクトする様な
設定をする必要があったので以下まとめました。

https通信したいのページは以下です。

  • /register
  • /mypage
  • /login
  • /logout

https通信したいページをlocationの正規表現(~)でprefixを引っ掛けて
http通信の場合、https通信に301リダイレクトさせてます。

以上

Go Revelフレームワーク jQuery非同期処理

概要

Go RevelフレームワークでAjax非同期処理を実装します。

CSRF 対策

以下コマンドにより
RevelフレームワークでCSFR対策する為のライブラリをインストール

1
$ go get github.com/cbonello/revel-csrf
  • app/init.go

ajax実行時にCSRFチェックする為、init.goでのチェックを外すように設定

以下CSRFのFilter設定

1
2
3
4
5
6
func init()
revel.Filters = []revel.Filter{
...
...
csrf.CSRFFilter, // CSRF prevention.
...

conf/routes で実行するAPIのURLはAjax実行時にCSRFチェックする為、
init.goではチェックを対象外とする様に設定

1
csrf.ExemptedFullPath("/api_execute")

View側の設定

  • views/header.html

<head>〜</head> 内にCSRFチェック用ハッシュ値をmeta情報として埋め込みます。

1
<meta name="csrf-token" content="{{ .csrf_token }}">

jQueryファイル

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function setAjaxToken( token ) {
// ajax --- start --------------------------------------------------
$.ajaxSetup({
crossDomain: false,
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", token );
}
}
});
}

$(document).ready(function () {
$(document).on("click", ".ajax_execute", function (event) {
event.preventDefault();

setAjaxToken( postData['_token'] );

var ajaxParamas = {};
ajaxParamas["type"] = "POST";
ajaxParamas["url"] = action;
ajaxParamas["data"] = postData;
ajaxParamas["cache"] = false;
ajaxParamas["dataType"] = "json";

$.ajax(ajaxParamas)
.success( function(res) {
console.log("(^-^) OK")
}).error ( function() {
console.log("(>_<) NG")
});
return false;
})

簡単…とは行ってない気がしますが
CSRF対策ができました。

fluentd設定ハマった所あるある

以下随時追加。

環境

  • CentOS Linux release 7.1.1503 (Core)
  • Fluentd 0.12.12
  • Nginx 1.8.0

Permission denined

  • パーミッションエラー!
1
2
3
4
# tail -f /var/log/td-agent/td-agent.log

2015-08-19 14:17:14 +0900 [error]: Permission denied @ xxxxxxx - /var/log/nginx/error.log
2015-08-19 14:17:14 +0900 [error]: suppressed same stacktrace

対策

td-agent実行ユーザをrootに変更する。

1
2
3
4
5
6
7
$ sudo vim /etc/init.d/td-agent

- TD_AGENT_USER=td-agent
- TD_AGENT_GROUP=td-agent

+ TD_AGENT_USER=root
+ TD_AGENT_GROUP=root

デーモンリロード

1
sudo systemctl daemon-reload

動作確認

以下のようにtailが正しく実行できていることが確認できます。

1
2
3
4
# tail -f /var/log/td-agent/td-agent.log

2015-08-19 14:17:15 +0900 [info]: following tail of /var/log/nginx/access.log
2015-08-19 14:17:15 +0900 [info]: following tail of /var/log/nginx/error.log

[warn]: pattern not match

これかなりハマりました。

Nginxのlogを流すときに以下のようにfomatするように書かれている記事を多く見たので
設定してみたらエラー発生(; >_<)

  • /etc/td-agent/td-agent.conf
1
2
3
4
5
6
7
<source>
type tail
format nginx
path /var/log/nginx/access.log
pos_file /var/log/td-agent/nginx-access.pos
tag nginx.access
</source>

対策

以下のように修正

  • /etc/td-agent/td-agent.conf
1
2
3
4
5
6
7
8
<source>
type tail
format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forwarder>[^\"]*)")?/
time_format %d/%b/%Y:%H:%M:%S %z
path /var/log/nginx/access.log
pos_file /var/log/td-agent/nginx-access.pos
tag nginx.access
</source>

td-agent再起動

1
$ sudo systemctl restart td-agent

これで大丈夫。

buffer_path 重複

1
[error]: failed to configure sub output redshift: Other '' plugin already use same buffer_path: type = , buffer_path = *

元々の設定は以下の様にしていました。
td-agent の送信先にトラブルがあり buffer が溜まり重複しエラーとなっていました。

1
buffer_path /logs/td-agent/nginx/logs

例)以下の様な tag があった場合、buffer_path は同じく /logs/td-agent/nginx/logs となってしまう

hogehoge.20170101.log
hogehoge.20170102.log

対策

tag_parts を用い、以下の様に tag 毎に buffer_path をユニークにすることで解決

1
buffer_path /logs/td-agent/nginx/logs_${tag_parts[0]}_${tag_parts[1]}

引き続き何か発生したら追記していきます。

Go初心者におすすめ本

概要

身の回りであまり Go を積極的にやっている人がいないので
やってみたいなぁ、気になってはいる、
という方に本をおすすめしてみたいと思いました。

この一冊!

以下をチョイスしました!

よかった点

  • 全部で 34 ページ!1 日で読み終わり、逆引きとしても利用できる。(Go のオフィシャルのチュートリアルをまとめてくれてる感じ)
  • Go の成り立ちを簡潔に説明しており、クロスコンパイルや並列処理サポートなどがあり Go の使いどころがわかる。
  • ちょうど「Web API デザインの鉄則」という特集があり、API 開発にはちょうど良い内容の一冊だった。

特に本を紹介して自分にお金が入ることはないので
斜めから見ずにまず本見てみてください ♪

Go を使いたくなる記事

JSON シリアライズし秒間のレスポンス回数測定

以下 Qiita 記事でまとめてくれていました。

「最速」フルスタック Web フレームワーク「revel」の紹介

個人的に好きな所

  • while や do/while 、参考演算子がなく for のみ、とか冗長なコーディングを許さない
  • gofmt でフォーマット化してくれる。いつもコミット前にやってます。
  • ライブラリ増えてる。 Python のpip installみたく go getでインストール可。
  • ネイティブなのでアプリケーションが大きくなってもさほど遅くならない。

以上
Gopher とお話できる機会が増えると何よりです。

Kibana4 インストール on CentOS7

前提

  • Nginx インストール済み

環境

  • CentOS Linux release 7.0.1406 (Core)
  • Nginx 1.9.3
  • Kibana 4.1.1

Kibana インストール

1
2
3
$ cd /usr/local/src
$ sudo wget https://download.elastic.co/kibana/kibana/kibana-4.1.1-linux-x64.tar.gz
$ sudo tar xvzf kibana-4.1.1-linux-x64.tar.gz

Kibana 設定ファイル修正

1
$ vi /usr/local/src/kibana-4.1.1-linux-x64/config/kibana.yml
  • host指定

デフォルトでは 0.0.0.0 となっています。
今回は同サーバに構築するので localhost とし保存します。

1
2
- host: "0.0.0.0"
+ host: "localhost"

上記の設定により、kibanaがlocalhostにアクセスできるようになります。

Kibana 実行パス作成

1
2
$ sudo mkdir -p /opt/kibana
$ sudo cp -R /usr/local/src/kibana-4.1.1-linux-x64/* /opt/kibana/

上記設定により以下コマンドでkibana実行可能になります。

1
/opt/kibana/bin/kibana

上記でも十分ですが、再起動した際にはkibanaは停止してしまいます。
なので、起動スクリプトを作成し、サービス登録します。

起動スクリプト作成

1
$ sudo vi /etc/systemd/system/kibana4.service
  • kibana4.service
1
2
3
4
5
6
7
8
9
10
11
12
[Service]
ExecStart=/opt/kibana/bin/kibana
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=kibana4
User=root
Group=root
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

上記保存します。

起動/サービス登録

1
2
$ sudo systemctl start kibana4
$ sudo systemctl enable kibana4

Nginx インストール

以下参考にしてください。

Nginx設定ファイル修正

リーバスプロキシでKibana4用ポート(5601)へ向ける。

1
$ sudo vi /etc/nginx/conf.d/default.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
server_name ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com;

auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd.users;

location / {
proxy_pass http://localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}

}

以上設定保存後、Nginx再起動

1
$ sudo systemctl restart nginx

アクセスして確認

以下のように表示されれば問題ありません。

以上

参考記事

Systemd入門(4) - serviceタイプUnitの設定ファイル

起動スクリプトについて 各項目説明

[Unit] について
オプション 説明
Description Unitの説明文
Documentation ドキュメントのURI
Requires このUnitが必要とする前提Unit
Wants このUnitが必要とする前提Unit
After このUnitより先に起動するべきUnit
Before このUnitより後に起動するべきUnit
[Install] について
オプション 説明
WantedBy enable時にこのUnitの.wantsディレクトリにリンク作成
RequiredBy enable時にこのUnitの.requiredディレクトリにリンク作成
Also enable/disable時に同時にenable/disableするUnit
Alias enable時にこのUnitの別名を用意

↓この本とってもお世話になりました♪