としたにあんの左脳

備忘録です.

fluentdでerror="argument out of range"というエラー

nginxからltsvでログはいてtd-agentでltsvで受けようとしたら,

error="argument out of range”

というエラーがでた.

2013-11-15 00:28:05 +0900 [warn]: "time:15/Nov/2013:00:28:05 +0900\thost:xxx.xxx.xxx.xxx\tforwardedfor:-\treq:GET /foo/bar HTTP/1.1\tstatus:304\tsize:0\treferer:http://xxx.xxx.xxx.xxx/foo/bar\tua:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36\treqtime:0.000\tvhost:xxx.xxx.xxx.xxx" error="argument out of range"

confファイルは以下のようにしていた.

<source>
  type tail
  format ltsv
  path /var/log/nginx/access.log
  tag test.nginx.log
  pos_file /tmp/nginx.pos
</source>

原因は,time_formatを書いていなかったこと.正しくは,

<source>
  type tail
  format ltsv
  time_format %d/%b/%Y:%H:%M:%S %z
  path /var/log/nginx/access.log
  tag test.nginx.log
  pos_file /tmp/nginx.pos
</source>

supervisordのstartsecs

supervisordのstartsecsって具体的に何なんだということで,以下の設定で設定でsupevisorを使ってプロセスを起動してみる.プロセスの起動時間をいじってみて,実験してみる.

supervisor.d/demo.ini

[program:demo]
command=python /home/vagrant/test.py
process_name=%(program_name)s
numprocs=1                   
autostart=true               
user=vagrant
redirect_stderr=true         
stdout_logfile=/var/log/supervisor/demo.log
stopsignal=INT               
startsecs=5

これ→stratsecs=5

実験

sleepして終了するプログラム,home/vagrant/test.pyをsupervisorから動かしてみる.

その1

import time
time.sleep(6)
print "finish!"

起動後6秒経って終了.

supervisor> status
demo                             EXITED     Nov 01 02:46 AM

その2

import time
time.sleep(4)
print "finish!"

起動後4秒経って終了.

supervisor> status
demo                             BACKOFF    Exited too quickly (process log may have details)

結果

startsecsより早く終了したら異常終了,遅く終了したら正常終了と判断するみたいです.

ちなみに

import sys
import time
time.sleep(x)
print "finish!"
sys.exit(1)

exitcodeを0以外にしてあげると,BACKOFFでもEXITでも再起動はちゃんとしてくれた.(追記:autorestartをunexpectedにしていたからでした) confの設定の詳しい説明をしてくれているとことがありました。

vagrantでconfig.vm.network :private_networkがうまくいかない

vagrantを使っていまして,Vagrantfileの

  config.vm.network :private_network, ip: "192.168.33.10"

の行を有効にしてあげるといい感じになるっぽいので,やろうとしました.

うまくいきませんでした.ゲスト側で,

$ ifconfig

してみると,eth0loしかない...eth1がvagrantfileのprivate_networkに割り当てられるはずっ! ということは,eth1をどうにかしなきゃいけないということがわかりました.

そもそもVirtual Boxの設定が悪いのかと思って この辺 を参考にしてみましたが,適切に設定されている模様.

/etc/network/interfacesをみても,良き感じに設定されている模様.

$ sudo /etc/init.d/networking restart

してみる.

Cannot find device "eth1"

っていわれる.

