unicornのlogrotate設定サンプル
/etc/logrotate.d 配下に下記を置く。
日次ローテート + 90日間保存で設定しています。
ローテートしたログは圧縮するが、直近の1世代分はそのまま
/var/www/app/shared/log/*.log { daily missingok rotate 90 dateext compress delaycompress lastaction pid=/var/www/app/shared/tmp/pids/unicorn.pid test -s $pid && kill -USR1 "$(cat $pid)" endscript }
※メモ
Unicornには、USR1シグナルを送ると、ログファイルを開きなおす機能が備わっている。
そのため、現在のログをリネームした後、USR1シグナルを送信してログをローテートする。
serviceコマンドでunicorn起動するための設定サンプル
下記ファイル を /etc/init.d/ に配置する。
#!/bin/sh # chkconfig: 345 99 01 # description: unicorn as Rails app server SERVICE="unicorn" ENV="production" RAILS_ROOT="/var/www/app/current" CONFIG=$RAILS_ROOT"/config/unicorn/"$ENV".rb" PID_FILE=$RAILS_ROOT"/tmp/pids/unicorn.pid" start() { START_CMD="cd $RAILS_ROOT && (RAILS_ENV=$ENV /usr/bin/env bundle exec unicorn -c $CONFIG -E $ENV -D)" su -l $USER -c "$START_CMD" & echo "service $SERVICE [start]" } stop() { STOP_CMD="cd $RAILS_ROOT && /usr/bin/env kill -s QUIT `cat $PID_FILE`" su -l $USER -c "$STOP_CMD" & echo "service $SERVICE [stop]" } status() { PID=`pgrep -f $CONFIG | wc -l` if [ $PID -eq 0 ]; then echo "$SERVICE stop" else echo "running $SERVICE ..." fi } case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo "Usage: $SERVICE [start|stop|restart|status]" ;; esac exit 0
下記コマンドで service に登録する
# /etc/init.d # sudo chkconfig --add unicorn
使い方
# sudo service unicorn [start|stop|restart|status]
webpack+Reactの環境構築メモ
npm install
$ cd my_project $ npm init $ npm install webpack -g $ npm install --save react react-dom $ npm install --save-dev webpack webpack-dev-server $ npm install --save-dev babel-loader babel-core babel-preset-react babel-preset-es2015
ReactDOM
DOM に React 要素をレンダーするためのモジュール
webpack
複数のファイルを変換してまとめるツール
たとえば複数のjsを変換してひとつにまとめたり。
babel (babel-cor)
JSコードの変換ツール
babel-loader
bableをwebpackで使うためのライブラリ
babel-preset-react
jsxをjsに変換するためのpreset(JSXはReact.createElementの糖衣構文)
babel-preset-es2015
ES2015をES5に変換するためのpreset
webpack.config.js
const webpack = require("webpack"); module.exports = { // minify // plugins: [ // new webpack.optimize.UglifyJsPlugin() // ], context: __dirname + '/src', entry: { js: './js/index.js' }, output: { path: __dirname + '/dist', filename: './js/app.js' }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015'] } }, { test: /\.jsx$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } } ] }, devServer: { // contentBase: 'dist', host: '127.0.0.1', port: 8080 }, };
ビルド
webpack
開発サーバ起動
package.jsonのscriptsに
"start": "webpack-dev-server"
追加して
npm run start
http://dackdive.hateblo.jp/entry/2016/04/13/123000#webpackconfigjs-の例
Elasticsearchことはじめ
仕事でElasticsearch使う必要があったので、GettingStarted!
これはなに?
分散型RESTful検索/分析エンジン
https://www.elastic.co/jp/products/elasticsearch
特徴
検索時は条件との完全一致ではなく"関連性が高いもの"を返す
http://gihyo.jp/dev/serial/01/js-foundation/0008
インストール
rpm -ivh https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.1.rpm chkconfig --add elasticsearch service elasticsearch start
基本操作
https://www.elastic.co/guide/en/elasticsearch/reference/5.2/getting-started.html
起動確認
curl -X GET http://localhost:9200 { "name" : "Ovee1U6", "cluster_name" : "elasticsearch", "cluster_uuid" : "_-CFvUxgRFy_4Q4lwKWMjw", "version" : { "number" : "5.2.1", "build_hash" : "db0d481", "build_date" : "2017-02-09T22:05:32.386Z", "build_snapshot" : false, "lucene_version" : "6.4.1" }, "tagline" : "You Know, for Search" }
インデックスの登録
curl -X PUT http://localhost:9200/customer?pretty { "acknowledged" : true, "shards_acknowledged" : true }
インデックス一覧
curl -X GET http://localhost:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open customer nXJXYUdyRpG_yxh-qTp7_w 5 1 0 0 650b 650b
ドキュメント登録
curl -X PUT http://localhost:9200/customer/external/1?pretty -d ' { "name": "John Doe" } '
インデックス/タイプが未作成の場合は一緒に作成される。
ID未指定の場合はPOSTメソッドを指定する。
ドキュメント確認
curl -X GET http://localhost:9200/customer/external/1 { "name": "John Doe" }
インデックス削除
curl -X DELETE http://localhost:9200/customer?pretty { "acknowledged" : true }
更新操作
変更
curl -X POST http://localhost:9200/customer/external/1/_update?pretty -d ' { "doc": {"age": 20} } '
ageカラムがある場合は上書き、ない場合は追加される。
他のカラムに影響はない。
メソッドはPUTではなくPOSTなのに注意。
スクリプト使った変更
curl -X GET http://localhost:9200/customer/external/1?pretty -d ' { "script": "ctx._source.age += 5" } '
ドキュメント削除
curl -X DELETE http://localhost:9200/customer/external/1?pretty
一括登録
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty&pretty' -H 'Content-Type: application/json' -d' {"index":{"_id":"1"}} {"name": "John Doe" } {"index":{"_id":"2"}} {"name": "Jane Doe" }
検索&集計
テストデータ登録
curl -X POST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json" curl http://localhost:9200/_cat/indices?v
サンプルjsonはここから
https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json
ファイル名の前に@をつける必要がある。
書き方1
curl -XGET 'localhost:9200/bank/_search?q=*&sort=account_number:asc&pretty' { "took" : 83, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1000, "max_score" : null, "hits" : [ { "_index" : "bank", "_type" : "account", "_id" : "0", "_score" : null, "_source" : { "account_number" : 0, "balance" : 16623, "firstname" : "Bradshaw", "lastname" : "Mckenzie", "age" : 29, "gender" : "F", "address" : "244 Columbus Place", "employer" : "Euron", "email" : "bradshawmckenzie@euron.com", "city" : "Hobucken", "state" : "CO" }, "sort" : [ 0 ] }, ... ] } }
q=* -> すべてを指定
sort=account_number:asc -> ソート指定
書き方2
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "sort": [ { "account_number": "asc" } ] } '
取得件数指定
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "sort": [ { "account_number": "asc" } ], "from": 10, "size": 10 } '
取得カラム指定
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "_source": ["account_number", "balance"] } '
完全一致検索
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match": { "address": "mill" } } } '
bool queryを用いた複数条件指定
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ], "filter": { "range": { "balance": { "gte": 20000, "lte": 30000 } } } } } } '
集計
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" } } } } '
aggs は aggregations(集計) の略。
SQLでいうとこんな感じ。
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
集計(平均値を出す)
curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword", "order": { "average_balance": "desc" } }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } } '
ざっとこんな感じで。
JavaScript(ES5)でクラスベースっぽくオブジェクト思考する
JavaScript(ES5)でクラスベースっぽくオブジェクト思考したかったので簡単な書き方をメモ。
var MyObject = function(a){ // アクセサっぽく this.a = a; // privateメソッドっぽく var privateFunction = function(){ alert('private function! arg is ' + a); } // publicメソッドっぽく var publicFunction = function() { alert('public function! arg is ' + a); } this.publicFunction = publicFunction; }; // 使い方 var obj = new MyObject("hoge"); obj.a // => "hoge"; obj.a = "fuga"; obj.a // => "fuga"; obj.publicFunction(); // => public function! arg is fuga
WindowsでAndroid開発環境を整える
仕事でAndroidアプリを扱うことになったけど、開発環境構築で色々とハマった。同じことを繰り返さないように設定メモを残しておく。
インストール
JDK
ここからダウンロードしてインストールする。
http://www.oracle.com/technetwork/jp/java/javase/downloads/index.html
AndrodiStudio
ここからダウンロードしてインストールする。
https://developer.android.com/studio/index.html
JDKの参照設定
AndroidStudioがJDKを参照できるように設定する。
Gitの設定
AndroidStudioは内部でgitコマンドを打つっぽい。コマンドプロンプトでgitコマンドが使えるように設定する。Cygwinっ子の僕はこんな感じで。
http://kinosuke.hatenablog.jp/entry/2016/12/02/151109
開発チュートリアル
Googleから初心者向けのチュートリアルが公開されている。ありがたい。
https://developer.android.com/training/basics/firstapp/index.html
AARファイルの作り方&取り込み方
Googleにドキュメントがある。ありがたい。
https://developer.android.com/studio/projects/android-library.html
なお、AARファイルを取り込むときに modules:aarファイル名 とすると、modulesディレクトリの下にモジュールが保存されるみたい。
実機テスト
こちらをご参考に。
https://blog.codecamp.jp/android_test
コマンドプロンプトでCygwinのシェルを使う
DLLコピー
C:\app\cygwin\bin\cygwin1.dll
を
C:\Windows\System32
配下にコピーする。
最後に
再度ログインする。これで使える。
※CygwinはC:\app\以下にインストールされている前提。
※参照:http://news.mynavi.jp/articles/2013/11/25/zerokaracygwin/