Jenkins + SonarQube で PHPコードメトリクス計測!

Jenkins + SonarQube で PHPコードメトリクス計測!

前回

Jenkins とは別のサーバ上に
SonarQube をインストールし
アクセスできるまでをまとめました。

今回は Jenkins からソースを解析し
SonarQube でのメトリクス情報を表示までの実行方法をまとめます。

言語は どれでも良いですが、 今回は PHP とします。

Overview

以下概要になります。

SonarQube 側事前準備

プロジェクトを作成しプロジェクトキーを発行します。

1. ログインページへアクセス

http://:9000/sessions/new

デフォルトでは以下 admin:admin アカウントでログイン

Item Value
ID admin
PW admin

2. プロジェクト作成

  • ヘッダーメニュー Administration クリックし Administration ページへ遷移
  • Projects > Management クリック
  • Create ボタンクリック
  • Name, Key 入力し
  • プロジェクトが追加されたことがわかります。

3. PHP Plugin インストール

  • Administration ページ System > Update Center クリック
  • Available 選択 → 検索窓で「PHP」と入力 → 表示された PHP Plugin で Install クリック
  • Restart で SonarQube に PHP Plugin インストール
  • Installed タブで PHP Plugin がインストールされていることを確認

4. authentication token 発行

  • Security > User クリック
  • TOKENS クリックしポップアップ表示
  • 任意の文字列を入力し create
  • token コピー
    Jenkins 側の設定時に利用します。

以上で SonarQube 側の事前準備は終了です。

Jenkins 側準備

1. SonarQube Plugin インストール

Jenkins の管理 > Plugin の管理
にて SonarQube Plugin インストール

2. SonarQube Scanner インストール

以下オフィシャルダウンロードページからリンク取得

Analyzing+with+SonarQube+Scanner

1
2
3
4
$ cd /var/lib/jenkins
$ wget https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-2.6.1.zip
$ unzip sonar-scanner-2.6.1.zip
$ ln -s sonar-scanner-2.6.1 sonar-scanner

3. Jenkins システム設定

  • Jenkins の管理 > システムの設定 へアクセス

  • JenkinsQube servers に必要項目入力

  • SonarQube Scanner に先ほどインストールした sonar-scanner パスを設定

上記入力後保存

4. ジョブ新規作成

「sonarqubeTest」という名前のジョブを新規作成します。

  • git リポジトリより PHP プロジェクト取得設定
  • SonarScanner 実行設定

以上で Jenkins 側の設定完了です。

SonarQube 反映確認

ちなみにこちら EC-CUBE 1.1 のプロジェクトでした。

EC-CUBE のコード重複率が多く
無駄が如何に多いかがわかります。

以上です。

MySQが落ちる トラブルシューティング Cannot allocate memory for the buffer pool

MySQが落ちる トラブルシューティング Cannot allocate memory for the buffer pool

概要

AWS E2 インスタンス上に MySQL, SonarQube インストールし起動するものの
MySQL が落ちるという事象が発生。

ログを見ると以下のエラーが。。

  • /var/log/mysqld.log
