kidoOooOoooOOom

ゲーム開発やってます

nodeでファイルの拡張子を厳格に指定して読み込み

nodeのプロジェクトで、/lib/service/index.js などのファイルから、同ディレクトリ配下のjsファイルを一括してexportsさせるケースがある。例えば下記のようなコード。

var fs = require('fs');
var path = require('path');
var _ = require('lodash');

_.forEach(_.filter(fs.readdirSync(__dirname), function (name) {
  return ('index.js' !== name);
}), function (name) {
  var basename = path.basename(name, suffix);
  exports[basename] = require('./' + basename);
});

これでうまく動いていたが、ある日突然nodeが死亡するケースが起きた。
原因を調べてみると、この index.jsのexports処理で不正なファイルを読み込もうとして落ちていた。
この不正なファイルというのが、「hoge.js.swp」といった vim でファイルを開いた時に自動で作られるswapファイルだった。

というわけで、余計なファイルを読み込まないように pathモジュールのextname()関数を用いて厳格にファイル拡張子を指定すれば問題なくなった。

path.extname(filename) === .'js'

http://nodejs.org/api/path.html#path_path_extname_p

macのterminal.appを環境別に色分け設定して共有

tmuxで各環境(dev, stg, prdなど)別のコンソール設定を作成できたので、次は環境別にコンソールの色を変えてみたい。
Macのターミナルappの[環境設定]-[設定]で + を押して新規プロファイルを作成する。


適当にウインドウの色や大きさの設定をし、[シェル]の設定でtmuxを立ち上げるコマンドを実行するようにしておく。

このプロファイルをドラッグ&ドロップでデスクトップなどに保存し、ターミナルから

open 保存したファイル

を実行すると設定したターミナルプロファイルでtmuxが立ち上がる。

tmuxのconf

いくつかのtmux設定記事を参考にして、適当な設定を自分向けに書いたのでメモ。
https://github.com/kidooom/tmux/blob/master/.tmux.conf

よく使うキーバインドとしては、(prefixはCtrl+aに変更してます)
C-a ? : ヘルプ
C-a [0-9] : window移動
C-a o : pain移動
C-a x: pain終了
C-a - : 水平分割
C-a | : 垂直分割
C-a d: デタッチ
tmux a: 最後にデタッチしたセッションにアタッチ

tmuxとtmuxinatorで開発環境別のコンソール環境整備

dev環境で作業やログ調査をする際に、webサーバをsshで開いてlogをtailして dbサーバをsshで開いてlogをtailしてmanagerサーバを(略)するのが面倒なので、tmuxとtmuxinatorを使ってコマンド一発でこの環境が開くようにする。

  • tmuxのインストール
$ brew install tmux
  • tmuxinatorのインストール
$ gem install tmuxinator
$ echo ' [[ -s $HOME/.tmuxinator/scripts/tmuxinator ]] && source $HOME/.tmuxinator/scripts/tmuxinator ' >> ${HOME}/.bashrc
$ source ${HOME}/.bashrc

$ echo 'export EDITOR=/usr/bin/vim' >> ${HOME}/.bashrc
$ echo 'export SHELL=/bin/bash' >> ${HOME}/.bashrc
$ source ${HOME}/.bashrc

// 動作確認
$ mux doctor


tmuxinatorのプロジェクトを作成する

mux new hogehoge

実行すると $EDITOR に設定したエディタで ~/.tmuxinator ディレクトリ以下に作成された yml ファイルが開くので、下記のような設定をした。

# ~/.tmuxinator/hoge.yml

name: hoge
root: ~/

windows:
  - web:
      layout: main-vertical
      panes:
        - ssh $SSH_USERNAME@hogeweb
        - ssh $SSH_USERNAME@hogeweb -t tailf /var/log/error.log
        - ssh $SSH_USERNAME@hogeweb -t tailf /var/log/api.log
  - db:
      layout: main-vertical
      panes:
        - ssh $SSH_USERNAME@hogedb
        - ssh $SSH_USERNAME@hogedb -t mongo
  - redis:
      layout: main-vertical
      panes:
        - ssh $SSH_USERNAME@hogeredis

layoutなどは適当なので、今後調節していく。
このconfファイルを社内のリポジトリに登録しておけば、チーム内でコンソール環境を共有できて良さげ。


ターミナルマルチプレクサ tmux 入門

ターミナルマルチプレクサ tmux 入門

Jenkinsジョブをリモートからビルド実行

管理ツールなど外部サーバからJenkinsのジョブを実行したい場合、Jenkinsのジョブ設定にある下記のリモートビルドの設定を行えばOK.

後は、外部サーバから設定したtoken付随のURLを叩くとjobが実行される。

nodejsで文字コードがsjisのcsvを取得して出力

svnサーバにあがっているcsvファイルを、httpsで取得してごにょごにょ処理をする必要があったのでメモ。
最初、httpsモジュール使って書いてたけど、文字化けがどうしても解決できなくて request モジュールに変えて enconding = null のオプションを使ったら解決した(http clientライブラリの中でレスポンスをそのまま返してもらえるように)。
sjisの文字をutf-8に変換するのは、iconvモジュール、csvのパースは csv-parseというモジュールを使った。
また、普通にhttpsプロトコルでrequestを送信すると、UNABLE_TO_VERIFY_LEAF_SIGNATUREエラーが帰ってくるので、一旦無視するようにしている。

下記がサンプルコード。

var Iconv = require('iconv').Iconv;
var sjis = new Iconv('SJIS', 'UTF-8//TRANSLIT//IGNORE');
var csvParse = require('csv-parse');
var url = require('url');
var request = require('request');

// for avoid UNABLE_TO_VERIFY_LEAF_SIGNATURE error
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

var url = url.parse('https://svnhogehoge');

request({ url: url, encoding: null }, function (error, response, body) {
  if (!error && response.statusCode == 200) {
    body = sjis.convert(body).toString();
    csvParse(body, function(err, csvOutput) {
      console.log(csvOutput);
    });
  }
});

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)

mongodbでクエリログを全部みたい

setProfillingLevelを2にする。

$ mongo
> use myDb
switched to db myDb
> db.getProfilingLevel()
0
> db.setProfilingLevel(2)
{ "was" : 0, "slowms" : 1, "ok" : 1 }
> db.getProfilingLevel()
2
> db.system.profile.find().pretty()

これでquery log 見れる。
また、setProfillingLevelの第2引数で slow query の閾値を決める。

参考:
http://stackoverflow.com/questions/15204341/mongodb-logging-all-queries
http://docs.mongodb.org/manual/reference/method/db.setProfilingLevel/


MongoDBイン・アクション

MongoDBイン・アクション



追記
user_idや時間等でクエリを特定したい場合は下記のようなクエリで特定させればok

b.system.profile.find({"query.user_id":40447, "ts": {"$gt": ISODate("2015-05-27T12:18:35.435Z")}});