2013年12月29日日曜日

【Android】java.io.FileNotFoundException: [file_path] open failed: ENOENT (No such file or directory)

Android内でプロパティファイルを読み込む際にFileNotFoundExceptionとなった
原因は以下だった

is = new FileInputStream(new File(path));
↓
is = this.getClass().getClassLoader().getResourceAsStream(path);
としプロパティファイルを「src」直下に配置する

Androidでnew Fileから読み込むと自動的に先頭に「/」が付いてしまっているようでうまくプロパティファイルが読み込めていなかった

2013年12月28日土曜日

ニフティクラウドmobile backendでAndroid(Nexus7)にプッシュ通知を送ってみた

今回作成したソースコードは以下で公開しています

https://github.com/kakakikikeke/android-ncmb-sample

以下にポイントを紹介します

●事前にeclipseとADT(Android Developers Tool)をインストールします

●gcm.jarは以下からダウンロードできます
gcm.jarはすでに開発が停止しているGCM用のクライアントライブラリです
ニフティクラウドmobile backendではgcm.jarが必要なようです
https://code.google.com/p/gcm/source/browse/gcm-client/dist/gcm.jar?name=gcm-1.0.2
ダウンロードしzipファイルを解凍し、./gcm-client/dist/gcm.jarをlib配下にコピーしビルドパスを追加します

●ProjectNumber(SenderId)を取得します
https://cloud.google.com/console#/project/[project_number]
ソースコード内でSenderIdとして利用します

●GoogleAPIKeyの取得
https://cloud.google.com/console#/project/[project_number]/apiui/credential
にてAPIKeyを取得します
ニフティクラウドmobile backendのダッシュボードのアプリ設定 -> プッシュ通知で取得したAPIキーを記載します

●ニフティIDの取得
ニフティクラウドモバイルmobile backendの申し込みにはニフティが提供するIDが必要です
無料で取得できるのでニフティのポータルサイトから取得します
http://www.nifty.com/

●エミュレータでは起動しません
エミュレータには「deviceToken」という端末個別のIDが存在しないためエラーとなります
at com.google.android.gcm.GCMRegistrar.checkDevice(GCMRegistrar.java:98)
実機にアプリを直接インストールして確かめる必要があります

いろいろと方法はありますが、自分はgmailに添付してインストールしました
eclipse -> プロジェクトを右クリック -> Export -> Export Android Application -> デスクトップに保存 -> apkファイルをGmailに添付して送信 -> Android端末で送信したGmailを受信 -> apkファイルをクリック -> アプリをインストール

●USBデバッグモードをONにします
以下を参考にUSBのデバッグモードをONにします
http://kakakikikeke.blogspot.jp/2013/12/nexus7usb.html

●Nexus7用のUSBドライバをインストールします
以下を参考にUSBドライバをインストールします
http://kakakikikeke.blogspot.com/2013/12/windowsnexus7usb.html

●プッシュ開封通知を送信する場合の注意
onCreateメソッド内で NCMBAnalytics.trackAppOpened(getIntent()); を実行しますが左記が呼ばれる条件として
  1. プッシュ通知開封時にバックグラウンドでアプリが起動していないこと
  2. プッシュ通知開封時にバックグラウンドでアプリは起動しているがプッシュ開封時に起動するActivityと同一のActivityが起動していないこと
のどちらかを満たしている必要があります
プッシュ通知を開封した際にActivityを指定できるので開封専用のActivityを用意しておくと確実に送信できるかと思います

■参考サイト

2013年12月27日金曜日

【Windows】Nexus7のUSBドライバをインストールする方法

■環境
WindowsXP 64bit
Nexus7(2012年発売モデル)
ADT 20131030

■事前準備
事前にADT(Android Developer Tools)をインストール必要があります
以下を参考にADTをインストールしてください
http://kakakikikeke.blogspot.jp/2012/10/windows7eclipseandroid.html
今回紹介する記事ではADTのインストールディレクトリを「C:\myinstallprogram\adt-bundle-windows-x86_64-20131030」とします

■ドライバのインストール
1. SDK Managerを起動
SDK Manager.exe をダブルクリックして起動します


2. Google USB Driverをインストール
Google USB Driver のチェックボックスをONにして「Install packages...」をクリックします


次に同意画面が表示されますので「Accept License」をONにして「Install」をクリックします
あとはインストールされるのを待ちます
※スクリーンショットはインストール後になります

3. USBデバッグをONにする
Nexus7はデフォルトではUSBデバッグがONになっていません
以下を参考にUSBデバッグをONにしてください
http://kakakikikeke.blogspot.jp/2013/12/nexus7usb.html

4. Nexus7をUSBでPCに接続
ドライバがないと言われるのでパスを指定してPC上にあるファイルからドライバをインストールします
一覧または特定の場所からインストールするを選択します


次の場所を含めるにドライバのパスを入力します

C:\myinstallprogram\adt-bundle-windows-x86_64-20131030\sdk\extras\google\usb_driver
先ほどGoogle USB Driverをインストールしたの以下のパスが存在しています(インストールしていない状態だとパスが存在しません)
入力後に「次へ」とするとドライバのインストール開始されます

エラーなくインストールされればドライバインストール完了です

■動作確認
eclipseでアプリを実行するときに実機が選択できるかどうか確認します
実行するアプリの「Run Configurations」を開きTargetタブで「Always prompt to pick device」にチェックを入れApplyします


その後Runでアプリを実行すると接続されている実機デバイスの一覧を選択する画面が表示されればWindows上で実機が認識されています


あとは実機を選択してOKをクリックすれば実機上でアプリが動作します、アプリは自動でインストールされインストール後に自動で立ち上がります
もちろんlogcatにも操作している間ログが流れるようになります

■Tips
MTPドライバのインストール
http://emobile.jp/products/gl07s/driver.html

2013年12月26日木曜日

Nexus7でUSBデバッグモードを有効にする方法

設定 -> タブレット情報 -> ビルド番号 -> 7回タップ

すると開発者「開発者 向けオプション」が新たに設定メニュー内に表示されるので「USBデバッグ」という項目のチェックボックスをONにしてください

設定 -> ストレージ -> 右上のメニュー -> USBでパソコンに接続 -> 「メディアデバイス(MTP)」のチェックをはずし「カメラ(PTP)」のチェックをONにする

USBデバッグとMTPモードを共存させることはできません
なのでMTPをOFFにしてPTPをONにします

これでUSBで接続時にデバッグモードとして接続されるようになります

2013年12月20日金曜日

【Java,mongo】java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer

mongo側のデータが明示的にintで宣言されていないために発生しています
updateする際にNumberIntを使って明示的にintで値を登録します
db.hogeCollection.update({"_id":"abcdefg"},{$set:{"number":NumberInt(1000000000)}}, false, true);

2013年12月19日木曜日

ニフティクラウドRDBにZabbixのデータベースを移行してみた

■事前作業
Zabbixのインストール
バージョンは何でも大丈夫だと思いますが今回自分が試したバージョンは1.8.3です

■RDBの作成
  1. https://console.cloud.nifty.com/web/rdb を開きます
  2. 左メニューのDBサーバーを選択し「DBサーバー新規作成」をクリックします
  3. DBエンジン選択…お好きなバージョンを選択します(2013/12/18現在ではMySQLの「5.5.32」,「5.6.12」が選択可能です、今回は 5.5.32 を選択しました)
  4. 基本設定…DBサーバー名のみを入力します、今回他の機能(HAやディスク変更)は実施しないでいきます
  5. DB設定…DBの名前、DB用のユーザ名とパスワード、LISTENするポートを入力します
  6. オプション設定…自動バックは実施しないので何も変更しません
  7. 確認…内容を確認し作成するをクイックします

だいたい30分から40分くらいでDBサーバーの作成が完了します

■DBファイアウォールの編集
作成したDBサーバーに対して既存のニフクラ上のサーバーが通信できる必要があります
作成したDBサーバーにはデフォルトFWが設定されておりそのFWに対してルールを追加する必要があります
デフォルトではルールは存在していないためどこからもアクセスできない状態となっております
  1. 左メニューのDBファイアウォールを選択します
  2. default.[zone名]というファイアウォールができていると思いますのでチェックボックスをクリックしプルダウンから「DBファイアウォールグループ編集」を選択します
  3. ルールを追加できるダイアログが表示されますので先ほど作成したDBサーバーがLISTENするポートに対して既存のサーバのからのアクセスを許可します
  4. 許可の設定はIPアドレスを直接設定するか、既存のFWグループを選択します

これでファイアウォールの設定は完了です

■RDBへの接続テスト
作成したDBサーバーへのアクセスが完了していると思いますので確認してみます
mysql -u [username] -p [dbname] -h [rdb_ip_address]
[username], [dbname], [rdb_ip_address] の部分にはDBサーバー作成時に設定したユーザ名、DBの名前、DBサーバーのIPアドレスを入力します
DBサーバーのIPアドレスはコントロールパネルのDBサーバー一覧で確認することができます
グローバル、プライベート両方が表示されているのでアクセスどちらかを入力します
(DBサーバーへのアクセスなので基本はプライベートになるかと思います)
パスワードの入力を求められますので、これもDBサーバー作成時に設定したパスワードを入力します

これで接続できるはずです、「show database」等でDBサーバー作成時に設定したDB名が存在していることを確認します
テーブルは1つも作成させれていません
ここで接続できない場合はFWの設定が怪しいのでFWやiptablesの設定を確かめてみてください

■ZabbixDBのエキスポートとインポート
1. 既存サーバーからのエキスポート
cd /var/tmp
mysqldump -u root -p zabbix > zabbix.dmp

2. RDBで作成したDBサーバーへのインポート
mysql -u [username] -p -h [rdb_ip_address]
  mysql > create database zabbix;
cd /var/tmp
mysql -u [username] -p zabbix -h [rdb_ip_address] < zabbix.dmp

DBサーバーに接続して「zabbix」という名前のデータベースにデータが存在することを確認します

■ZabbixServerの設定変更
vim /etc/zabbix/zabbix_server.conf
DBUser=[username]
DBHost=[rdb_ip_address]
DBPassword=DBサーバー作成時に設定したパスワード

vim /etc/zabbix/zabbix.conf.php
$DB["USER"] = '[username]';
$DB["SERVER"] = '[rdb_ip_address]';
$DB["PASSWORD"] = 'DBサーバー作成時に設定したパスワード';

/etc/init.d/zabbix-server restart
エラーなく再起動できればOKです

■動作確認
ZabbixのWebUIから確認します
テンプレートを一つ追加してzabbix.hostsテーブルにに指定した名前のテンプレートのレコードが追加されていることを確認します
ex) select * from hosts where host='test-template';