1
2
3
4
5
6
InnoDB: mmap(137363456 bytes) failed; errno 12
[ERROR] InnoDB: Cannot allocate memory for the buffer pool
[ERROR] Plugin 'InnoDB' init function returned error.
[ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE
[ERROR] Unknown/unsupported storage engine: InnoDB
[ERROR] Aborting
1
2
3
Cannot allocate memory for the buffer pool

バッファープールへのメモリ割当ができない

割りあてるメモリがないという話。
なので、メモリを作ります。

対策 1. swap 領域を作成する

swap 領域作成

1
2
3
4
5
6
7
8
// 空ファイル作成
# dd if=/dev/zero of=/swapfile bs=1M count=1024

// 作成した空ファイルをswap領域に設定
# mkswap /swapfile

// スワップ領域を有効化
# swapon /swapfile

swap 領域確認

1
2
3
4
5
# free

total used free shared buff/cache available
Mem: 1015472 833592 66456 1456 115424 54708
Swap: 1048572 491136 557436 ← Swapの設定が追加されていることを確認

mysql 再起動

1
# systemctl restart mysqld

対策 2. innodb_buffer_pool_size の割当を増やす

現在設定されている innodb_buffer_pool_size 確認

1
2
3
4
5
6
7
$ mysql -u <user> -p<pass> <db>  -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size'"

+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 118835956 |
+-------------------------+-----------+

エラーログにあった 137363456 を下回ってるのがわかります。
この割当メモリを増やします。

my.cnf の場所探し

左から順に検索し該当するファイルがあればその my.cnf を参照します。
/etc/my.cnf → /etc/mysql/my.cnf → /usr/etc/my.cnf → ~/.my.cnf

1
2
3
# mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

メモリ追加

自分の方では
my.cnf 上に innodb_buffer_pool_size の設定項目がなかったので
追加しました。

  • my.cnf
1
2
3
4
5
6
7
8
9
10
[mysqld]
...
...

# 以下追加
innodb_buffer_pool_size = 256M

[mysqld_safe]
...
...

mysql 再起動

1
# systemctl restart mysqld

増えているか確認

1
2
3
4
5
6
7
$ mysql -u <user> -p<pass> <db>  -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size'"

+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 268435456 |
+-------------------------+-----------+

今回発生していたエラーログが消えました。

CentOS7にSonarQubeをインストールしアクセス確認まで

CentOS7にSonarQubeをインストールしアクセス確認まで

概要

sonarqube
Java, Python, Ruby, PHP 等、複数言語のコードメトリクス集計ができる
優れものです。

以前 MacOSX ローカル環境で
Unity プロジェクト C#コードのコードメトリクス抽出方法をまとめました。

今回は CentOS7 上に構築する方法を以下にまとめました。

環境

  • CentOS7 64bit
  • Java 1.8
  • ec2 t.micro

JDK インストール

1
2
# cd /usr/local
# wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u45-b14/jdk-8u45-linux-x64.tar.gz"
1
# tar xvf jdk-8u45-linux-x64.tar.gz
1
# ln -s jdk1.8.0_45 latest

環境変数 JAVA_HOME 設定

.bash_profile での設定ではユーザにより環境変数が異なるので
全ユーザ共通で設定する場合は /etc/profile.d/ 以下に shell を用意する。

1
2
3
4
5
# echo "export JAVA_HOME=/usr/local/java/latest
export PATH=$PATH:$JAVA_HOME/bin" > /etc/profile.d/javaenv.sh

# echo "export JAVA_HOME=/usr/local/java/latest
export PATH=$PATH:$JAVA_HOME/bin" > /etc/profile.d/javaenv.csh

MySQL インストール

今回は同一サーバに MySQL インストールしています。
別途 MySQL サーバを立てる場合は不要です。

1
2
3
4
5
6
7
8
9
10
11
12
13
# yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
# yum -y install mysql-community-server
# chown -R mysql:mysql /var/lib/mysql/*
# systemctl start mysqld
# chkconfig mysqld on

// 以下 DB名: sonar, DB User: sonar, DB Pass: sonar で設定
# mysql -u root

mysql> CREATE DATABASE sonar;
mysql> CREATE USER 'sonar'@'localhost' IDENTIFIED by 'sonar';
mysql> GRANT ALL PRIVILEGES ON sonar.* TO 'sonar'@'localhost';
mysql> FLUSH PRIVILEGES;

SonarQube インストール

以下サイトにてダウンロード zip を取得します。
SonarQube Donwloads

Imgur

※ 2016-05-19 時点 最新は ver 5.5

1
2
3
4
5
# mkdir /usr/local/sonarqube
# cd /usr/local/sonarqube
# wget https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-5.5.zip
# unzip sonarqube-5.5.zip
# ln -s sonarqube-5.5 sonar

環境変数 SONAR_HOME 設定

1
2
3
4
5
# echo "setenv SONAR_HOME=/usr/local/sonarqube/sonar
setenv PATH=$PATH:$SONAR_HOME/bin/linux-x86-64" > /etc/profile.d/sonarenv.sh

# echo "setenv SONAR_HOME=/usr/local/sonarqube/sonar
setenv PATH=$PATH:$SONAR_HOME/bin/linux-x86-64" > /etc/profile.d/sonarenv.csh

SonarQube から MySQL を利用できる様に設定

以下ファイルを編集し作成した DB にアクセスできるように設定します。

  • /usr/local/sonarqube/sonar/conf/sonar.properties
1
2
3
sonar.jdbc.username=sonar # DB User
sonar.jdbc.password=sonar # DB Password
sonar.jdbc.url=jdbc:h2:tcp://localhost:9092/sonar # DB url

SonarQube が利用する java コマンド設定

以下ファイルを編集し SonarQube が利用する java コマンドを
インストールした JDK 内の java を指定するように変更

  • /usr/local/sonarqube/sonar/conf/wrapper.conf
1
2
#wrapper.java.command=java
wrapper.java.command=/usr/local/java/latest/bin/java

SonarQube 起動スクリプト設定

1
2
3
# ln -s /usr/local/sonarqube/sonar/bin/linux-x86-64/sonar.sh /etc/init.d/sonar
# chkconfig --add sonar
# chkconfig sonar on

サーバ再起動

/etc/profile.d に設定した 環境変数を反映させるべくサーバ再起動します。

1
# reboot

アクセスして確認

http://<IPアドレス>:9000

SonarQube 管理ページが表示されれば OK です!

再起動後アクセスできない場合

SonarQube の設定を見直すか、もしくは、

今回利用している ec2 t2.micro のような小メモリの場合
メモリ不足で MySQL が落ちる可能性があります。

以下参照して対応してください。

あとがき

どんなプロジェクトでもここ修正したい!
と思うことは多々あるかと思います。

その際、なんとなくここ使いづらいから直そう!
という曖昧な判断ではなく

先立ってまず全体としてどういう状態にあるか、
を数値でみて判断する、

というプロセスが踏めるようになることを目的に導入しました。

次回は Jenkins からの実行方法をまとめます。

sftpをシェル化してファイルアップロード

概要

データ解析サービスを提供するサードパーティで
指定の Server, Path に指定形式で格納するように、
と指示がありました。

また、
「Protocol は sftp のみ許可でお願いします」
とも。

定期実行する必要もあったため
シェルで書けないかということで、
以下まとめました。

shell

Point

  • expect で通常、対話形式となるsftpコマンドの先読みでパスワードを通過

  • -oオプションで bachmode no を指定し以下のエラーを回避

1
2
Permission denied (publickey,password).
Connection closed
  • -bオプション バッチファイルにsftpログイン後の実行処理を記述

当方では、Jenkins や cron でシェルを定期実行する必要があった為
明示的にバッチファイルの内容を指定できるようにしています。

以上です。

Zabbix3.x系からSlack通知

Zabbix3.x系からSlack通知

概要

Zabbix3.x 系での Slack への障害内容通知方法をまとめました。

簡単なメッセージの通知でなく
ある程度見やすく、状況判断しやすい様にしました。

↓ まずざっくりとこんな感じです。

手順

Git に上げてます。ご参照ください。

とにかくシンプルにPHPでLineBotApiを書きました

とにかくシンプルにPHPでLineBotApiを書きました

概要

話題の Line bot Api 用スクリプトを PHP で書きました。

とにかくシンプルに = カスタマイズしやすさ

という所で
修正する場所を限って利用できるようにしたつもりです。

作ったもの

適当に文字を打つと →「hello」
perfect と打つと → 「human」

と返すようにした本当にシンプルなものです。

そのロジック部分をカスタマイズすれば
マイ bot ができますね。

環境

  • さくらレンタルサーバ VPS CentOS release 6.7 (Final)
  • PHP 5.6.16

SSL は無料の StartSSL を利用しました。取得・設定は以下参照してください。

スクリプト

function getMessage で bot に返信させたいメッセージを決定しています。

そこで他 API を呼んだり、サイトからスクレイプしたり情報をとってきて返してあげると
簡易的なメッセージ返信 Line bot できあがりです。

こんな感じです!

パスワードなし!公開鍵認証でSSHログイン

パスワードなし!公開鍵認証でSSHログイン

概要

rsync を Jenkins や crontab で利用する場合
SSH 経由で実行する際、
パスワードを求められ処理が中断してしまうということがあるかと思います。

その為、SSH で公開鍵認証という方法でパスワードを求めることなく
SSH アクセスできる様な設定を明示的にしました。

以下まとめます。

環境

  • 接続元サーバ A の global IP を 192.168.11.200 とします。
  • 接続先サーバ B の global IP を 192.168.11.201 とします。

サーバ A → サーバ B へ 公開鍵認証で SSH ログインを目的とします。

以下手順です。

接続元サーバ A

公開鍵作成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[host A]# mkdir ~/.ssh
[host A]# ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/pgsql/.ssh/id_rsa): ←何も入力せず[Enter]を押す
Enter passphrase (empty for no passphrase): ←何も入力せず[Enter]キーを押す
Enter same passphrase again: ←何も入力せず[Enter]キーを押す
Your identification has been saved in <home>/.ssh/id_dsa.
Your public key has been saved in <home>/.ssh/id_rsa.pub.
The key fingerprint is:
7e:38:5c:9f:f3:e2:67:eb:ce:c6:07:83:48:c8:85:ec

[host A]# ls -l
合計 12
-rw------- 1 hogehoge hogehoge 668 5月 25 15:11 id_rsa ←作成された秘密鍵
-rw-r--r-- 1 hogehoge hogehoge 610 5月 25 15:11 id_rsa.pub ←作成された公開鍵

[host A]# cat id_rsa.pub
<中身をコピーする>

接続先サーバ B

接続元サーバの公開鍵を authorized_keys に保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[host B]# cd ~
[host B]# chmod 755 .
[host B]# mkdir .ssh
[host B]# chmod 700 .ssh
[host B]# cd .ssh
[host B]# vi id_rsa.pub
<接続元サーバでコピーした公開鍵の内容をペースト>

[host B]# ls id_rsa.pub
id_rsa.pub

[host B]# cat id_rsa.pub >> authorized_keys
[host B]# chmod 600 authorized_keys
│-rw------- 1 hogehoge hogehoge 796 4月 5 15:50 authorized_keys

接続元サーバのアクセス許可設定

  • /etc/hosts.allow を編集し 接続元 IP 許可設定する。
1
[host B]# vi /etc/hosts.allow
1
2
3
4
5
6
7
8
#
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
sshd: xxx.x.xx.xx xxx.x.xxx. xx.xx.x. xx.xx.xxx.xx
sshd: xxx.xx.xxx.xx
sshd: 192.168.11.200 ← 追加

公開鍵認証許可設定

  • バックアップ保存
1
[host B]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bk
  • 修正
1
[host B]# vi /etc/ssh/sshd_config
1
2
3
4
5
#PubkeyAuthentication yes    ← コメントアウトを外す
#AuthorizedKeysFile .ssh/authorized_keys ← コメントアウトを外す

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
  • 差分確認
1
2
3
4
5
6
7
[host B]# diff /etc/ssh/sshd_config.bk /etc/ssh/sshd_config

< #PubkeyAuthentication yes
< #AuthorizedKeysFile .ssh/authorized_keys
---
> PubkeyAuthentication yes
> AuthorizedKeysFile .ssh/authorized_keys
  • sshd configure チェック
1
2
3
[host B]# sshd -t
// 何も出力されなければ構文上問題なし。
// 但し存在しないパスを指定するなどまではチェックしないので注意。
  • sshd リスタート
1
2
[host B (CentOS7)]# systemctl restart sshd
[host B (CentOS6)]# service sshd restart

以上で接続先サーバでの準備完了しました。

接続元サーバ A から パスワードなしで SSH 接続する

1
2
[host A]# ssh 192.168.11.201
Last login: Tue Apr 5 16:02:08 2016 from xxx.xx.xxx.xxx

ログイン成功!

ログイン失敗する場合

  • ログを調査しましょう。

権限や所有権がよろしくない、
ということで認証失敗理由がわかります。

1
2
3
# tail -f /var/log/secure

Authentication refused: bad ownership or modes for directory <homeディレクトリ>

あとがき

以下デフォルトの sshd_config の設定の場合
パスワード認証と鍵認証、どちらも認証パス可能です。

1
2
3
#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes

インフラ専門の会社さんや街の噂では
デフォルトでどちらも認証 OK にしている企業さん多いという話でした。

以上です。

awk で CSV の特定列を整形 〜数値を文字列扱いする〜

awk で CSV の特定列を整形 〜数値を文字列扱いする〜

概要

ある顧客データを抽出してレポートしたい、というときに
CSV ファイルで “090” などと携帯電話があると Excel で CSV ファイルを開いたときに
“90” になってしまうということがあるかと思います。

そんなときの為に特定列のみ数値を文字列扱いにしたときの内容まとめです。

Excel で数値を文字列扱いするには

1
"090"

とあったとすると

1
="090"

のように整形することで文字列扱いになります。

例)