(´・ω・`)

(このエントリー)http://mypace75.blog92.fc2.com/blog-entry-363.htmlと出会う.

$ lshw -C network

確かにeth2がある.これが原因か.

/etc/udev/rules.d/70-persistent-net.rules を良き感じにする.(eth2eth1に変更)

再起動したらeth1が出現した!

(追記) /etc/udev/rules.d/70-persistent-net.rulesの中身をすべて消してからboxを作り直すと,うまくいった.

Ubuntu Server 12.04 LTS のISOファイルからVagrantのBoxを作る

以下のダウンロードページからからUbuntu Server 12.04 LTSをダウンロードしてくる.

ubuntu server 12.04LTS

以下のサイトにしたがって,VirtualBoxの仮想環境へUbuntu Serverをインストールする.

Virtual Boxへのインストール

以下のサイトにしたがって,Box化する.

box作成

==注意点==

sudo: 端末 (tty) が存在せず、パスワードを尋ねる (askpass) プログラムが指定されていません.

ここ にあるように sudo visudo

%vagrant ALL=(ALL) NOPASSWD:ALL

を追記する(vagrantユーザがパスワードなしでsshできるようにする)

(追記) vagrant用の公開鍵autorized_keysに登録してあげなくてはいけません.

nginxのerror_logはformat指定できない.

nginxとかsupervisorとかDBのログをfluentdで一括管理したいなぁとおもったので,とりあえず 参考 にしたがって,nginxのログをltsv形式にしてみようとしたわけです.

環境は

  • ubuntu server 12.04 LTS

  • nginx 1.4.3

怒られる

nginx.confのログの部分をこんな感じにしてみました.

        log_format ltsv "time:$time_local"
                        "\thost:$remote_addr"
                        "\tforwardedfor:$http_x_forwarded_for"
                        "\treq:$request"
                        "\tstatus:$status"
                        "\tsize:$body_bytes_sent"
                        "\treferer:$http_referer"
                        "\tua:$http_user_agent"
                        "\treqtime:$request_time"
                        "\tvhost:$host";

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

nginx再起動!...動かない...

$ sudo nginx -t

してみると,

nginx: [emerg] invalid log level "ltsv" in /etc/nginx/nginx.conf:45
nginx: configuration file /etc/nginx/nginx.conf test failed

らしい....(´・ω・`)

Nginx-HttpLogModuleを見る限りででは,公式でサポートされてるっぽいよなぁ.

ログレベルを指定してみる

Is it possible to specify custom error log format in nginx? を見てみる.

ログレベルってのは[ debug | info | notice | warn | error | crit ] のどれからしい.

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

にして,テストしてみた.

nginx: [emerg] unknown log format "info" in /etc/nginx/nginx.conf:44

ぐぬぬ...

つまり,log_formatを指定したら,level入れろよ!って怒られて.level入れたらlog_format入れろよ!って怒られる.

わかったこと

色々やっててテストがパスした.

わかったことは...

  • access_logはlog_formatを指定する.

  • error_logはlog_levelを指定する.

nginx: [emerg] invalid log level "ltsv" in /etc/nginx/nginx.conf:45

エラーログにlog_formatは指定できない.

nginx: [emerg] unknown log format "info" in /etc/nginx/nginx.conf:44

アクセスログにlog_levelは指定できない.

ということみたいです.

参考ページとか,ちゃんとみると,access_logしか指定してませんね.

ちゃんと読むようにしないとなぁ.

nginxのエラーログはどういう風に管理しましょう.

dyld: Symbol not found: __cg_jpeg_resync_to_restart

ある日,Macで

$vagrant up

しようとしたら,こんなエラーがでた.

dyld: Symbol not found: __cg_jpeg_resync_to_restart
  Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib
  Expected in: /usr/local/lib/libJPEG.dylib
 in /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib

その他色々触ってたら,

$ open -a hogehoge

しても同じエラーがでた.

原因

libJPEG.dylib__cg_jpeg_resync_to_restartっていう関数を使用したいけど無いらしい.

原因は,homebrewでlibJPEGをインストールしちゃってたことみたい.

homebrewでインストールされるlibJPEG__cg_jpeg_resync_to_restartを持たない.

本来は/System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylibを使わなきゃいけないっぽい.

homebrewで入った/usr/local/lib/libJPEG.dylibを先に見つけてしまって,その結果,関数がなくてエラーみたいな感じ.

対策

$brew uninstall jpeg

これでうまくいかなかったら

 ln -s /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib /usr/local/lib/libJPEG.dylib

してあげたらいいと思う

submodule と subtree-merging

gitのsubmodulesubtree-mergingがどう違うか実験してみた.

やりかたは,calcモジュールとcalcモジュールを使うcomplicated_calcっていうプロジェクトを作る.

calcモジュールとcomplicated_calcプロジェクトは別のリポジトリで管理する.

submoduleとsubtree-mergingの両方を使ってモジュールを取り込んでみたり,Pullしたり,Pushしたりしてみる.


calcリポジトリを作る.

└─ calc
      └── __init__.py

__init__.pyの中身

class Calc(object):
    def plus(self, l, r):
        return l + r     
    def minus(self, l, r):
        return l - r

こんな感じ.

続いて,complicated_calcリポジトリを作る. calcモジュールを使いたい.

└── complicated_calc
    ├── main.py
    └── calc
        └── __init__.py

とりあえず main.pyの中身