以上でニフティクラウドRDBへのZabbixDBの以降は完了です

●トラブルシューティング
ERROR 1129 (00000): Host 'xxx.xxx.xxx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
mysqladminコマンドが上記のせいでそもそも実行できないので自分は再起動するしかなったです。。。
何か別の方法があるのだろうか

Cannot connect to the database. Exiting...
ZabbixServerのログに出力されていました、これはzabbixの設定ファイルがうまく設定できていなかったために発生していました

2013年12月17日火曜日

fluentd+elasticsearch+kibana3をやってみた

■環境
CentOS 5.9

elasticsearch 0.90.5
kibana3
fluentd 0.10.39
のインストールは事前済ませておいてください
今回は/var/log/messagesを解析してみたいと思います

■/etc/fluent/fluent.confの設定
1. ログ送信側(クライアント側)設定
vim /etc/fluent/fluent_elasticsearch_client.conf
<source>
  type tail
  format syslog
  path /var/log/messages
  tag log.messages
</source>

<match log.messages>
  type forward
  flush_interval 5s
  <server>
    name server_host_name
    host server_host_name
    port 24224
    weight 60
  </server>
</match>

2. ログ受信側(サーバ側)設定
vim /etc/fluent/fluent.conf
<source>
  type forward
  port 24224
</source>

<match log.messages>
  index_name messages
  logstash_format true
  type elasticsearch
  host server_host_name
  port 9200
  include_tag_key true
  tag_key _key
  flush_interval 10s
</match>
include_tag_key を true にするとelasticsearchにログを突っ込む際にmatchに合致したタグ情報を自動で付与してくれます

■fluent-plugin-elasticsearchのインストール
fluent-gem install fluent-plugin-elasticsearch

■各種デーモンの起動
1. elasticsearch起動
elasticsearch -f
2. kibana3起動(apache起動)
service httpd start
3. サーバ側fluentd起動
fluentd
4. クライアント側fluentd起動
fluentd --conf /etc/fluent/fluent_elasticsearch_client.conf

各種起動が完了しエラーが表示されていないければkibana3を開きデータが入っていることを確認します
kibana3 サンプル画像


■Tips
syslogをelasticsearchに送る場合は素直に「format syslog」を使って下さい
format /^(?<timestamp>\w{3} \d{2} \d{2}:\d{2}:\d{2}) (?<host>[^ ]*) (?<body>.*)$/
こんな感じで自分でパースしてelasticsearchに渡すとうまくtimestampをパースしてくれません
以下にあるようにmappingを手動で設定してもダメでした
なので「format syslog」を使うのが定石になるのですが、ポイントとしてはサーバ側のfluent.confに「logstash_format true」を必ず入れて下さい
これを入れることでdynamic mappingもちゃんと働くので自分でmappingを登録する必要がなくなります

●elasticsearchにindexの登録とmappingの設定(今回は実施しなくて大丈夫です)
1. indexの登録
curl -X POST 'http://server_host_name:9200/messages'
サーバ側のfluent.confに記載してあるindex_nameと同じindexを作成してください

2. mapping登録
curl -X PUT http://server_host_name:9200/messages/fluentd/_mapping -d '{
  "app_log" : {
    "properties" : {
      "host" : {"type" : "string"},
      "body" : {"type" : "string"},
      "timestamp": {"format" : "MMM dd HH:mm:ss","type" : "date", "locale" : "ja_JP"}
    }
  }
}'

2013年12月12日木曜日

【AWS】SimpleQueueServiceクイックスタート for PHP(composer編)

■環境
CentOS 5.9 64bit
PHP 5.3.3

■クイックスタート
1. AWS SDK for php for composer をダウンロードする
以下の記事を参考に事前にcomposerをインストールしてください
http://kakakikikeke.blogspot.jp/2013/12/phpcomposer.html

touch composer.json
vim composer.json
{
    "require": {
        "aws/aws-sdk-php": "2.*"
    }
}

composer install
以下のようになれば完了です(デバッグログにデフォルトで色付けされているのがいいです)
WARNING: channel "pear.php.net" has updated its protocols, use "pear channel-update pear.php.net" to update
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing symfony/event-dispatcher (v2.4.0)
    Downloading: 100%

  - Installing guzzle/guzzle (v3.7.4)
    Downloading: 100%

  - Installing aws/aws-sdk-php (2.4.11)
    Downloading: 100%

symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
aws/aws-sdk-php suggests installing doctrine/cache (Adds support for caching of credentials and responses)
aws/aws-sdk-php suggests installing ext-apc (Allows service description opcode caching, request and response caching, and credentials caching)
aws/aws-sdk-php suggests installing monolog/monolog (Adds support for logging HTTP requests and responses)
aws/aws-sdk-php suggests installing symfony/yaml (Eases the ability to write manifests for creating jobs in AWS Import/Export)
Writing lock file

2. アクセスキーとシークレットキーの取得
https://portal.aws.amazon.com/gp/aws/securityCredentials
アクセスしawsのアカウントでログインします
取得したアクセスキー、シークレットキーは後で使いますので大切に補完しておいてください

3. サンプル実行ファイルを作成する
touch sample_sqs.php
vim sample_sqs.php
以下を貼り付けてください
<?php
require 'vendor/autoload.php';
use Aws\Sqs\SqsClient;

$client = SqsClient::factory(array(
  'key'    => 'your access key',
  'secret' => 'your secret access key',
  'region' => 'us-west-2'
));

echo 'ListQueues' . "\r\n";
$result0 = $client->listQueues(array(
  'QueueNamePrefix' => 'string',
));
$result0->get('QueueUrls');
var_dump($result0);

$result1 = $client->createQueue(array(
  'QueueName' => 'kaka_queue002',
  'Attributes' => array(
    'VisibilityTimeout' => '300',
  ),
));
$queueUrl = $result1->get('QueueUrl');
echo $queueUrl . "\r\n";

$result2 = $client->sendMessage(array(
  'QueueUrl' => $queueUrl,
  'MessageBody' => 'test message !',
  'DelaySeconds' => 0,
));

echo 'ReceiveMessage' . "\r\n";
$result3 = $client->receiveMessage(array(
  'QueueUrl' => $queueUrl,
  'MaxNumberOfMessages' => 10,
  'WaitTimeSeconds' => 20,
));
$body = $result3['Messages'];
echo $body[0]['Body']. "\r\n";
#var_dump($result3);

echo 'OK';
?>

リージョンはus-west-2(Oregon)にしていますので適宜変更して問題ございません
key と secret を取得したアクセスキーとシークレットキーで設定してください
基本的に結果は連想配列で返ってくるようなので、中身をvar_dumpメソッドで確認しながら目的のデータを取得する感じになるかと思います

php sample_sqs.php
とするとkaka_queue002に「test message !」というメッセージが送信され受信もされます

■参考

2013年12月11日水曜日

【PHP】composerのインストール方法

■環境
CentOS 5.9 64bit
PHP 5.3.3
composer 2013-12-06

■インストール
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/
cd /usr/local/bin
ln -s composer.phar composer

■バージョン確認
composer -V
Composer version 80499bb02418711b34bba59c1a6d8032429e5702 2013-12-06 12:32:19

あとはcomposer.jsonを作成し
composer install
とすればvendor配下にライブラリが追加されていきます
実行するphpのソースコード内では「vendor/autoload.php」をrequireするだけで自動でインストールしたライブラリが使えるようになります

2013年12月9日月曜日

puppetのインストールとサンプルの実行

■環境
CentOS 5.9
puppet 2.6.18 ( puppetd, puppetmasterd ともに同じバージョンです )

■インストール
yum -y install puppet
yum -y install puppet-server
※epelのリポジトリの登録が必要です

■puppetmasterdサーバ起動
vim /etc/puppet/puppet.conf
main 部分に以下を記載
※servernameにはpuppetmasterdが動作するサーバのホスト名またはIPアドレスを入力してください
server = servername
puppetmasterd --no-daemonize --d
  • --no-daemonizeを指定することでフォアグランドで動作します
  • -dはデバッグログを出力するためのオプションです
  • Ctrl + c で停止できます
  • バックグラウンドで実行した場合に停止する際はkillで停止してください

■マニュフェストファイルの作成
上記puppetmasterdは起動したまま以下の作業を続けます
今回はhostsファイルの権限を変更するサンプルを実行してみます
touch /etc/puppet/manifests/site.pp
emacs /etc/puppet/manifests/site.pp
file { '/etc/hosts':
    owner => 'root',
    group => 'root',
    mode  => 644,
}
※.ppファイルの名前が「site」でないとうまく動作しない可能性があります

■puppetdクライアント実行
実行する前にhostsファイルの権限を777とかに変更しておいてください
実行後にhostsファイルを確認すると権限が644になっているかと思います
puppetd --server [servername] --no-daemonize -d
※[servername]にはpuppetmasterdを起動しているサーバのIPもしくはホスト名を入力してください

■参考

●いろんなresourceを使ったサンプルマニュフェスト
1. ファイルを作成する
file { 'test.txt':
  path => '/var/tmp/test.txt',
  ensure => present,
  mode => 644,
  content => "これはテスト用のファイルです",
}
pathはフルパスでファイル名まで記載します
mode, contentは記載しなくてもOKです、ない場合は空のファイルを作成するだけです
contentに記載の内容はファイルに書き込まれます、日本語も使えます

2. コメントアウト
先頭に「#」をつけることで1行のコメントアウト、「/* ... */」で囲うことで複数行のコメントアウトができます

3. chkconfigをON/OFFにする
service { 'tomcat':
  enable => false,
}
/etc/init.dで管理されている必要があります

4. puppetをpuppetmasterdなしに単独で実行する方法
puppet apply localhost.pp -d
とするとpuppetmasterdが起動していなくてもクライアント単独でpuppetを実行させることが可能です
「-d」を付けることでデバッグログを出力することができます
chefでいうところにchef-soloにあたるのかなと思います

5. serviceの起動と停止をする方法
service { 'tomcat':
  #ensure => 'running',
  ensure => 'stopped',
}

6. マニュフェスト内で変数を使用する方法
$process_name = 'tomcat'
$file_name = 'test2'

service { $process_name:
  #enable => false,
  enable => true,
  ensure => 'running',
  #ensure => 'stopped',
}

file { "/var/tmp/$file_name":
  ensure => 'directory',
}
変数を文字列と結合して参照する場合はダブルクオートで囲うことで変数が展開されます


2013年12月7日土曜日

【Mac】ターミナルの色をきれいに表示するSolarizedをインストール、設定する方法