1
"デミスハサビス",="09099999999","DeepMind"

整形してみる

  • 例)以下のような tmp.csv があるとします。
1
2
"デミスハサビス","09099999999","DeepMind"
"いとうせいこう","08088888888","エムパイヤ・スネーク・ビルディング"
  • 2 つ目のカラムのみ =を左端に追加します
    ※”(ダブルクォテーション)で囲まれた値の左側に「=」を追加します。
    ※あえて分かりやすく $1, $2, $3 の項目を明示的に指定してみました。
1
2
3
$ awk -F ',' '{print $1 ",="$2","$3}' tmp.csv
"デミスハサビス",="09099999999","DeepMind"
"いとうせいこう",="08088888888","エムパイヤ・スネーク・ビルディング"

上記のように 「=」 が追加されました。

  • 出力先を指定
1
2
3
4
$ awk -F ',' '{print $1 ",="$2","$3}' tmp.csv > output.csv
$ cat output.csv
"デミスハサビス",="09099999999","DeepMind"
"いとうせいこう",="08088888888","エムパイヤ・スネーク・ビルディング"

output.csv を Excel で開いてみます。

できました ♪

おまけ

Excel を開く際、Windows ではデフォルト SJIS なので文字コードが UTF8 の場合、文字化けします。
以下 CSV ファイルを SJIS に文字コード変換します。