from calc import Calc

def main():
    c = Calc()
    print c.plus(1, 1)
    print c.minus(10, 4)

if __name__ == "__main__":
    main()

超複雑!

ここで,calcモジュールをsubmoduleで使うか,subtree-mergingで使うかを検証.

とりあえず取り込んでみる.

submodule

参考

calcモジュールをサブモジュールとして追加する

$ git submodule add git@bitbucket.org:foo/calc.git calc

calcディレクトリ以下にcloneされてくる.

$ python mian.py 
2
6

複雑な計算ができた!!!

submodulesの差分

#     new file:   .gitmodules
#     new file:   calc

calcはバージョン管理される時には,ディレクトリだけ管理されて,中身は管理されない.

他のマシンでcloneした時は

$ git submodule init
$ git submodule update

をすると,.gitmodulesを見て,モジュールのcloneをしてくれる.

subtree-merging

参考

$ git remote add calc_remote git@bitbucket.org:foo/calc.git calc
$ git fetch calc_remote
$ git checkout -b calc_branch calc_remote/master

これで,現在のリポジトリcalc_branchにはcalcモジュールのファイルが,masterにはcomplicated_calcのファイルがある状態になる.

ここで,masterのサブディレクトリにcalc_branchを取り込む.

$ git read-tree --prefix=calc/ -u calc_branch

見事にcalcモジュールができた!

$ python main.py 
2
6

複雑な計算(ry

subtreeの差分

#    new file:   calc/.gitignore
#    new file:   calc/__init__.py

submoduleとは異なり,calcの中身もバージョン管理される.

公開されてるモジュールを使う場合など,自分のプロジェクトで手を加えることが無いなら,正直どちらでも大差ないと思う.(人様のモジュールを自分のリポジトリに入れるのもあれなんでsubmoduleを使うべきなんですかね)

Pullする

Calcクラスにmulメソッドを追加してみる. この変更をsubmoduleとsubtree-mergingでどうやって取り込むかを見てみる.

class Calc(object):
    def plus(self, l, r):
        return l + r
    def minus(self, l, r):
        return l - r
    def mul(self, l, r):
        return l * r

main.pyに追加

    print c.mul(3, 4)

submodule

git submodule foreach 'git pull origin master'

参考

calcディレクトリ内は親プロジェクトとは独立してバージョン管理されているので,これだけでpull作業は完了.

差分は

#    modified:   calc (new commits)

こんな感じになってる.

この段階で

$ git submodule update #前のリビジョンに戻ってしまう

すると,前のリビジョンのcalcにリバートされてしまう.

親プロジェクト側でcalcをコミットすると,そのコミットに記録されたcalcのリビジョンを使うようになる.

subtree-merging

$ git checkout calc_branch
$ git pull

ここでcalc_branchのCalcクラスはmulメソッドを持った状態になる.

$ git checkout master

この時点では,masterブランチのCalcクラスはmulメソッドを持たない.

$ git merge --squash -s subtree --no-commit calc_branch

これで,calc_branchmasterにマージされた.

差分は

#    modified:   calc/__init__.py

Pushする

親プロジェクトでCalcクラスの変更を行う.divメソッドの追加

class Calc(object):
    def plus(self, l, r):
        return l + r
    def minus(self, l, r):
        return l - r
    def mul(self, l, r):
        return l * r
    def div(self, l, r):
        return l / r

submodule

親プロジェクト内で

$ cd calc
$ 編集
$ git add .
$ git commit -m "added div"

これで,Pushしたらcalcリポジトリは更新される.calcディレクトリは親プロジェクトとは別にバージョン管理されているため.

親プロジェクトの差分は

#    modified:   calc (new commits)

親プロジェクトでもコミットして,使用するcalcのリビジョンを記録すれば完了.

subtree-merging

$ cd calc
$ 編集
$ calcの変更履歴をコミット

ここまでで,親プロジェクトのバージョン管理は完了.

calcのリポジトリに変更を反映しなければならない.

$ git checkout calc_branch
$ git merge --squash -s subtree --no-commit master

マージが終わったら,公開リポジトリにPushしてあげれば終わり! 割と簡単に差分が取り込めて感動!

ここまでやってみて

submoduleとsubtree-mergingの使い分け

ここに詳しい説明がある.

1回実験をしてみると,何を言っているのかわかる!

subtree-merging の方が良さげかなぁ