■環境
OS X 10.8.5

■インストール
1. ターミナルから実施
ターミナルを開きます
cd /var/tmp
git clone https://github.com/tomislav/osx-terminal.app-colors-solarized solarized
git clone https://github.com/altercation/vim-colors-solarized.git
mkdir -p ~/.vim/colors
mv vim-colors-solarized/colors/solarized.vim ~/.vim/colors
touch ~/.vimrc
syntax enable
set background=dark
colorscheme solarized
let g:solarized_termcolors=256

sudo port -v selfupdate
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"
※上記のbrewをインストールするためには事前にJavaとruby、XcodeCommandLineが必要です
brew install coreutils
※全然関係ないですが、インストール時にビールのアイコンがターミナル上に表示されます
git clone https://github.com/seebi/dircolors-solarized.git dircolors-solarized
vim ~/.bash_profile
alias ls='gls --color=auto'
eval $(gdircolors /var/tmp/dircolors-solarized/dircolors.ansi-universal) 
source ~/.bash_profile

2. ターミナルの設定
ターミナル -> 環境設定 -> プロファイル一覧の一番した歯車マークから「読み込む」を選択
先ほどターミナルからの操作でダウンロードした/var/tmp/solarized/Solarized Dark.terminal と Solarized Light.terminalを読み込みます
起動 -> 起動時に開く -> Solarized Darkを選択
ターミナルを再起動するとSolarizedのカラーテーマのターミナルが立ち上がり「ls」および「vim」でカラー付けがされているかと思います

以上で設定は完了です

2013年12月5日木曜日

Zabbixでmongoの監視やってみた

■環境
CentOS 6.2
Zabbix 2.0.3
mongoDB 2.4.5
php 5.3.3
※事前作業としてZabbixサーバのインストールとmongoDBのインストールは完了しているものとします
※今回の対応自体ではzabbix_agentd自体は使用しません、また作業はほぼ全てZabbixサーバ上で実施します、zabbix_agentdはインストールしてあっても問題はないです

■モジュール追加(Zabbixサーバ上で実施上で実施)
yum -y install php-devel php-pear gcc make
pecl install mongo
vim /etc/php.ini
以下を追記
extension=mongo.so

vim test.php
以下を追記
<?php
new MongoClient("mongodb://dbserver:27017");
?>

php test.php
でエラーとならなければOK
エラーとなる場合はmongoのプロセスが上がっているかやACLの設定(FWやiptables)を見なおして下さい