1
$ nkf -sLw output.csv > output_sjis.csv

以上です。

.htaccessが効かない、動かないときの対処

.htaccessが効かない、動かないときの対処

概要

.htaccess に設定した通りに動作しない、そもそも読み込んでいないように見える場合の対策です。

http だと mod_rewrite でリダイレクトするけど、 https だとしない、とか
ありがちな設定ミスパターンは以下基本的なことを確認して解決できます。

検証環境

  • CentOS 6.6 (Final)
  • Apache/2.2.15(Unix)

そもそも .htaccess を利用するには

/etc/httpd/conf/httpd.conf 等設定ファイル内で以下の記述が必要です。

1
AllowOverride All

mod_rewrite を利用するには

利用頻度の多い mod_rewrite を利用するには以下が必要です。

1. mod_rewrite.so インストール

2. mod_rewrite.so を Apache 設定ファイルからロード

まずは上記の確認です。

1. mod_rewrite.so インストール確認

Apache の場合、大抵 modles ディレクトリ以下に格納されてます。

1
2
$ ls -al /etc/httpd/modules/mod_rewrite.so
-rwxr-xr-x 1 root root 60464 10月 16 23:49 2014 /etc/httpd/modules/mod_rewrite.so

2. mod_rewrite.so を Apache 設定ファイルからロードされているか確認

