astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

Pipeline Jobから実行結果を簡単にSlackに通知する

こんにちは。宮崎からリモートしてます。開発部のyanagitaです。

新型コロナウィルスの影響の中、皆さんいかがお過ごしでしょうか。
全国的に緊急事態宣言が解除となりましたが、一足早く解除された宮崎では少しずつ緊急事態宣言前の生活に戻りつつあります。
先日、首都圏、北海道も解除宣言されてこともあり、一日も早く宣言前の生活に戻れることを願っております。

話を戻しまして、今回はすこし古いですがJenkinsのPileline JobからSlack通知について書きたいと思います。

今回確認したJenkinsとPluginのバージョン

  • Jenkins ver.2.222.3
  • Slack Notification Plugin v2.40

(問題)Pipelineプロジェクトでは、Slack Notificationsの設定項目がない

フリースタイル・プロジェクトやMavenプロジェクトでは、ビルド後の後処理に「Slack Notifications」が選択でき、ここでjobの実行結果に合わせてSlack通知の設定が可能になります。
しかし、Pipelineプロジェクトではビルド後の処理項目の表示がないので、Slack通知の設定はPipelineのScript内に記述する必要があります。

f:id:astamuse:20200527094635p:plain
フリースタイル・プロジェクトの例

ビルド後の後処理に「Slack Notifications」が選択が可能になっています。

f:id:astamuse:20200527094822p:plain
Pipelineプロジェクトの例

Pipelineプロジェクトではパイプラインの設定まででビルド後の処理が項目がないです。

Pipeline Script内にSlack通知を記述する

まず、Pipeline Scriptの記述は2つあって、pipeline記述にとnode記述が存在します。

  • Pipeline記述
pipeline {
    agent any
    stages {
        stage("code") {
            steps {
                echo "pipeline."
            }
        }
    }
}
  • Node記述
node {
    stage("code") {
        echo "node."
    }
}

両方とも同じ内容のJobになっていて、node構文のほうが記述量が少なく、プログラム形式に記述することができるので細かい制御が可能になりますが、ビルド失敗時のケアもプログラミング同様に記述する必要がでてきます。
複雑なJob実行を求められていないのであれば次で説明するpipeline記述のpost構文と組み合わせるとこで、Slack Notificationsの設定同様にビルド結果に合わせて通知内容を簡単に制御できます。

piepline記述のpost構文は、Jobの実行結果ごとに追加処理を記述することができるようになっています。

pipeline {
    agent any
    stages {
        // job処理
    }

    // ここからがpostの記述
    post {
        success { /* Job正常終了時 */ }
        failure { /* Job失敗時 */ }
    }
}

post直下のsuccess、failureがJob実行結果の条件になっており、該当する条件内の処理が実行されます。
success、failure以外はこちらをご確認ください。

post構文でビルド後の後処理と同様の設定が可能になったので、次に各実行結果の中でSlack通知を記述していきます。
Slack通知はSlack Notification Pluginに含まれるslackSendコマンドを利用します。

post {
    success {
        slackSend  color: 'good',
                           message: "build success."
        }
    }
    failure {
        slackSend  color: 'danger',
                           message: "build failure."
        }
    }
}

f:id:astamuse:20200527102717p:plain
Slack通知イメージ

slackSendは、メッセージ以外にチャンネルの指定やBot名も設定できます。(オプションはこちら)
指定しない場合は、Jenkinsの管理 > システムの設定 > Slack設定の内容がデフォルトの通知設定になります。
※ オフシャルのサイトではmessageオプションは省略可能になっていますが、私が環境ではmessageオプションを付けないとビルドエラーになってしまいJobの実行ができませんでした。
※ node記述でもslackSendは利用可能です。

以上、pipeline記述のpost構文とslackSendの組み合わせで、pipeline jobからSlack Notifications設定同様のSlack通知設定が簡単に行えるようになりました。

さいごに

アスタミューゼではたくさんのエンジニア&デザイナをまだまだまだ募集しています。 気になる方は下からご応募ください!新しい出会いをメンバー一同お待ちしてます!

PostgreSQLのベンチマークを pgbench でバージョン毎に取得してみた

f:id:astamuse:20200507105024j:plain

こんにちは。並河(@namikawa)です。

新型コロナウイルスが終息していくことを祈り、弊社もリモートワーク体制に移行しておりまして、私自身もほぼ自宅で過ごしている日々です。弊社では、従前よりフルリモートワークを遂行しているメンバーが数名いますので、各人のリモートワークへの移行も割とすんなり出来たのではないかと感じています。(細かい課題意識はもちろんありますが)

さて、閑話休題。

このブログでも散々話題に出ているかと思うのですが、弊社では技術や投資にまつわるデータを大量に保有しておりまして、それぞれのデータの特性や用途によって、データストアを使い分けています。