■スクリプト追加(Zabbixサーバ上で実施)
mkdir -p /opt/zabbix/share/zabbix/externalscripts/
cd /opt/zabbix/share/zabbix/externalscripts/
wget http://mikoomi.googlecode.com/svn/plugins/MongoDB%20Plugin/mikoomi-mongodb-plugin.php
wget http://mikoomi.googlecode.com/svn/plugins/MongoDB%20Plugin/mikoomi-mongodb-plugin.sh
chmod 755 mikoomi-mongodb-plugin.*
chown zabbix:zabbix mikoomi-mongodb-plugin.*
※どうやらchefインストールした環境だと上記のパスに置く必要があるようです(すいません、先に書いておくべきでしたが今回Zabbiサーバのインストールはchefで実施しています

■スクリプト修正(Zabbixサーバ上で実施)
以下は実施しないでもいいかもしれません、自分の環境では実施しないと動作しなかったので備忘録がてら記載しておきます
  1. mikoomi-mongodb-plugin.sh内で「shift」コマンドを実行している行を削除(shiftすることで引数がうまくphpに渡せませんでした)
  2. mikoomi-mongodb-plugin.php内541行目あたりでzabbix_senderを呼んでいるパスをフルパスに変更(フルパスで呼んでいないのでPATHを通していない場合はzabbix_senderをフルパスで呼ぶように変更してください)

■Zabbixサーバへのテンプレート登録(Zabbixサーバ上で実施)
http://mikoomi.googlecode.com/svn/plugins/MongoDB%20Plugin/MongoDB_Plugin_template_export.xml
をダウンロードしてZabbixのWebUIからテンプレートを登録します
インポートできたテンプレートに対して監視対象のホストを追加します
テンプレートの設定からマクロタブを選択して
{$HOSTNAME}、{$PORT}、{$SERVER}
を追加します
{$HOSTNAME}と{$SERVER}に監視するmongoDB側のIP(またはホスト名)を入力し
{$PORT}にLISTENしているmongoのポートを入力します(test.phpでテストしたときのポート番号を入力します)

■ACL設定(ZabbixサーバとDBサーバ)
Zabbixサーバ -> tcp/27071 -> mongoDB
上記を満たすFWやiptablesの設定をしてください
replicaSet構成の場合は各ポートも通信できるようにしたほうがいいかもしれません
※公式だとmongosのプロセスを監視すれば良いと書いてあるようでしたが私はreplicaSetのPRIMARYポートを監視するようにしました(なのでfail overした場合は監視するポート変更する必要があります。。。)

■参考

以上で設定自体は完了です
あとは自分が設定した際のトラブルシューティングを記載しているので参考にしてみてください

●全体的な動きの流れ
全体的な動きとしては
シェル実行 -> php実行 -> mongoからデータ取得 -> zabbix_sender で 127.0.0.1にデータ登録
という流れとなっています
なのでzabbix_agentを使えないで監視ができるわけです
zabbix_senderは /tmp/mikoomi-mongodb-plugin.php_dbserver.data のデータを送っています
ちなみにphp内で送信しているzabbix_senderのコマンドは以下でした
/opt/zabbix/bin/zabbix_sender -vv -z 127.0.0.1 -i /tmp/mikoomi-mongodb-plugin.php_dbserver.data
上記を実行してエラーとならないことを確認する必要もあります
zabbix_sender自体のログも/tmp配下にあります

●トラブルシューティング
うまく取得できない場合はホストのアイテムの設定からMiscellaneous: Data Collectorのステータスを有効にしてください
その後zabbix_server.logを見るとシェルを実行した結果のログがでるのでそれを元に修正します

配置したシェルを直接叩いて動作を確認することもできます、以下は実行サンプルです
sh /opt/zabbix/share/zabbix/externalscripts/mikoomi-mongodb-plugin.sh -h dbserver -p 27071 -z dbserver
phpは以下のように実行します
php /opt/zabbix/share/zabbix/externalscripts/mikoomi-mongodb-plugin.php -h dbserver -p 27071 -z dbserver
シェルやphpをrootで実行した場合は/tmp配下のログの権限に気をつけてください
ログの所有者がrootになってしまいzabbixから実行した場合はzabbixユーザで実行することになりログへの権限がなくなりスクリプトがうまく動かなくなりますのでrootで直接スクリプトを実行した場合は権限の書き換えかファイルの削除をしてください

「timeout while executing a shell script」が出力される場合はzabbix_server.confのTimeoutの値を30に変更しzabbix_serverを再起動してください

「No Data Received in 5 minutes」でアラートが常にあがってしまう場合はトリガーの設定でnodateの引数を800くらいあげてください
どうやらZabbixトラッパーでのデータの取得が10分おきになっているのでデフォルトの300秒(5分)だと常にアラートがあがってしまうようです

最終的にzabbix_server.logに
8967:20131204:171621.274 item [db_server:mikoomi-mongodb-plugin.sh[-h {$SERVER} -p {$PORT} -z {$HOSTNAME}]] became supported
的なログが出力されれば完了です

2013年12月3日火曜日

apacheでリアルタイムに秒間リクエスト数を取得する方法

apachetopというコマンドを使用することでリアルタイムの値を取得することが可能です
apachetopはデフォルトではインストールされていませんので
yum -y install apachetop
でインストールしてください(CentOS 6.3の場合)
インストールしたらapacheのログを引数として以下のように実行します

apachetop -T 1 -d 1 -f /var/log/httpd/http+access.log

apachetopはアクセスログを元に現在のリクエスト数を取得することができます
「-T」はログ監視する間隔でこれを1秒にすることで1秒間の間に流れたログを元にアクセス数を算出してくれます

サーバ上のリソース状況を監視するtopコマンド同様で標準出力に出続けます
なのでリダイレクトなどを使ってファイルに出力したり、awkやgrepと組み合わせてコマンドを実行するたびに値を取得するのはちょっと難しいかもしれないです
監視データを永続的に持っておきたい場合にはzabbixを使ったapacheの監視方法を別記事で紹介してますのでそちらを参照してください
http://kakakikikeke.blogspot.jp/2013/06/chefzabbixapache.html

2013年11月27日水曜日

【python】easy_installでインストールしたパッケージの一覧を確認する方法

python2.6の場合

cat /usr/lib/python2.6/site-packages/easy-install.pth

2.4の場合は「python2.6」->「python2.4」に変更すれば確認可能です

easy_installはpythonのバージョンごとにインストールしているパッケージを管理しているため、2.6でインストールしたパッケージは2.4でもインストールしないと使用することはできません

【PHP】GoogleCustomSearchAPIを使って検索結果を取得する

<?php
require_once "HTTP/Client.php";

# define
$api_key = 'Please input your api_key';
$custom_search_key = 'Please input your google custom search id';
$input_file = 'keyword_list.csv';
$result_file = 'result.tsv';
$sleep_time = 10;

$csv = array();
$fp= fopen($input_file, "r");
$fp2 = fopen($result_file, "w");

while (($data = fgetcsv($fp, 0, ",")) !== FALSE) {
  $csv[] = $data;
}
fclose($fp);
#var_dump($csv);

$client =& new HTTP_Client();
for ($i = 1; $i < count($csv); $i++) {
  $keyword = $csv[$i][1];
  $urlStr  = "https://www.googleapis.com/customsearch/v1?key=" . $api_key . "&cx=". $custom_search_key . "&q=" . urlencode($keyword) . "&alt=json";
  #echo $urlStr;
  fwrite($fp2, $i . "\t" . $keyword . "\t");

  $client->get($urlStr);
  $response = $client->currentResponse();
  $json = json_decode($response['body'], true);
  if (array_key_exists('items', $json)) {
    $items = $json['items'];
    for ($j = 0; $j < count($items); $j++) {
      #var_dump($items);
      $items_info = $items[$j];
      fwrite($fp2, str_replace(array("\r\n","\r","\n"), '', $items_info['title']) . "\t" . str_replace(array("\r\n","\r","\n"), '', $items_info['snippet']) . "\t");
      #echo 'title : ' . str_replace(array("\r\n","\r","\n"), '', $items_info['title']) . "\r\n";
      #echo 'snippet : ' . str_replace(array("\r\n","\r","\n"), '', $items_info['snippet']) . "\r\n";
    }
  }
  fwrite($fp2, "\r\n");
  sleep($sleep_time);
}
fclose($fp2);
?>

■準備
1. APIキーの取得
GoogleCloudConsole (https://cloud.google.com/console) にアクセスしてAPIキーを取得します
Registered appsから取得します
取得したAPIキーは上記ソースコード中の「$api_key」の部分にセットします

2. カスタム検索エンジンIDの取得
Googleカスタム検索 (https://www.google.co.jp/cse/all) にアクセスして検索エンジンIDを取得します
検索エンジンがない場合は Add から検索エンジンを作成してください
ポイントとしては検索するサイトに「www.google.co.jp/*」を入力し
作成後の編集画面で検索サイトの部分を「追加したサイトを重視して、ウェブ全体を検索する」を選択します
検索エンジンが作成できたら
基本 -> 詳細 -> 検索エンジンID をクリックしてIDを取得します
取得した検索エンジンIDは上記ソースコード中の「$custom_search_key」の部分にセットします

3. HTTP_Clientのインストール
pear install HTTP_Client
※pear自体のインストールに関しては→http://kakakikikeke.blogspot.jp/2013/11/phppearphp.html

2013年11月26日火曜日

pythonのバージョンをアップデートするとyumが動かなくなるときの対応

■環境
CentOS 5.9
python 2.4.3 -> 2.6.8

■エラー内容
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

No module named yum

Please install a package which provides this module, or
verify that the module is installed correctly.

It's possible that the above module doesn't match the
current version of Python, which is:
2.6.8 (unknown, Nov 7 2012, 14:47:45)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-52)]

If you cannot solve this problem yourself, please go to
the yum faq at:
http://wiki.linux.duke.edu/YumFaq

■対処方法
emacs /usr/bin/yum
上記のファイルの先頭部分を変更
#!/usr/bin/python
↓
#!/usr/bin/python2.4
明示的に2.4のバージョンのpythonを使うように変更しましょう

2013年11月24日日曜日

【PHP】csvに書かれているキーワードの一覧からGoogle検索を実施するスクリプト(非推奨)

<?php
require_once './simple_html_dom.php';

$csv = array();
$input_file = 'keyword_list.csv';
$fp= fopen($input_file, "r");
$result_file = 'result.csv';
$fp2 = fopen($result_file, "w");
$search_result_count = 10;
$sleep_time = 10;

while (($data = fgetcsv($fp, 0, ",")) !== FALSE) {
  $csv[] = $data;
}
fclose($fp);

#var_dump($csv);

for ($i = 1; $i < count($csv); $i++) {
  $keyword = $csv[$i][1];
  $urlStr  = "http://www.google.co.jp/search?num=$search_result_count&q=" . urlencode($keyword) . '&ie=utf-8&oe=utf-8';
  $html = file_get_html($urlStr);

  $lcnt = 1;
  fwrite($fp2, $i . ',' . $keyword . ',');
  $result = '';
  foreach($html->find('h3[class=r]') as $e) {
    $result_title = preg_replace('/<a href=(.+?)>/', '', $e->outertext);
    $result_title = preg_replace('/<b>|<\/b>|<\/a>|<h3 class="r">/', '', $result_title);
    $result_title = preg_replace('/<\/h3>/', '', $result_title);
    $result = $result . $result_title . ',';
    $lcnt++;
  }
  $result = rtrim($result, ",");
  fwrite($fp2, $result . "\r\n");
  sleep($sleep_time);
}
fclose($fp2);
?>

simple_html_dom.php は
http://sourceforge.net/projects/simplehtmldom/files/
からダウンロードして上記スクリプトと同じディレクトリ内において実行ください

ちなみにこのスクリプト内で実施している検索はGoogle Search APIを使用しておらず頻繁に利用するとGoogleからBANされ、結果がすべて302にリダイレクトされます
大量に使用する場合はちゃんとGoogle Search APIを利用してください

2013年11月23日土曜日

elasticsearch+kibana3で /var/log/messages を簡単に解析してみた

■事前準備

■/var/log/messagesを解析
1. 解析スクリプトを使ってelasticsearchにデータを投入
以下のスクリプトを適当な場所に配置し実行します
事前に「elasticsearch -f」でelasticsearchを起動しておいてください
#!/bin/sh

count=1
cat /var/log/messages | while read line
do
  date=`echo ${line} | awk '{print $1,$2,$3}'`;
  hostname=`echo ${line} | awk '{print $4}'`;
  message=`echo ${line} | awk '{for(j=5;j<NF;j++){printf("%s ",$j)}print $NF}'`;
  timestamp=`date "+%Y-%m-%d %H:%M:%S"`
  #echo ${date} ${hostname} ${message}
  curl -X POST http://localhost:9200/system/message/${count} -d "{\"date\":\"${date}\",\"hostname\":\"${hostname}\",\"message\":\"${message}\",\"@timestamp\":\"${timestamp}\"}"
  echo ${count};
  count=`expr ${count} + 1`;
done
内容としては/var/log/messagesをdateとhostnameとmessageに分割してelasticsearchにPOSTしています
/var/log/messages全行を処理してデータを投入します

2. @timestampの_mappingを変更する
@timestampフィールドは「type」が「date」でなければいけません
上記スクリプトで投入したデータは「type」が「string」になってしまっているので「date」に変換してあげます
現状のmappingは以下のコマンドで取得できます
curl -X GET http://localhost:9200/system/message/_mapping

elasticsearchにはmappingというメタ情報を持っており、これをPUTで更新してあげることで type を変更します
また、mapping は一回データを投入したあとではすでにmappingが確定してしまっているため一度削除してから更新する必要があります

curl -X DELETE http://localhost:9200/system/message/_mapping
curl -X PUT http://localhost:9200/system/message/_mapping -d '{"message": {"dynamic":"true","properties": {"@timestamp" :{"type":"date", "format":"YYYY-MM-dd HH:mm:ss"},"date":{"type":"string"},"hostname":{"type":"string"},"message":{"type":"string"}}}}'
※タイムスタンプ形式で「T」や「Z」が入ってしまうパターンがありますが入れないほうがいいです、うまくelasticsearchがパースできずグラフがうまく表示されないことがあります

これでelasticsearch側のデータ登録は完了です
あとはkibana3で可視化してみます

3. kibana3でグラフ作成
http://localhost:9200/kibana
にアクセスし画面下部の「Blank Dashboard」をクリックします


ダッシュボードの設定画面が表示されるので画面右上のダッシュボード設定ボタンをクリックします


Generalからダッシュボードの名前を設定します


Indexから登録したデータのindexのみを表示するようにします(デフォルト「_all」なのでそれでも問題ないです)


次にダッシュボードに戻り右下にある「ADD A ROW」をクリックします
グラフを表示するための行を追加していきます


行を追加できるダイアログが表示されますので title に「pie」「histogram」「table」の3つを入力して Create Row をクリックします


各行にパネルを追加していきます
画面の構成は「ダッシュボード」->「ロウ」->「パネル」の順で構成されています
先ほど3つのロウを追加したので1つ目の「pie」からパネルを追加していきます
ダッシュボードの左にある「Add panel to empty row」をクリックします


パネルを追加するダイアログが表示されますのでプルダウンから「pie」を選択し Add Panel をクリックしてパネルを追加します


同様に「histogram」「table」をプルダウンから選択して追加していきます
先ほどと違うのはspanの欄に 12 を入力して横いっぱいのパネルを作成します




追加後に以下のようになればOKです
事情により_idと_indexのみ表示しています
カラムの絞り込みはtableパネルで左の項目から表示したい項目にチェックをすると絞り込みが可能です


これで最低限のグラフの作成は完了です
肝はヒストグラムで@timestampがうまくparseできないとグラフが描画されません
また、ヒストグラムで表示しているのは「指定した期間内でヒットするデータの数」になるので細かく時系列ごとに見たい場合(秒間リクエスト数など)は範囲を1mや5m等の短い時間で指定することで見たいグラフが表示されるかと思います
今回使用したデータテストデータなのです、timestampも適当ですが、実際にはログのtimestampをうまくparseしてそれをelasticsearchに登録する感じになると思います

※今回elasticsearchに投入したデータだと以下のようなヒストグラムを見ることができるようになります
Interval:1s Line, Points, Stack:ON



■Tips
作成したグラフを保存する場合は右上のフロッピーのようなアイコンから「Save」->「Advanced」->「Set as my home」をクリックすると次回ダッシュボードアクセス時に今回作成したダッシュボードが表示されます
違いダッシュボードを作成したい場合は「Clear my home」をクリックすると次回アクセス時に初回画面が表示されるようになります

2013年11月22日金曜日

【emacs】php-modeのインストール方法

■環境
CentOS 5.9
GNU Emacs 23.4.1

■インストール手順
http://downloads.sourceforge.net/project/php-mode/php-mode/1.5.0/php-mode-1.5.0.tar.gz?r=http%3A%2F%2Fphp-mode.sourceforge.net%2F&ts=1384992949&use_mirror=jaist
tar zvxf php-mode-1.5.0.tar.gz
cd ~/.emacs.d/site-lisp/
mv /var/tmp/php-mode-1.5.0 .

emacs ~/.emacs
以下を追記する
(load-file "~/.emacs.d/site-lisp/php-mode-1.5.0/php-mode.el")
(push '("\\.php$" . php-mode) auto-mode-alist)

■動作確認
emacsを再起動(Ctrl+x, Ctrl+cで抜けて起動するだけ)
emacs sample.php
とすると以下のような感じで色付けされます

Githubで公開しているchefのemacs cookbooksも対応しました
https://github.com/kakakikikeke/cookbooks-emacs

2013年11月20日水曜日

【AWS】SimpleQueueServiceクイックスタート for PHP(pear編)

■環境
CentOS 5.9 64bit
PHP 5.3.3
pear 1.9.4

■クイックスタート
1. pearでawsのphp用のファイルをダウンロードしてくる
pear install Services_Amazon_SQS-0.3.0
WARNING: channel "pear.php.net" has updated its protocols, use "pear channel-update pear.php.net" to update
downloading Services_Amazon_SQS-0.3.0.tgz ...
Starting to download Services_Amazon_SQS-0.3.0.tgz (34,121 bytes)
.........done: 34,121 bytes
downloading HTTP_Request2-2.1.1.tgz ...
Starting to download HTTP_Request2-2.1.1.tgz (99,151 bytes)
...done: 99,151 bytes
install ok: channel://pear.php.net/HTTP_Request2-2.1.1
install ok: channel://pear.php.net/Services_Amazon_SQS-0.3.0
※このときpearのバージョンが1.9.2以上ないとERRORとなりインストールできませんのでpearのバージョンが古い方はpearのバージョンをアップグレードしてください

2. アクセスキーとシークレットキーの取得
https://portal.aws.amazon.com/gp/aws/securityCredentials
アクセスしawsのアカウントでログインします

vim /usr/cfg/Services_Amazon_SQS/sqs.ini
に取得したアクセスキーとシークレットキーを記載します
※「sqs」とコマンドを打つとエラー文中に設定ファイルを記述する箇所が表示されますので上記の設定ファイルがない場合は自分の環境の設定ファイルの場所を確認してください
※アクセスキーとシークレットキーを設定後に「sqs」と打つと指定できるコマンドの一覧が表示されます

3. コマンドから実行する
pear経由で実行するとbash上でコマンドとして実行しSQSにアクセスすることができるようになります
デフォルトのリージョンは「us-east-1」に作成されるようです
・キューを作成する
  sqs create kaka_queue001
・キューの一覧を取得する
  sqs list
・メッセージを送信する
  echo "test" | sqs send http://queue.amazonaws.com/000000000000/kaka_queue001
・メッセージを受信する
  sqs receive http://queue.amazonaws.com/000000000000/kaka_queue001
※MaxNumberOfMessagesは指定できないので1つずつ受信する
・キューを削除する
  sqs delete http://queue.amazonaws.com/000000000000/kaka_queue001
※000000000000の部分はアカウントごとに設定されているIDを入力します
※Queue URLは「sqs list」でも取得で取得できた値をそのまま入力すればOKです

4. ソースコードから実行する
vim sqs_test.php
<?php
  require '/usr/share/pear/Services/Amazon/SQS/Queue.php';

  $accesskey='your accesskeyId';
  $secretkey='your secretkeyId';
  $accountId='your accountId ex) 000000000000';
  $queueName='kaka_queue001';
  $queueURL='http://queue.amazonaws.com/' . $accountId . '/' . $queueName;

  // send message
  $sqs=new Services_Amazon_SQS_Queue($queueURL, $accesskey, $secretkey);
  try {
    $sqs->send('test message');
  } catch (Services_Amazon_SQS_Exception $e) {
    trigger_error($e->getMessage());
  }
?>

php sqs_test.php
とするとkaka_queue001に「test message」というメッセージが送信されます

どうやら最近はpearでやるよりかはcomposerでやるほうがモダンらしいので
次回はcomposerでもやってみたいと思います

■参考

2013年11月19日火曜日

【PHP】pearをバージョンアップする方法

■バージョンアップ手順
wget http://pear.php.net/go-pear.phar
php go-pear.phar
※以下バージョンアップ実行時の標準出力

Below is a suggested file layout for your new PEAR installation. To
change individual locations, type the number in front of the
directory. Type 'all' to change all of them or simply press Enter to
accept these locations.

1. Installation base ($prefix) : /usr
2. Temporary directory for processing : /tmp/pear/install
3. Temporary directory for downloads : /tmp/pear/install
4. Binaries directory : /usr/bin
5. PHP code directory ($php_dir) : /usr/share/pear
6. Documentation directory : /usr/docs
7. Data directory : /usr/data
8. User-modifiable configuration files directory : /usr/cfg
9. Public Web Files directory : /usr/www
10. Tests directory : /usr/tests
11. Name of configuration file : /etc/pear.conf

1-11, 'all' or Enter to continue:
Beginning install...
Configuration written to /etc/pear.conf...
Initialized registry...
Preparing to install...
installing phar:///var/tmp/go-pear.phar/PEAR/go-pear-tarballs/Archive_Tar-1.3.11.tar...
installing phar:///var/tmp/go-pear.phar/PEAR/go-pear-tarballs/Console_Getopt-1.3.1.tar...
installing phar:///var/tmp/go-pear.phar/PEAR/go-pear-tarballs/PEAR-1.9.4.tar...
installing phar:///var/tmp/go-pear.phar/PEAR/go-pear-tarballs/Structures_Graph-1.0.4.tar...
installing phar:///var/tmp/go-pear.phar/PEAR/go-pear-tarballs/XML_Util-1.2.1.tar...
install ok: channel://pear.php.net/Archive_Tar-1.3.11
install ok: channel://pear.php.net/Console_Getopt-1.3.1
install ok: channel://pear.php.net/Structures_Graph-1.0.4
install ok: channel://pear.php.net/XML_Util-1.2.1
install ok: channel://pear.php.net/PEAR-1.9.4
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

The 'pear' command is now at your service at /usr/bin/pear

** The 'pear' command is not currently in your PATH, so you need to
** use '/usr/bin/pear' until you have added
** '/usr/bin' to your PATH environment variable.

Run it without parameters to see the available actions, try 'pear list'
to see what packages are installed, or 'pear help' for help.

For more information about PEAR, see:

http://pear.php.net/faq.php
http://pear.php.net/manual/

Thanks for using go-pear!

上記でpearのバージョンアップは完了です
1-11の数字の入力を求められるところはとりあえずEnterを入力すれば問題ありません
実際にinstallされたpearのバージョンを確認する方法は「pear list」でPEARのバージョンを確認してください
2013/11/19現在でバージョンアップした際のPEARのバージョンは「1.9.4」でした

■Tips(バージョンアップできないときによく出るエラー)
pear upgrade PEAR-1.5.4
ERROR: unable to unpack /tmp/tmpACbIi9/Structures_Graph-1.0.4.tgz
http://stackoverflow.com/questions/8571925/upgrading-pear-on-x86-64-gnu-linux

2013年11月16日土曜日

【Java】HashMapを「=」でコピーすると参照元のマップオブジェクトのデータも削除される

まずはサンプルソースと結果を御覧ください

■サンプルソースコード1
package com.kakakikikeke.sample.test;

import java.util.HashMap;

public class Test {

 public static void main(String[] args) {
  HashMap<String, String> map1 = new HashMap<String, String>();
  map1.put("key1", "value");
  map1.put("key2", "value");
  System.out.println("* before");
  for (String key: map1.keySet()) {
   System.out.println(key);
   System.out.println(map1.get(key));
  }

  HashMap<String, String> map2 = map1;
  map2.remove("key1");
  System.out.println("* after");
  for (String key: map1.keySet()) {
   System.out.println(key);
   System.out.println(map1.get(key));
  }
 }

}

■結果1
* before
key2
value
key1
value
* after
key2
value

■サンプルソースコード2
package com.kakakikikeke.sample.test;

import java.util.HashMap;

public class Test {

 public static void main(String[] args) {
  HashMap<String, String> map1 = new HashMap<String, String>();
  map1.put("key1", "value");
  map1.put("key2", "value");
  System.out.println("* before");
  for (String key: map1.keySet()) {
   System.out.println(key);
   System.out.println(map1.get(key));
  }

  HashMap<String, String> map2 = new HashMap<String, String>(map1);
  map2.remove("key1");
  System.out.println("* after");
  for (String key: map1.keySet()) {
   System.out.println(key);
   System.out.println(map1.get(key));
  }
 }

}

■結果2
* before
key2
value
key1
value
* after
key2
value
key1
value

■考察
サンプルソースコード1では作成したmap1を「=」でmap2に代入しています
そのあとにmap2に対してremoveを実行します
すると、代入したmap1からデータが削除されていることがわかります

これを回避する方法としてサンプルソースコード2を見て下さい
ソースコード2で緑色が付いている部分でmap1からmap2にオブジェクトをコピーしています
ソースコード1では単純に「=」で代入してましたが、今度はHashMapのコンストラクタの引数としてmap1を指定しています
単純にmap2のオブジェクトを新規で作成しているだけですが、サンプルソースコード2のほうはmap2側のデータをremoveしてもmap1側には影響していません

上記を踏まえてこの現象をまとめると
  • ソースコード1はmap1とmap2が同じデータを見ているためmap1側にも影響があった
  • ソースコード2はmap1と全く同じデータを持つmap2オブジェクトを新規で作成したためmap1側には影響がなかった
ということになります

考えてみると当たり前かもしれませんが、HashMapをコピーしたいという場合に結構陥りそうな罠なのかと思いました

2013年11月15日金曜日

【AWS】SimpleQueueServiceクイックスタート for Java

■環境
Windows7 64bit
eclipse 3.7(Indigo)
Java 1.7.0_03
AWS SDK for Java 1.6.5

■クイックスタート
1. AWS のSDKをダウンロードする
http://aws.amazon.com/jp/tools/
ダウンロードしたSDKでSQSも使えるようになっています

2. eclipseでJavaプロジェクトを作成する
特に設定する項目はなし
プロジェクト名を適当に設定して作成する
プロジェクトを作成した各種ライブラリを配置するようのディレクトリ「lib」を作成する

3. ダウンロードしたzipファイルを解凍しjarファイルをeclipse上のプロジェクトにコピーする
解凍したファイルの中に「lib/aws-java-sdk-1.6.5.jar」があるのでそれを先ほど作成したeclipseのプロジェクト「lib」ディレクトリにコピーする
同様に「third-party/*」内のファイルをすべてプロジェクトの「lib」配下にコピーする

4. ビルドパスを通す
先ほどlib配下に配置したaws-java-sdk-1.6.5.jarとthird-party配下のjarファイルをビルドパスに追加します
プロジェクトを右クリックして「ビルド・パス」->「ビルド・パスの構成」から追加するか
jarファイルを右クリックし「ビルド・パス」->「ビルド・パスに追加」を実行してビルドパスを追加します

5. サンプル実行クラスと設定ファイルのコピー
解凍したファイルの中に「samples/AmazonSimpleQueueService/SimpleQueueServiceSample.java」をeclipseプロジェクトの「src」内にコピーします
解凍したファイルの中に「samples/AmazonSimpleQueueService/AwsCredentials.properties」をeclipseプロジェクトの「src」内にコピーします

6. アクセスキーとシークレットキーの取得
https://portal.aws.amazon.com/gp/aws/securityCredentials
アクセスしawsのアカウントでログインします
プロジェクト内にコピーしたAwsCredentials.propertiesを開き「accessKey」「secretKey」に上記で取得したアクセスキーとシークレットキーを入力します

7. サンプルクラスの実行
eclipseからSimpleQueueServiceSample.javaを実行します
キューの作成 -> キュー一覧の表示 -> メッセージの送信 -> メッセージの受信 -> メッセージの削除 -> キューの削除
という順にリクエストが呼ばれていきます

以上でサンプルの実行は完了です
サンプルクラスに対して適宜コメントを入れることでキューの削除やメッセージの削除を抑制することが可能です

■Tips
プロキシの設定
sqsオブジェクトを作成している部分で以下のようにconfを設定しオブジェクト生成するように変更します
ClientConfiguration conf = new ClientConfiguration();
conf.setProxyHost("proxyhostname");
conf.setProxyPort(8080);
AWSCredentialsProvider credentialsProvider = new ClasspathPropertiesFileCredentialsProvider();
AmazonSQS sqs = new AmazonSQSClient(credentialsProvider, conf);

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
がcloudfrontとs3の部分で警告表示されますが特にsqsでは問題なくキューやメッセージは作成、送信されます

リクエストの投げ方は基本的に「hogehogeRequest」クラスのオブジェクトを作成しパラメータ等を設定した上でAmazonSQSのhogehogeメソッドで呼び出す感じになります
ex) SetQueueAttributesを呼び出す場合
SetQueueAttributesRequest sqaRequest = new SetQueueAttributesRequest();
sqaRequest.setQueueUrl(queueUrl);
HashMap attributes = new HashMap();
attributes.put("DelaySeconds", "900");
sqaRequest.setAttributes(attributes);
sqs.setQueueAttributes(sqaRequest);

2013年11月14日木曜日

Jenkinsからメモ帳を開く方法

■概要
Jenkinsのビルドでnotepad.exe等を指定するとバックグランドでメモ帳が開かれて見ることができません
今回はJenkinsがバッググラウンドで開いたnotepad.exeを見る方法を紹介します

■環境
Windows7 64bit
Jenkins 1.538

■設定方法
1. スタート -> すべてのプログラム -> 管理ツール -> サービスからJenkinsサービスのプロパティを開く
(ローカルコンピュータ)Jenkinsのプロパティダイアログが表示されます
ログオンタブを開いてローカルシステムアカウントの「デスクトップとの対話サービスに許可」をONにします
以下のようにしてください

2. Jenkinsを再起動します
先ほどの管理ツールから「サービスの再起動」を実施すればOKです

3. メモ帳を開くビルドの作成
適当に作成します
ポイントとしては「Windowsバッチコマンドの実行」ビルドを以下のように設定します

作成できたらそのままビルドを実行します

4. 対話型サービスの検出からメッセージを表示する
ビルドを実行するとタスクバーに「対話型サービスの検出」というタスクが出現します
ここで「メッセージの表示」をクリックします

5. バックグラウンド側の状況を確認する
するとJenkinsが実行されているバックグラウンドの状況を確認することができます
別のデスクトップが立ち上がるイメージでそこに実行したメモ帳が開かれていることが確認できると思います
※スクリーンショットが取れなかったので実写になっています

このデスクトップ上で開かられているメモ帳を閉じるとJenkins側のジョブも終了します
ジョブはnotepad.exeが開かれている間実行され続けますので、上記画面で閉じるかtaskmgrからプロセスを強制的に停止する必要があります

いちおうこれでJenkinsからメモ帳や他のGUI系のアプリを開くことができるようになりましたが、
毎回、対話型サービスの検出を表示するとしないと表示されないので結構微妙かもしれません
他のやり方があるといいのですが。。

■参考サイト

2013年11月13日水曜日

Windows上のJenkinsでjavaが実行できない

前回
http://kakakikikeke.blogspot.com/2013/08/windowsjenkins.html
の記事でWindows上で実行する際の注意事項を紹介しましたが
どうやらJenkinsが読みにいく環境変数が「ユーザ環境変数」ではなく「システム環境変数」を読みに行っているようです
原因としては環境変数周りなのですが、今回は現象として以下のようなことが確認できました

■現象
  • Jenkinsをローカルシステムではなくログインしているユーザのプロセスとして立ち上げてもシステムの環境変数を読みに行っている
  • そのためJenkins上でユーザ環境変数が有効になっていない
  • システムの環境変数のPATHにJAVA_HOME変数を使ってPATHが設定してあった
  • システムの環境変数側にJAVA_HOME変数の定義がなかった
  • なのでシステム環境変数側のPATHにjavaコマンドまでのパスがうまく通っていなかった

■対策
  • システム環境変数側のPATHに設定してあるをjavaコマンドまでのパスをJAVA_HOME変数で参照するのではなくちゃんとパスを入力してあげた(C:\からはじまるパス)
  • 上記はシステム環境変数側にJAVA_HOME変数を追加してあげても対応可能かと思われます
  • Jenkinsを再起動し、うまくjavaコマンドが動作することを確認した(再起動しないと環境変数も反映されないようです)

Windows上でJenkinsを動かす場合は環境変数周りで苦しめられそうです
環境変数にスペースとか入っているとそれが原因でうまく変数が読み込めないみたいなこともありそうです。。。

2013年11月12日火曜日

mongodumpとmongorestoreのメモ

■環境
mongo 2.4.6
CentOS 5.9 64bit

■ダンプ
  • mongodump
  • すべてのDB情報をダンプする、ポートは27017、ダンプ元ホストはlocalhost、ユーザ認証なし
  • mongodump --db test1
  • test1のDB情報をダンプする、ポートは27017、ダンプ元ホストはlocalhost、ユーザ認証なし
  • mongodump --db test1 --port 30717
  • test1のDB情報をダンプする、ポートは37017、ダンプ元ホストはlocalhost、ユーザ認証なし
  • mongodump --db test1 --port 30717 --host localhost -u guest -p hogehoge
  • test1のDB情報をダンプする、ポートは37017、ダンプ元ホストはlocalhost、ユーザguestでhogehogeパスワードで認証

■リストア
  • mongorestore
  • ./dump配下のすべてのDBをリストアする
  • mongorestart --db test1 ./dump/test1
  • test1 DBに対して./dump配下のtest1 DBをリストアする
  • mongorestore -d [db_name] -c [collection_name] [bson_file_name].bson
  • 特定のコレクションだけを指定してリストアする「--port」を指定することも可能

■Tips
mongoは起動中でもダンプ、リストアをすることが可能

2013年11月11日月曜日

kibana3をインストール

■環境
CentOS 5.9
elasticsearch 0.90.5
kibana 3.0.0

■前提条件
前回elasticsearchのインストールを実施しました
http://kakakikikeke.blogspot.jp/2013/10/elasticsearch.html
今回はelasticsearch用のWebUI「kibana3」をインストールし簡単な使い方を紹介します

またWebサーバが必要なのでapacheを事前にインストールしておいてください

■kibana3インストール
wget https://download.elasticsearch.org/kibana/kibana/kibana-3.0.0milestone4.tar.gz
tar xvzf kibana-3.0.0milestone4.tar.gz

mv kibana-3.0.0milestone4 /usr/local/
cd /usr/local
ln -s kibana-3.0.0milestone4/ kibana
cd /usr/local/kibana
vim config.js
elasticsearch: "http://"+window.location.hostname+":9200",
※elasticsearchが起動しているホスト名とポート名に変更がある場合は上記を変更します
cd /var/www/html
ln -s /usr/local/kibana kibana

service httpd start
elasticsearch -f
※httpdでkibanaが起動します、elasticsearchも起動します

■動作確認
http://localhost/kibana/
にアクセスしダッシュボードにアクセスできることを確認します

ダッシュボードの右側にいろいろと説明があります、要約すると
  • ブラウザは最新版のchrome or firefox or safari か IE9以上を使って下さい
  • webserverをインストールしてください
  • Elasticsearchをインストールしてください
  • WebサーバとElasticsearchが同じホストにインストールされているのであれば特に設定は不要です
  • 違うサーバで動作している場合はconfig.jsの設定を変更してください
  • Logstashユーザの場合は専用のUIがすでに用意されています
  • そうじゃない場合は以下の3つから選択してください
  • サンプル用のダッシュボード
  • データだけ読み込んだダッシュボード
  • 何も設定していないダッシュボード
サンプル用のダッシュボードを選択するとすでにElasticsearchに入れたデータをグラフで見ることができます

とりあえず今回はインストールまでなので次回あたりでオリジナルのグラフが見れるようにしてみたいと思います

■参考サイト

2013年11月9日土曜日

【mongo】DBアクセス時に認証を追加する方法

■環境
mongo 2.4.6
CentOS 5.9 64bit

■認証設定
とりあえず通常通りmongoを起動します
mongod

今回はtest1というDBに対して権限を追加します
use test1
db.addUser({user:"guest",pwd:"hogehoge",roles:["dbAdminAnyDatabase","readWrite"]})
test1というDBに対してのみ認証設定を実施するので他のDBに対しては操作することはできません
なので他のDBに対しても操作したい場合はtest1にした処理を同様に他のDBにも実施する必要があります

「dbAdminAnyDatabase」はroles名です、指定できるrole名の一覧は以下を参照してください
http://docs.mongodb.org/manual/reference/user-privileges/

adminコレクションに対しても認証させたい場合は「use admin」を実施したあとで同様のaddUserを実施してください
よくわからないのですが、ユーザ追加のクエリは若干時間がかかります(と言っても数秒です)

■認証ありでのmongod起動
一旦、mongodを停止します( kill or db.shutdownServer() )
認証モードでmongodを起動します
mongod --auth
これで認証が必要な状態でmongodが起動しました

再度、mongoでログインして「show dbs」等を実行しようとすると以下のエラーになるかと思います
Tue Nov  5 12:48:22.596 listDatabases failed:{ "ok" : 0, "errmsg" : "unauthorized" } at src/mongo/shell/mongo.js:46

先ほど追加したユーザでmongoにログインしてみます
mongo test1 -u guest -p hogehoge
show collections を実行するとコレクションの一覧を確認することができると思います
show dbs は他のDBに触ることになるのでエラーとなります
test1 配下のコレクションに関してはfindやsaveができます
ログインの方法はdb.auth("guest", "hogehoge")でも可能です

■参考サイト

2013年11月6日水曜日

【PHP】pearというphpのパッケージマネージャを使ってみた

■環境
CentOS 5.9 64bit
PHP 5.3.3
pear 2.3.0
apache 2.2.3

■pearインストール
yum -y install php-pear
  • pear list # インストールしてあるモジュールを表示
  • pear list-all # インストール可能なモジュールを一覧表示する
  • pear install hoge  # hogeパッケージをインストールする
  • pear uninstall hoge # hogeパッケージをアンインストールする
  • pear version # pearのバージョンを確認する
pear だけ入力すると各種指定できるコマンドを確認できます

■pear動作検証
※apache上でphpが動作する環境が構築されている前提とします

vim sample.php
以下の内容をコピーします
<?php
    echo "check_ip <br>";
    require_once "/usr/share/pear/Net/CheckIP.php";
    $isip = Net_CheckIP::check_ip("192.168.1.1");
    if ($isip) {
        echo "$isip";
    }
?>

mv sample.php /var/www/html
「/var/www/html」はapacheのDocumentRootです、必要に応じて適宜変更してください
まずこの状態で
http://hostname/sample.php
にアクセスすると「check_ip」とだけブラウザに表示されると思います
つまり、Net_CheckIP::check_ip関数がうまく呼べていない状態で最後の「check ip finish」が表示されていない状況となります

次にpearでモジュールをインストールしてみます
pear install Net_CheckIP
インストール後に再度
http://hostname/sample.php
にアクセスすると
「1 check ip finish」と追加で表示されていることがわかるかと思います
つまり、Net_CheckIP::check_ip関数がうまく呼べたことを意味しておりpearによりインストールしたモジュールが有効になっていることがわかります

ついでにcheck_ipで指定している「192.168.1.1」を「192.168.1.a」とかにして
再度ブラウザで確認すると今度は「check ip finish」の部分だけが表示され if の中に入っていないことがわかります

■Tips
pearでinstallすると.phpファイルがローカルマシン上にダウンロードされるようでデフォルトのままだと「/usr/share/pear」配下に配置されるようです
今回はyumでpearをインストールしたのでyumでインストールした場合は上記パスになると思われます

モジュールの読み込みは「require_once」を使っていますが「require」でも問題ないです

■参考サイト

2013年11月5日火曜日

【Linux】コマンドの結果がファイルにリダイレクトされない場合の対処方法

pear > pear_help.txt 2>&1

「2>&1」を末尾に追加してあげます
上記はpearでコマンドに引数が表示されない場合ヘルプが表示されるのですが、「2>&1」がないとうまくファイルに結果をリダイレクトできません
これはpearのヘルプが標準エラーとして出力されているせいで、「2>&1」を付与しない場合は標準出力のみをリダイレクトするので
ファイルには何も出力されない状況となります

「2>&1」は標準エラーを標準出力に複製する命令になるので標準出力となった結果がファイルに出力されるようになります

2013年11月3日日曜日

Growlと連携してRedmineのチケットが自分に来た時に通知してくれるRubyスクリプト

https://gist.github.com/kakakikikeke/7289446

Gistでソースコードを公開しました
Rubyで作っています

■環境
Windows7 64bit
Ruby 2.0.0p195
Growl 2.0.9.1

■インストール方法
1. 事前準備

2. 必要なgemのインストール
コマンドプロンプトを開いて以下のコマンドを実行し必要なモジュールをインストールします
デフォルトでインストールされているモジュールもありますので必要に応じて実行してください
gem install json
gem install open-uri
gem install mail
gem install date

3. スクリプト設定
Gistからダウンロードしたcheck_ticket.rbをGrowlをインストールしたディレクトリに配置します
配置したcheck_ticket.rbに対して「rubyw.exe」で開くようにプログラムを紐付けます
※ruby.exeではなくrubyw.exeを紐付けてください、rubyw.exeを紐付けることで実行時にコマンドプロンプトを表示させないようにします

check_ticket.rbの以下の項目を設定してください
  • user_id・・・redmine上で管理されているユーザのIDを入力します、URLに表示される「query_id=」の数字を入力します
  • username・・・redmineにログインするユーザ名を入力します
  • password・・・redmineにログインするユーザのパスワードを入力します
  • redmine_hostname・・・redmineが動作しているドメインもしくはIPアドレスを入力します
  • redmine_port・・・redmineが動作しているポートを指定します、80番の場合も省略せずに入力してください
  • proxy_hostname・・・プロキシのホスト名またはIPアドレスを指定します(プロキシを利用する場合は23行目のopen_uriの部分のコメントアウトを切り替えてください)
  • proxy_port・・・プロキシが動作しているポート番号を入力します、80番の場面も省略せずに入力してください

4. Windowsタスクスケジューラの設定
タスクスケジューラを開き右上「タスクの作成」を選択します
名前、説明は適当に入力します(「Redmineチケット通知」とかにしておきましょう)
タスクの実行は「毎日」で設定します(あとで更に設定変更します)、間隔も1日で大丈夫です
タスクの実行は「プログラムの開始」を選択し、プログラムにダウンロードしてGrowlのインストールディレクトリに配置したcheck_ticket.rbを参照から選択します
そのまま確認画面にいってOKを押下してタスクを作成します

作成したタスクが一覧に表示されるのでプロパティを表示します
トリガータグから編集を選択し「トリガーの編集」ダイアログを表示します
繰り返し間隔を「1分間」に設定し、継続時間を「無期限」に設定します
繰り返し間隔はプルダウンに1分間というのがないのですが、5分間を選択したあとにプルダウンを編集して1に変更してください


これで設定は完了です
うまく動作しない場合はcheck_ticket.rbをデバッグしてエラーが出ていないか確認してください

■Tips
デバッグしたい場合は以下の内容のファイルをGrowlのインストールディレクトリに配置して実行してください
rubyの実行内容がコマンドプロンプトに表示されます
cd C:\Program Files (x86)\Growl for Windows
ruby check_ticket.rb

現状の設定だと過去5分間に更新されたチケットを通知します
なので1分毎に回るタスクだと一回の更新で通知が3から4件ほど来てしまいます
通知を減らしたい場合は時間をbefore_minute変数の時間を「60*5」ではなく「60*2」とかにしてください

2013年11月2日土曜日

Jakarta HTTPClientを使ってREST-APIのリクエストを送信してみた

https://github.com/kakakikikeke/java-http-client-sample

Gitでソースコードを公開しました
Javaで作っています
REST-APIで必要なGET,POST,PUT,DELETEのリクエストを送信することができます

2013年10月31日木曜日

mavenとtestngでJavaのテストコードをモダンに開発

■概要
rubyやpython, phpなどのスクリプト言語にあるパッケージ管理ツール「gem」「easy-install」「composer」などを使って
サーバサイド上で簡単にソースが書けちゃうってやつを頑張ってJavaでやるとこうなったというのを紹介します
頑張れば、できなくなないです。。。

■環境
CentOS 5.9 64bit
maven 3.1.0
Java 1.7.0_05
※Javaのインストールに関しては
http://kakakikikeke.blogspot.jp/2012/06/centosjenkinsjavatomcatantgit.html
※mavenのインストールに関しては
http://kakakikikeke.blogspot.jp/2013/10/maven.html

■開発
1. mvnプロジェクトを作成する
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.kakakikikeke.test -DartifactId=Sample_Test

2. testngをダウンロードする
vim pom.xml
<dependencies>...</dependencies>の間に以下を追記する
※記載したあ、とデフォルトで入っているJUnitのdependencyの記載を削除して大丈夫です
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.3.1</version>
  <scope>test</scope>
</dependency>
mvn clean
mvn compile

すると以下のローカルのリポジトリにパスにjarファイルがダウンロードされます
/root/.m2/repository/org/testng/testng/6.3.1/
※mvn clean と mvn compile はやらなくても記載して保存した段階で勝手にmavenがダウンロードしてきてくれます

3. テストケースを書く(サンプル)
vim src/test/java/com/kakakikikeke/test/AppTest.java
package com.kakakikikeke.test;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;

public class AppTest {

  @BeforeTest
  public void beforeTest() {
    System.out.println("beforeTest");
  }

  @AfterTest
  public void afterTest() {
    System.out.println("beforeTest");
  }

  @Test
  public void TestCase1() {

  }
}
と記載したら

mvn clean
mvn test-compile
mvn test

でtestngのテストが実行されます
あとはTestCase1に肉付けして行ったり、TestCase2を作成したりすれば一応「mvn」コマンドだけでテストケースを書いて実行することができます


とここまで環境が整っていざ開発となると、実は正直かなりめんどくさかったです。。。
以下、具体的にいけてない感じた点です
  • ライブラリを追加するときにいちいち maven repository から必要なライブラリを見つけてそのXML情報をpom.xmlに記載する必要がある
  • maven repository の検索性能がイマイチで自分が必要としているライブラリがなかなか見つからない
  • 全然関係ないライブラリを追加していることがある
  • mvn clean から test までの流れを毎回やるのが正直めんどくさい(シェルを一つ書いて一回でできるようにするとか独自のgoalを作るとかはありますが)
  • やっぱりJavaはサジェストがエディタににないと厳しい(このへんは emacs とかでもなんとかなりますが、準備が大変。。。)
といった印象を受けました
最終的にはあきらめて「mvn eclipse:eclipse」とかでeclipse形式に吐き出してeclipseにインポートして開発するのが一番楽なのかなと思ってしまった次第です
本当に枠組みだけ作るのであれば紹介した手順だけでもいいのかなーと思いました

2013年10月30日水曜日

【Windows7】デスクトップに通知できるgrowlをインストール

■概要
growl(ぐろーる)はMac用に作られたデスクトップ通知アプリです
今回はWindows7版のgrowlをインストールして通知テストを実施したいと思います

■growlのインストール
http://www.growlforwindows.com/gfw/
のサイトからWindows版のgrowlをダウンロードします
2013/10/25段階での最新版は2.0.9でダウンロードリンクは以下にありました


インストール時は特に何も気にすることなくNextと押していけば大丈夫です
デフォルトの設定だと「C:\Program Files (x86)\Growl for Windows」にインストールされるようです

■基本設定
まず、growlを起動します
起動するとタスクトレイにgrowlのアイコンが出現するのでダブルクリックで設定ダイアログを表示します
・General → Automatically start Growl at login にチェックをする
とりあえず上記のみ設定しました

次に、コマンドプロンプトを立ちあげて以下のように実行します
cd C:\Program Files (x86)\Growl for Windows
growlnotify.exe aaa
growlは基本的にコマンドから実行して使います
上記を実行するとデスクトップ上に通知が表示されると思います

そして、growlのApplicationタブを選択すると先ほど実行したコマンドがアプリケーションとして追加されます
通知のデザイン等を変更できるのでお好みに合わせて変更してください(任意)

とりあえずインストールとテスト通知は以上です
アプリを自分で追加することで独自の通知をすることは可能ですが、すでにたくさんのアプリがあるので以下から取得することも可能です
http://www.growlforwindows.com/gfw/apps.aspx

時間があったら独自の通知アプリでも作ってみたいと思います

2013年10月29日火曜日

【Zabbix】net.tcp.serviceを使う際の注意事項

■環境
CentOS 6.3 64bit
Zabbix 2.0.3

■注意事項
net.tcp.serviceはポートの状態を確認することができるキーです
LISTEN可能な状態なら1が返ってきます

net.tcp.serviceは引数を3つ設定でき
  • 1つ目はプロトコル(ssh、service.ntp、ldap、smtp、ftp、http、pop、nntp、imap、tcpのいずれか1つを指定)
  • 2つ目はIPアドレス
  • 3つ目はポート番号
を指定するのですが、LISTENしているIPアドレスによって2つ目の引数の設定に注意してください

以下具体例です
  • ポート10052が127.0.0.1でLISTEN -> net.tcp.service[tcp,,10052]
  • ポート10052が0.0.0.0でLISTEN -> net.tcp.service[tcp,,10052]
  • ポート10052が192.168.1.10でLISTEN -> net.tcp.service[tcp,192.168.1.10,10052]

何も指定しないとデフォルト監視しに行くのIPアドレスは「127.0.0.1」となります
0.0.0.0でLISTENしている場合は127.0.0.1でもアクセスできるので何も指定しなくても大丈夫です
厄介なのが192.168.1.10(とかプライベートIP系)でLISTENしている場合で
IPアドレスを指定しないと127.0.0.1に聞きに行ってしまうのでうまく監視できません
なのでちゃんとIPを指定してあげないとずっと「0」が返ってきてしまいます

ブログ等の紹介はIPアドレスまでちゃんと指定しているケースが少ないので
ちゃんと引数が何を意味しているのかはちゃんと調べないとダメですね

■参考サイト

2013年10月28日月曜日

2013年10月27日日曜日

mavenコマンドの使い方(主にgoal)について調べたのでメモ

■環境
CentOS 5.9 64bit
maven 3.1.0
Java 1.7.0_05
mavenのインストール方法は以下を参照
http://kakakikikeke.blogspot.jp/2013/10/maven.html

■プロジェクトの作成
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.mycompany.app -DartifactId=my-app

通常のJavaプロジェクトを作成する場合のパラメータです
archetypeGroupIdは後述にもありますが、mavenで用意されたテンプレートみたいなものを設定します(独自で作成することも可能)
groupIdはいわゆるパッケージ名です
artifactIdはいわゆるプロジェクト名です

コマンド実行時に入力が必須の部分もあるので入力必須の項目のサンプルを以下に記載します
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 312:
  enter入力
Choose org.apache.maven.archetypes:maven-archetype-quickstart version:
  enter入力(1.1)
Define value for property 'version':  1.0-SNAPSHOT: :
  enter入力
確認
  Confirm properties configuration:
  groupId: com.mycompany.app
  artifactId: my-app
  version: 1.0-SNAPSHOT
  package: com.mycompany.app

■goal検証
maven自体にはgoalと呼ばるmvnコマンドに渡す引数がいろいろと用意されており
そのgoalの指定によりjarを作ってくれたりとかテストしてくれたりとか.classファイルを作ってくれたりとか振る舞いが変わってきます
基本はこのgoalの種類と動きがある程度わかっていればmvn自体は使えるようになると思います

またプラグインという概念があり、振る舞いをいろいろと変更、拡張できるのでメジャーなプラグインさえ覚えておけば大丈夫だと思います
プラグインは独自で作成することも可能です

ここで紹介するgoalやプラグインが全てではないので他のgoalについては以下のページなどを確認してください
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

以下で紹介するコマンドはプロジェクト配下のディレクトリ(今回だとmy-app)配下でpom.xmlがあるところで実行してください

・mvn compile
target/classes 配下にjavaコンパイルした.classファイルを作成してくれます

・mvn test-compile
target/test-classes 配下にコンパイルしたテスト用.classファイルを作成してくれます

・mvn test
target/classes 配下にjavaコンパイルした.classファイルを作成し
target/test-classes 配下にコンパイルしたテスト用.classファイルを作成し
target/surefire-reports 配下にテスト結果を作成してくれます
mavneデフォルトのテストツールは「JUnit」となっておりpom.xml内でdependencyが定義されています

・mvn package
target 配下にjarファイルを作成し
target/classes 配下にjavaコンパイルした.classファイルを作成し
target/test-classes 配下にコンパイルしたテスト用.classファイルを作成し
target/mavne-archiver 配下にpom.properties(プロジェクトのメタ情報ファイル?要調査)を作成し
target/surefire-reports 配下にテスト結果を作成してくれます
「jar:jar」「compile」「test-compile」「test」等をまとめて実行してくれるgoalです
test結果に関してはSurefireプラグインというプラグインを使っているようでテスト結果を統計的に見れるファイルも作成してくるようです
http://maven.apache.org/surefire/maven-surefire-report-plugin/

・mvn clean
target ディレクトリを削除してくれます
「compile」「test-compile」「test」「package」等を実行する前には実行する必要があります

・mvn install
作成した成果物(jarファイル)をローカルのmavenリポジトリに配備してくれます
具体的なパスは例えばrootユーザで実行した場合は
/root/.m2/repository/com/mycompany/app/my-app/1.0-SNAPSHOT/
配下にjarやxmlファイルを展開してくれます
他のプロジェクトが成果物を参照する必要がある場合に実施します

・mvn archetype:generate
指定できる主なオプションは以下があります
  • -DarchetypeGroupId・・・作成するプロジェクトの元となるarchetypeを入力します
  • -DgroupId・・・パッケージ名を入力します
  • -DartifactId・・・プロジェクト名を入力します
groupIdやartifactIdは任意の値を入力することができます
archetypeGroupIdに関してはMavenCentralで公開されているarchetypeGroupIdを指定しなければいけません
ただ量が膨大で覚えるのはほぼ不可能です
なので省略することもでき、省略した場合はプロジェクトを作成するときにどのarchetypeGroupIdを使用するか選択することができます
一覧がずっと出てきて番号を入力することでarchetypeGroupIdを選択することができます
ただ、この一覧もものすごい量が出てくるので選択するのが結構大変です

・mvn site
pom.xmlをもとにプロジェクトの情報をHTML形式に吐き出してくれます
現在使用しているプラグイン読み込んでいるjarファイルの一覧等が確認できます

・mvn idea:idea
InteliJ形式のフォルダ構成に変換してくれる
InteliJからインポートすればコマンドで作成したプロジェクトをInteliJ上で開発できます
my-app.iml, my-app.ipr, my-app.iwsを作成してくれます

・mvn eclipse:eclipse
上記のeclipse版
.classpath, .projectを作成してくれます

■プラグインに関して
主なプラグインについて紹介します
デフォルトの状態でもメジャーなプラグインはすぐに使える状態にあります

・mvn jar:jar
target 配下にjarファイルを作成してくれます
http://maven.apache.org/plugins/maven-jar-plugin/

・mvn war:war
target 配下にwarファイルを作成してくれます
http://maven.apache.org/plugins/maven-war-plugin/

今回の場合通常のJavaプロジェクトでWebアプリ用のプロジェクトではないので失敗すると思います
具体的にはweb.xmlの定義に失敗するのですが、冒頭のプロジェクト作成時の
archetypeGroupIdをwebアプリ用で指定してプロジェクトを作成するとwarファイルの作成もうまくいきます
サンプルは以下の通りです
mvn archetype:generate -DarchetypeGroupId=maven-archetype-webapp -DgroupId=com.mycompany.web.app -DartifactId=my-web-app

他のarchetypeGroupId関しては以下を参照してみてください
http://maven.apache.org/guides/introduction/introduction-to-archetypes.html

■所感
mavenリポジトリがグローバルにアクセスできないと使えないのでグローバルに接続できる環境は必須
プロキシ等の環境の場合、pom.xmlを修正しないといけない等、若干ハードルが高くなる

■参考

2013年10月26日土曜日

elasticsearchを試してみた

■環境
CentOS 5.9
Java 1.7.0_05
elasticsearch 0.90.5

■elasticsearchインストール
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.5.tar.gzs
tar xvzf elasticsearch-0.90.5.tar.gz
mv elasticsearch-0.90.5 /usr/local/
cd /usr/local/
ln -s elasticsearch-0.90.5/ elasticsearch

vim /root/.bashrc
export ELASTIC_SEARCH=/usr/local/elasticsearch
export PATH=$ELASTIC_SEARCH/bin:$PATH
source /root/.bashrc

elasticsearch -f
netstat -an | grep 9200
最終的に9200ポートでLISTENしていればインストールおよび起動は完了

■サンプル実行
1. サンプルデータの投入
curl -X POST http://localhost:9200/dictionary/name/1 -d '{"famiry_name":"kaka","first_name":"abc","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/2 -d '{"famiry_name":"kaka","first_name":"def","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/3 -d '{"famiry_name":"kaka","first_name":"ghi","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/4 -d '{"famiry_name":"kaka","first_name":"jkl","email" :"sample@sample.email.com","age":20}'
curl -X POST http://localhost:9200/dictionary/name/5 -d '{"famiry_name":"kaka","first_name":"mno","email" :"sample@sample.email.com","age":20}'
「/hoge/foo/n」のような感じでパスを自由に設定することができます
n の部分は数字を設定する必要があります
最後の数字の n 部分を変えてデータをPUTしないと同じデータをタダ上書きするだけなので注意が必要です

2. サンプルデータの取得(キーワード検索)
curl -X GET http://localhost:9200/dictionary/name/_search -d '{"query":{"match":{"famiry_name":"kaka"}},"size":10,"from":0}'
「/hoge/foo/_search」というパスにリクエストすることで検索することができます
今回はcurlコマンドなので-dでリクエストのbody部分を設定します
1. で登録した全てのデータが返ってくるはずです
sizeとfromはmysqlで言うところのlimitで範囲を指定して取得する場合などに使えます(デフォルトはsize:10, from:0のようです)
クエリの指定方法はたくさんありますので他のクエリの指定方法は以下を参考にしてみてください
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-uri-request.html

3. サンプルデータの取得(部分一致検索、正規表現検索)
curl -X GET http://localhost:9200/dictionary/name/_search -d '{"query":{"regexp":{"famiry_name":"ka.*"}},"size":10,"from":0}'
基本的な指定は2. と同様ですが「match」ではなく「regexp」を使用しております
使用できる正規表現は以下に詳しく記載があります
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html

今回は以上です
elasticsearchはすべてをREST-API経由で実行するツールとなっています
データの検索に特化しており、全文検索や位置検索もできるようになっています
また応用編ですがhadoopにも対応しているので簡単にスケールアウトできるようです(未調査)

次回はelasticsearch用のWeb UI「kibana」でも試してみたいと思います

■Tips
・登録したすべてのルートパス(indexes)を表示する方法
curl -X GET http://localhost:9200/_aliases
・不要なindexesを削除する方法(_riverというindexes配下のデータをすべて削除する)
curl -XDELETE 'http://localhost:9200/_river

■参考