Apache 設定ファイル
/etc/httpd/conf/httpd.conf/etc/httpd/conf.d/*.conf で以下を設定している。

※環境によっては /etc/httpd/conf/httpd.conf に設定ファイルを置いてない場合もあるので
 あくまで一般的な例とします。

1
LoadModule rewrite_module modules/mod_rewrite.so

補足

モジュール読み込み設定は大抵、
以下のように ディレクティブ で AllowOverride All が設定されているかと思います。

以下例では「/var/www/html」ディレクトリ以下では 配置した .htaccess を優先して設定されることになります。

1
2
3
4
5
6
<Directory "/var/www/html">
AllowOverride All
Options -Indexes FollowSymLinks Includes ExecCGI
Order allow,deny
Allow from all
</Directory>

万が一 mod_rewrite.so モジュールが存在しない場合は Apache の再コンパイルが必要になります。

Apache に mod_rewrite をインストールしリコンパイル

  • リコンパイルして Apache 再起動します。
1
2
3
4
5
$ sudo su -
# cd <path to httpd source>
# ./configure –enable-ssl=shared –enable-rewrite –enable-deflate –enable-headers –enable-so
# make & make install
# service httpd restart

以上です。

IPアドレスからホスト情報取得

IPアドレスからホスト情報取得

概要

ipinfo.io の API により
ホスト情報を取得するシェルを書きました。

不審なアクセスが増えてきた、
というときに接続元ホストを探る際に利用しています。