その中でも、RDB には PostgreSQL が以前より活用されていまして、今日のエントリの趣旨は、この PostgreSQL の基礎ベンチマーク数値をバージョン毎に差異があるかを確認してみた記録となります。

ベンチマークの取得環境について

ベンチマークを取得した環境について記載しておきます。

  • ベンチマークに使用したソフトウェアは "pgbench" です。
    • "pgbench" は PostgreSQL のソフトウェアに標準で同梱されているツール。
  • 対象の PostgreSQL のバージョンは、 9.5, 9.6, 10, 11, 12 です。
  • PostgreSQL を稼働させたサーバは、Google Compute Engine (GCE) の下記2インスタンスです。
    • n1-standard-1 (1vCPU, 3.75GB)
    • n1-standard-4 (4vCPU, 15GB)
  • サーバで稼働させた OS は Ubuntu 20.04 LTS です。
  • PostgreSQLのデータを置いたディスクは、SSD で容量は 100GB となります。ファイルシステムは ext4 です。

PostgreSQL の設定については、下記の2パターンを用意して試してみました。

  • デフォルトの設定 (インストール時の状態)
  • PGTune で生成した設定

環境のセットアップ

GCE でインスタンスを起動させて、以下のコマンドで PostgrSQL が稼働する環境を作ります。

# apt-get install curl ca-certificates gnupg

# curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -

# sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

# apt-get update

# apt-get install postgresql-${バージョン番号}

これで、PostgreSQL サービスが稼働しているのと、pgbench も実行できる状態になっているはずです。

続いて、ベンチマークで使うデータセットを pgbench を使って実行します。

# su - postgres

$ createdb test

$ pgbench -i -s 10 test

pgbench コマンドは "-i" オプションが初期化モード、 "-s" オプションが生成されるデータの桁数を示します。デフォルトは 1 で、1 だと10万行となります。↑の例だと100万レコードでデータセットが生成された感じです。

ベンチマークの取得

次に、実際にベンチマークを取得してみます。 今回は、以下のコマンドで取得を行いました。

$ pgbench -c 16 -t 1000 test

"-c" はクライアント数なので、↑の例だと同時に 16 コネクションで同時実行していることになります。 "-t" オプションは、各クライアントが実行するトランザクション数です。

ベンチマークは、下記のそれぞれの条件において、上記のコマンドを5回実行し、その中央値を結果として記載しています。

ベンチマーク結果

今回とったベンチマークの結果が以下の表となります。

f:id:astamuse:20200507102409p:plain

縦軸が PostgreSQL のバージョン。横軸の項目は、1つ目の表記がサーバのコア数で、2つ目の表記が PostgreSQL の設定です。で、結果の数値は TPS (excluding connections establishing) となります。

横軸の補足説明ですが、例えば、1つ目の "1core, default" だと、1コアのインスタンスで、デフォルトの PostgreSQL の設定を使った結果となります。4つ目の "4core, PGTune" は、4コアのインスタンスで、PostgreSQL の設定をPGTuneの推奨値に書き換えた結果となります。

グラフにすると以下。

f:id:astamuse:20200507102458p:plain

こちらの結果から、概ね、バージョンを上げていくことで、TPSレベルでの基本的なパフォーマンスは伸びていっているように思います。またデフォルトの設定ではなく、PGTune の推奨値を使った方が、よりパフォーマンスが上がる結果になりました。

シングルコアのサーバ(今時あまり使わないかもしれませんが)だと、その結果は顕著です。

一方で、4コアのサーバを使った結果は、バージョンごとにさほど大きな差はつきませんでした。ひょっとしたらデータセットのサイズ、メモリサイズとその割り当て量が影響しているのかなとも思いますが、I/Oの状況等、あまり細かく見れていないので、もう少しレコード数を増やした検証も、後日行ってみたいなと考えています。

とりあえず、この数値だけみていると、バージョン 12 には上げていきたいなーと思ったので、「PostgreSQL の バグ修正状況を調べてみた。」を参考に、下半期以降とかでアップグレードしていきたいな、と思ったのでした。


・・・と、若干中途半端感は否めないのですが、今日はこの辺で。 本当は、もうちょいコア数をスケールさせたらどうなる?とか、データセットのサイズ変えたらどうなる?とか、クライアントのコネクション数やトランザクション数変えたらどうなる?とか、時間があれば色々やってみたいと思うので、また追試したら、結果報告したいと思いますー!

それでは!=͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞(๑•̀д•́

@namikawa が書いた過去記事)

pythonのArgumentParserような使い心地!picocliのご紹介

f:id:astamuse:20200415113243p:plain

こんにちは、開発部のnishikawaです。本日はpicocliというライブラリを使ってScalaでコマンドを実装する機会があったのでご紹介します。

コマンド作りあるある

コマンドを作る時によく実装されるのが引数のパースです。これはどんな言語で実装されていても多くの人が実装すると思います。よく使われるのがgetoptsですが、これを使っても毎回引数のパースを作り込むのは面倒です。

もちろんjavaも例外ではないのですが、この実装が面倒で時間がない時はバリデーションを省略するような実装をすることも多いと思います。

コマンド作るならやっぱりpythonだよねー

その点pythonだと、デフォルトで高機能な引数のパーサーがあります。それがArgumentParserです。これが存在することや便利なライブラリがあるのでコマンド作りはpythonでという人は多いと思います。

しかし、プロダクトの多くをJVM言語で実装しているようなチームでは資産が流用できないのでやっぱりpythonは・・・というようなところも多いかもしれません。じゃあJVM言語でもArgumentParserのような機能が欲しいということで出てくるのがpicocliです。

picocli とは

picocliはjavaで実装されたコマンドラインインターフェースを提供するライブラリです。とても高機能でJVM言語で利用可能です。

picocli: https://github.com/remkop/picocli

pythonのArgumentParserと比較しながら使ってみる

picocliはArgumentParserのような使い心地です。実際にpythonのArgumentParserと比較してみたいと思います。

以下は引数に数字を列挙すると最大値を返し、オプションで「--sum」をつけると列挙した引数の数字を合計するコマンドをArgumentParserとpicocliを利用して実装した例です。

ArgumentParser

まずはpythonのArgumentParserを使った例です。

test.py

import sys
from argparse import ArgumentParser, _SubParsersAction


import argparse

def main():
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('integers', metavar='N', type=int, nargs='+',
                        help='an integer for the accumulator')
    parser.add_argument('--sum', dest='accumulate', action='store_const',
                        const=sum, default=max,
                        help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

    return 0


if __name__ == '__main__':
    sys.exit(main())

サンプルを実装したら、実行してみます。

ヘルプ実行例

$ python3 test.py -h
usage: test.py [-h] [--sum] N [N ...]

Process some integers.

positional arguments:
  N           an integer for the accumulator

optional arguments:
  -h, --help  show this help message and exit
  --sum       sum the integers (default: find the max)
$

通常実行(--sumオプションなし)

$ python3 test.py 1 2 3
3
$

通常実行(--sumオプションあり)

$ python3 test.py 1 2 3 --sum
6
$

picocli

TestCommand.scala

package com.example

import java.util.concurrent.Callable

import picocli.CommandLine
import picocli.CommandLine.{Command, Option, Parameters}

import scala.util.{Failure, Success, Try};



object TestCommand {

  def main(args: Array[String]) = {
    System.exit(new CommandLine(new TestCommand).execute(args: _*))
  }

}

@Command(name = "test", mixinStandardHelpOptions = true, version = Array("test sample command 1.0.0"))
class TestCommand extends Callable[Int] {

  @Parameters(arity = "1..*", paramLabel = "N", description = Array("an integer for the accumulator"))
  var integers: Array[Int] = Array()

  @Option(names = Array("-s", "--sum"), description = Array("sum the integers (default: find the max)"))
  var isSum: Boolean = false

  override def call(): Int = {
    Try { if (isSum) integers.sum else integers.max } match {
      case Success(result) =>
        println(result)
        0
      case Failure(exception) =>
        exception.printStackTrace()
        1
    }
  }

}

サンプルを実装したら、実行してみます。(scalaの例ではassemblyで実行可能なjarにあらかじめパッケージングしております)

ヘルプ実行例

$ java -jar test.jar -h
Usage: test [-hsV] N...
      N...        an integer for the accumulator
  -h, --help      Show this help message and exit.
  -s, --sum       sum the integers (default: find the max)
  -V, --version   Print version information and exit.
$

通常実行(--sumオプションなし)

$ java -jar test.jar 1 2 3
3
$

通常実行(--sumオプションあり)

$ java -jar test.jar 1 2 3 --sum
6
$

まとめ

  • コマンド実装をJVM言語で行う時にはpicocliを利用すると面倒な引数のパースを簡略化することができる
  • 使い勝手はpythonのArgumentParserに近くとても使いやすい

ArgumentParserとpicocliを使ってみての感想

以上、pythonとscalaで二つのライブラリを使用して同じコマンドを実装してみましたが、言語差異によるコンパイルなどの手間はありますが、それ以外はpythonでの実装に近い使い勝手だったかなと思いました。

また、今回は簡単な例を実装しましたが、picocliは機能が豊富でドキュメント量が多いのでもっと色んなことができそうです。

まだまだ盛んに開発が行われているので、コマンドやバッチの実装などがある方は導入を検討してみるのもいいと思います。

それでは。

Copyright © astamuse company, ltd. all rights reserved.