株式会社クリアコード > ククログ

ククログ


2014年にやりたいことと2013年のまとめ

年の初めなので、2014年にやりたいことと2013年のまとめを書きます。

2014年にやりたいこと

まず、今年やりたいことです。

設立当時からクリアコードが大事にしていることは次の2つです。

  • 継続的にフリーソフトウェアの考えを実践すること
  • ソフトウェアを継続して改良してくいくためにクリアなコードを書くこと

これらを実現するために今年は次のことに力を入れます。

  • フリーソフトウェアの考えを実践している人・実践したい人の採用
  • コミットへのコメントサービスの改良

それぞれ、もう少し説明します。

フリーソフトウェアの考えを実践している人・実践したい人の採用

まず採用についてです。

フリーソフトウェアの考えを実践している人・実践したい人を採用したいです。これは、「働く人が実践したくてそれを会社が支援する」という仕事の進め方を強化したいからです。

これを実現するためには、クリアコードに入ってからフリーソフトウェアに興味を持ったというケースよりも、フリーソフトウェアに興味があるのでクリアコードに入ったというケースの方が自然だと考えました。前者の場合は「実践することを会社が働く人に促す」仕事の進め方になってしまうでしょう。

そのため、すでに実践している人あるいは実践したい人を採用したいという考えになりました。

もう少し背景を説明します。

これまでの応募者や外の人から話を聞くと、クリアコードでのイメージは次のようなものでした。

  • Rubyをやってそう
  • Mozillaをやってそう
  • キレイなコードを書いていそう

一方、「フリーソフトウェアの考えを実践していそう」というイメージはほとんどありませんでした。

イメージではなく実際のクリアコードは、フリーソフトウェアの考えを実践するためにイメージ通りの技術を使っています。Rubyを例にすると、Rubyで開発し、成果物を自由に使えるソフトウェアとしてリリースします。

クリアコードは自社のサービスを提供することで対価を得るのではなく、受託開発で対価を得ています。そのため、成果物を自由に使えるソフトウェアとしてリリースするためにはお客さんと相談する必要があります。相談するときは、お客さんにとってのメリット・デメリットを伝えます。特にデメリットは正直に伝えます。その上で判断を仰ぎます。部分的な場合もありますが、多くの場合は賛成してくれます。クリアコードの仕事は開発して対価を得るだけでなく、成果物を自由に使えるようにするところまで含んでいます。

Rubyを使いたい*1という気持ちはあるものの、フリーソフトウェアに関しては特に思うところがない人にとっては、成果物を自由に使えるようにするという話は面倒なことに感じるでしょう。この場合、クリアコードでの仕事は面倒なことがついてまわる仕事という扱いになります。それは働く人にとってもクリアコードにとってもつらいことです。

成果物を自由に使えるようにすることをやりたいことと感じる人であれば、つらい思いをせず、むしろ積極的に行動できるはずです。そのため、フリーソフトウェアの考えを実践している人・実践したい人を採用したいです。

コミットへのコメントサービスの改良

次にコミットへのコメントサービスについてです。

クリアコードとしては、このサービス自体はよいサービスであり、続けていきたいサービスです。ただし、今のままでよいものではなく、もっとよくしていけるサービスであると認識しています。2014年は、このサービスをよくして、それを実際に提供したいです。

このサービスは、開発チームが「よいコードが当たり前な文化」になるために「みんながみんなのコードを読む」文化づくりを支援するサービスです。それを支援するためにコミットにコメントするという「手段」を使います。そのため「コミットへのコメントサービス」という名前になっています。

実際にサービスを提供したところ、コミットにコメントすること以外にも「みんながみんなのコードを読む」文化づくりを支援するためにできることがいくつもあることがわかりました。それらのフィードバックを反映し、「みんながみんなのコードを読む」文化づくりをよりうまく支援できるようにこのサービスを改良し、実際に改良したサービスを提供します。

近いうちに詳細を発表する予定です。

2014年にやりたいことのまとめ

2014年にやりたいこととして次の2つのことに力をいれたいということを説明しました。

  • フリーソフトウェアの考えを実践している人・実践したい人の採用
  • コミットへのコメントサービスの改良

2013年のまとめ

それでは、2013年のことを月ごとにふりかえります。

1月

設計判断事例の紹介:E4Xの事実上の廃止を受けての、UxUの開発方針の検討では、ふだんあまり言葉にしない、どのように設計判断をしているかということを文章にまとめました。なんとなく決めているようにみえてもいろいろ考えているものなのです。

Ruby用単体テストフレームワークtest-unitでのデータ駆動テストの紹介では、test-unitでのデータ駆動テスト機能の使い方について紹介しました。使いすぎると逆にテストをメンテナンスしづらくなりますが、適切な分量で使えばメンテナンスしやすいテストになるので活用してください。

社宅制度による社会保険料と所得税の削減はクリアコードのお金関係のことの紹介です。

2月

クリアコードのサポートサービスはクリアコードがサポートサービスをどのように提供しているかを説明しています。仕事の仕方を説明している珍しい記事です。回答の書き方の部分を、機会があれば回答の書き方(相手に伝える文書の書き方)についてもっと詳しく説明したいところです。

インターン募集を開始しました。その後、2回インターンシップを実施しました。

るびま0041号の「Rubyコードの感想戦」のお知らせでは、咳さんから文通の返事があったことをお知らせしました。

クリアなコードに囲まれて - クリアコードでの二年間は、クリアコードでアルバイトをしていたおやまださんに、クリアコードがどう見えていたかを書いてもらったものです。

3月

Developer Migration 2013: 「開発者は仕事でリーダブルなコードを書けるのか?」 #devmiは今年最初の発表です。SIerの人向けに話すこともパネルディスカッションも初めてで、発表した側としては得るものがたくさんあったよい機会でした。

ぐんまRuby会議01: 「プログラマー」 #gurubyは今年2回目の発表です。とてもよい雰囲気のRuby会議だった印象と、リベンジしたいような悔しさと、しばらく自重したくなる挫折感が相まって、とても突き刺さるRuby会議でした。

Mac OS XのCocoa版GTK+で日本語入力を行うためのgtkimmodule(GtkIMCocoa)の開発は、OS X上でのGTK+の日本語入力まわりを改善する取り組みです。この後も取り組みを継続して、途中経過を報告しています。

日本OSS奨励賞受賞!しました。数年前から関わっているGroongaの開発チームの一員としての受賞です。受賞者発表ページの「肉の日リリース」の解説がとても詳細だったことが印象的でした。

Sylpheedのプラグインの作り方は貴重な情報です。これほど詳細にSylpheedのプラグインの作り方を解説した文書は他にありません。

4月

Rubyで定義したメソッドの引数にYARD用のドキュメントを書く方法Rubyで定義したメソッドに戻り値のYARD用ドキュメントを書く方法はYARDの使い方をまとめるシリーズの記事です。

Fedoraプロジェクトで新規パッケージをリリースする方法も貴重な資料です。実際にFedoraプロジェクトで新規パッケージをリリースした経験を元にまとめたものです。リリースするまでの作業を時系列でまとめているので流れもわかります。日本語での情報としてここまでまとまっているものは他にないでしょう。

わかりやすいコミットメッセージの書き方は久しぶりにコミットメッセージの書き方をまとめたものです。これを実践することでコミットメッセージがグッとわかりやすくなります。コミットメッセージを書くことに慣れてきたらステップアップのために実践してみてください。なお、これが2013年で一番反応が多かった記事です。

5月

GDBでデバッグするなら-g3オプションはコミットへのコメントサービスを実施しているときのやりとりで出てきた話題をまとめたものです。

働く環境としてのクリアコード(福利厚生編)はインターンとパッチ採用の問い合わせがないのはクリアコードのことをわからないからではないか、と予想し、その状態を解消しようとしたものです。その後、インターンにもパッチ採用にも問い合わせはあったのですが、それまで問い合わせがなかったのはこれが原因ではなかったようです。

GtkIMCocoaの動作状況はこの頃のOS X上でのGTK+の日本語入力周りの話です。前回の記事への反応があったことからXamarin Studioのことを知りました。

コミットへのコメントサービス導入事例のご紹介はミラクル・リナックスさんに導入した事例を紹介しています。現時点でも導入実績はこの1件なのですが、今年は前述のような改良をしながら新しく導入したいです。

RubyKaigi 2013の予告:ステッカー・チラシの配布とRubyHirobaでの企画案と発表内容 #rubykaigiでは、RubyKaigi 2013で発表した「Be a library developer!」の内容を説明しています。RubyKaigi 2013ではまっとうに発表できたので、ぐんまRuby会議01での挫折感を解消することができました。

6月

RubyKaigi 2013にシルバースポンサーとして参加したまとめ #rubykaigiはスポンサー視点でのRubyKaigi 2013の成果をまとめたものです。RubyKaigi 2013きっかけでインターンの応募があったことは特筆すべきことです。RubyKaigiは(うまく活用できれば)宣伝効果があるのです。

クリアコードの1日は、あるクリアコード社員の1日の仕事の流れを説明したものです。なお、この記事の中で触れられている「向日葵」は今は閉店しています。

クリアコードがインターンシップを実施する理由は、インターン候補の人に説明する中で、なぜクリアコードはインターンシップをするのか、ということを言葉で説明できるようになったのでそれをまとめたものです。

問題の原因調査のためのログ収集のセオリーはデバッグの仕方の1つであるログを利用する方法を説明しています。このあたりを論理的に進めることができれば、原因判明までの時間を短くできるので、とても大事な考え方です。

7月

Mac OS X版GTK+における日本語入力対応の近況はこの頃の日本語入力周りの状況報告です。別の実装がGTK+に取り込まれたのでGTK+の標準機能で日本語入力できるようになっています。ただ、いくつか問題が残っていることもわかりました。

クリアコードの開発の様子をフォローしやすくしましたはクリアコードの開発やインターンシップの様子などを誰でも参照できるようにした、というお知らせです。

Fedoraプロジェクトでパッケージを更新するにはは新規パッケージを更新した経験を元に日本語で説明した貴重な資料です。

クリアコードのフリーソフトウェアビジネスはクリアコードがこの7年どうやってお金を稼いできたかを説明しています。

milter manager 2.0.0 リリースは2年ぶりのmilter managerのメジャーリリースのお知らせです。ここで紹介しているtest-mailsプロジェクトは2014年も積極的に取り組んでいく予定のプロジェクトです。

8月

インターンシップで学んだこと1:コメントを書きたくなるときはコードを見直す機会は6月中旬から7月末まで実施したインターンシップで学んだことを文章としてまとめたものです。学んだことはたくさんあり、この後もいくつかまとめていますが、まだまとめられていないことが残っています。

インターンシップで学んだこと2:1人で開発しているときはていねいに開発を進めるはコミットに残らないちょっとした開発テクニックをまとめたものです。

インターンシップで学んだこと3:テストを整理する方法はメンテナンス可能なテストの重要性とその書き方をまとめたものです。

9月

インターンシップで学んだこと4:何をテストするかは、テストを書くときは何に注目しているかを考えると必要最小限のテストを書くことができるのではないか、という話です。

Autotools事始めは今でも広く使われているビルドツールであるAutotoolsの概要について説明したものです。

Rubyで定義したメソッドの使用例をYARD用のドキュメントとして書く方法は久しぶりのYARDの使い方の説明です。おそらく、これが最後になるでしょう。

インターンの作業を進めやすくするための工夫は9月に実施したインターンシップで発生した問題点とそれを解決するために行ったことをまとめたものです。

10月

現状共有の会で進行役をするとき気をつけていることはうまくまとめきれなかった記事です。

Windowsの32bit/64bit版Ruby用バイナリ入りgemをDebian GNU/Linux上で作る方法はRubyの拡張ライブラリー作者には便利な情報です。

消費税率引き上げへの対応はお金の話です。

segv-handler-gdb:Rubyスクリプトがクラッシュしたときにより詳しくCレベルのバックトレースを出力するgemは当時gdbruby.rbが話題になったので対抗して書いたものです。

11月

github-post-receiverの複数サイト対応はGitHubにpushしたらコミットメールを送信する仕組みをGitLabでも動くようにしたという話です。

gettextとバージョン管理システムの相性の悪さを解消する案は.poのメタデータをバージョン管理対象ではなく自動生成可能な情報と扱ってはどうだろうか、という提案です。その後、droonga.orgでこの方法を実装しました。しばらく試してよさそうならdroonga.org以外でも使えるようにパッケージ化する予定です。

Rubyで変数宣言っぽいものをした方が読みやすくなるときはコミットへのコミットサービスを実視している時のやりとりで話題になったことをまとめたものです。

12月

GTK-Docの使い方はGTK+用のドキュメントツールの紹介です。

全文検索エンジンGroongaを囲む夕べ 4での発表資料は毎年いい肉の日に開催しているGroongaイベントでの発表内容の紹介です。

スクリプト言語の拡張機能の作り方とGObject Introspectionの紹介はバインディング作成技術の推移をまとめています。SWIGで知識が止まっている人には役に立つ話なはずです。

パーフェクトRubyのおかげでYARDがよくなってGroongaイベントも開催できた話はちょっとした裏話です。

GObject Introspection対応ライブラリーの作り方は貴重な資料です。日本語で同種の資料はないはずです。

Mac OS X版GTK+の日本語入力対応 その後は最新情報を紹介しています。OS X上でのGTK+の日本語入力周りの話題はこれで一区切りです。

まとめ

2014年にやりたいことと、2013年のことをまとめました。

今年もよろしくおねがいします。

*1 あるいは、Mozillaを使いたい、クリアなコードを書きたい

2014-01-09

メタプログラミングをして割に合うかの判断基準:処理を1箇所に局所化できるか

毎日他の人のコミットをながめる文化で生活していると、理由は浮かばないけど「ん?このコミットはなんか気になる」と感じるようになります。それは、新しいことを知ることができたコミットだったり、真似したくなるようなコードが入っているコミットだったり、なんかまずそうな気がするコミットだったり、様々です。

「ん?」と感じてコミットを見直してみても、何が気になったか自分でもすぐにわからない場合があります。そんなとき、気になったことをコミットした人に伝えるために、コミットへのコメントをまとめ始めます。「コミットした人に伝えるため」というように、他の人に伝えようとすることがポイントです。他の人に伝えるためにまとめようとすると、思いの外なにが気になったかまとまるものです。

今回は、メタプログラミングを使ってコードを整理したコミットで「ん?」と感じたときのことについて紹介します。このおかげで「メタプログラミングをして割に合うかの判断基準」を1つ明確にできました。その基準とは「処理を1箇所に局所化できるか」です。

該当コミットとコメント

このとき「ん?」と感じたコミットはdroonga/fluent-plugin-droonga@1b22308です。

もともと次のようなコードがありました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def format
  formatted_result = {}

  if need_element_output?("count")
    format_count(formatted_result)
  end

  if need_element_output?("attributes")
    format_attributes(formatted_result)
  end

  if need_element_output?("records")
    format_records(formatted_result)
  end

  if need_element_output?("startTime")
    format_start_time(formatted_result)
  end

  if need_element_output?("elapsedTime")
    format_elapsed_time(formatted_result)
  end

  formatted_result
end

これを次のように整理しています。フォーマット対象すべてをHashにしてまとめて扱えるようにし、フォーマットする処理を動的に変えるコードにすることで同じようなコードを1つにまとめています*1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SUB_FORMATTERS = {
  "count"       => :format_count,
  "attribtues"  => :format_attributes,
  "records"     => :format_records,
  "startTime"   => :format_start_time,
  "elapsedTime" => :format_elapsed_time
}

def format
  formatted_result = {}

  SUB_FORMATTERS.each do |name, sub_formatter_method_name|
    if need_element_output?(name)
      method(sub_formatter_method_name).call(formatted_result)
    end
  end

  formatted_result
end

25行あったコードが19行になり、何度もでてきた次のようなコードのパターンがなくなっています。

1
2
3
if need_element_output?(NAME)
  format_NAME(formatted_result)
end

整理されているように見えます。しかし、「ん?」と感じたのです。

コメントをまとめてわかったこと

どうして「ん?」と感じたことを伝えるために、コミットにコメントしました。このコメントを書き始めたときはどうして「ん?」と感じたかわかっていなかったのですが、コメントを書きながらわかってきました。わかったことを紹介します。それは、「メタプログラミングをして割に合うかの判断基準」です。

メタプログラミングをすれば動的にプログラムを実行することができます。プログラムの一部をパラメーター化することでコードの重複を取り除くこともできます。うまく使えばリーダブルにもなります。しかし、使い方によっては理解しにくくなったり、メンテナンスしにくくなったりします。メタプログラミングはうまく付きあうことが難しい機能です。

このコミットで見たメタプログラミングの使い方は割に合わないと感じました。

オーバースペックなメタプログラミング

このケースではメタプログラミングを使わず、次のようにcase whenで十分ではないかと感じました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def format
  formatted_result = {}

  @request.output["elements"].each do |name|
     case name
     when "count"
       value = format_count
     when "attributes"
       value = format_attributes
     when "records"
       value = format_records
     when "startTime"
       value = format_start_time
     when "elapsedTime"
       value = format_elapsed_time
     else
       next
     end
     formatted_result[name] = value
    end
  end

  formatted_result
end

# 参考: formatメソッドで使っていたneed_element_output?の実装イメージ
# def need_element_output?(name)
#   @request.output["elements"].include?(name)
# end

case whenの書き方では行数は24行ともともとの25行とほとんど変わりませんが、重複していた次のパターンは解消しています。

1
2
3
if need_element_output?(NAME)
  format_NAME(formatted_result)
end

どうしてこれで十分なのか。それは、メタプログラミングを使うようにしても、新しくフォーマット対象を追加する時の変更箇所を局所化できていないからです。

メタプログラミングを使うようにした場合、新しくフォーマット対象を追加するときは次のように2箇所変更します。

  • format_XXXというフォーマットメソッドを定義
  • 別の場所にあるSUB_FORMATTERSに定義したメソッドを登録

変更箇所を局所化できていないと、このあたりのコードをいじるたびに、「このメタプログラミングをしているところはどういう仕組みで動いているか」を理解しなければいけません。これは通常のコードを理解するよりも高くつきます。抽象化のレイヤーにヒビが入っていて、違うレイヤーがのぞいてしまっているイメージです。

よって、変更箇所を局所化できるほど抽象化できていないメタプログラミングのコードはオーバースペックと感じていることがわかりました。それなら、メタプログラミングではなくてcase whenで十分だと感じたということです。

逆に言うと、メタプログラミングでやっていることの詳細を知らなくても使えるくらい抽象化しているのであれば、メタプログラミングのメリットを感じているということです。今回のケースだと例えばこんな感じ、というものはコミットへのコメントを参照してください。

その後、このあたりのコードはdroonga/fluent-plugin-droonga@6943d69というようになりました。case whenベースで前述のコードよりさらにスッキリしたものです。

まとめ

「ん?」と感じたコミットに対してコメントをまとめることで「メタプログラミングをして割に合うかの判断基準」の1つが明確になりました。判断基準は次の通りです。

  • 処理を1箇所に局所化できるか

言いかえると、こうなります。

  • メタプログラミングでやっていることの詳細を知らなくても使えるくらい抽象化しているか

このように、自分がどのように感じているか自分でも曖昧なことを明確にできるので、次のことをオススメします。

  • 普段から他の人のコミットをながめる生活を当たり前にする
  • 「ん?」と感じるコミットがあったらどうして自分がそう感じたかをコミットした人に伝わるようにまとめる

これができるようになるお手伝いをしています。興味のある方はコミットへのコメントサービスを参照してください。

*1 method(name)でメソッドで指定した名前のメソッドオブジェクトを取得し、callで取得したメソッドを呼び出します。method(name).call(*args)send(name, *args)と等価です。sendはここでやりたいことを実現するメソッドそのものなので、sendを使った方がコードの意図が明確になります。

2014-01-16

消費税率引上げへの対応 契約時の対応編

はじめに

10月に消費税率引上げへの対応を書いたところ多くのアクセスをいただきありがとうございます。前回の記事の時点では、2014年4月1日の消費税率引上げの日をまたいだ契約はそれほどありませんでした。しかし、この3ヶ月間で締結した契約のほとんどが2014年4月1日をまたぐもので、取引先ごとの消費税率引き上げへの対応がまちまちで調整に時間がかかりました。例えばまだ社内システムが消費税率8%に対応していないので、8%での支払いはできないケースや、2014年3月31日までの支払い分はすべて5%とするケースなどがありました。そこで今回はこのような取引先の事情にあわせて、クリアコードがとった対応を紹介します。

インシデントサポート契約について

今回題材にするのはインシデントサポート契約です。この契約はフリーソフトウェアのサポートを時間制で提供するものです。サポート対象のフリーソフトウェアはmilter managerやMozilla Firefox,Thunderbird、GStreamerなどです。契約内容は期間1年で、たとえば最大30時間まで障害解析など問合せに対応します。価格は消費税別で30万円となります。 このインシデントサポート契約は、契約期間中に作業時間が30時間に達するとその時点で契約終了になります。またサポート依頼がいつ発生するかは契約時には不明で、契約当初に集中することもあれば、毎月ぽつぽつ発生することもあります。作業量が毎月一定ではないため、売上は契約終了時に全額を計上することにしています。もっとも一般的な保守契約であれば、年間保守料を12等分した金額を毎月売上計上するのが通例です。よって、このインシデントサポート契約はサポート契約という名称ではあるものの、契約満了時に一括して売上計上する点において受託開発的な契約と言えます。なお、契約金額の支払い条件は契約開始月末締め翌月末振込を基本としています。たとえば契約開始日2014年1月6日の契約を、2013年12月27日に受注した場合、2014年2月28日支払期日の請求書を2014年1月31日に発行します。

消費税率改定への対応事例

では、インシデントサポート契約の締結にあたって、消費税率引上げに対する取引先の事情を考慮してどのような対応(条件の変更)を行ったのか、事例を紹介していきます。

消費税率8%で前払いとする 契約が3月31日までに終了した場合は3%の差額を返金する

これまでどおりの支払い条件を踏襲した場合は、消費税率8%で前払いとなります。ただし契約が2014年3月31日までに終了した場合は、2014年4月1日をまたいだ契約とならないので5%を適用します。2014年3月31日までの契約にも関わらず8%分の消費税を受け取ったままというわけにはいきません。そのため、もし2014年3月31日までに契約が終了した場合は3%の差額を4月1日以降に返金することにします。このような消費税返金の条件は請求書に次のように記載しています。返金する場合はお客さまから振込先を通知していただく目的で請求書を発行してもらうことにしています。

  • 2014年3月31日時点で契約が終了している場合は、消費税率5%を適用します。この場合、消費税の差額9,000円を5月30日に返金いたします。その際は消費税差額の請求書を2014年4月30日までにお送りください。
消費税率5%で前払いとする 契約が3月31日を超えた場合は3%の差額を4月1日に請求する

もっとも多いのがこのパターンです。大手企業では2014年3月31日までに請求する場合は、2014年4月1日以降の部分も5%で消費税額を計算し、2014年4月1日以降に8%と5%の差額を請求するよう求めているところが多いようです。まだ消費税率引上げへのシステム対応が完了していないお客さまも、消費税率8%で支払うことが困難なため、一旦5%で支払うこの方法を選択されています。このお客さまの場合、8%で後払いにすることも検討されました。しかしお客さまがサポート契約を再販しており、後払いにすることによって下請法違反になることがわかったため、5%で前払いする方法を選択されました。下請法については、公正取引委員会のサイトで詳しく紹介されています。 なお、クリアコードが発行する請求書には消費税の取扱について次のように記載しています。

  • 2014年4月1日時点で契約が終了していない場合は、消費税率8%を適用します。この場合、消費税の差額9,000円を5月末にお支払いいただきます。なお、消費税差額の請求書は2014年4月30日に発送します。
消費税率8%で後払いとする 契約が3月31日までに終了した場合は5%を適用する

インシデントサポートを自社で利用する場合は、下請法の心配はありませんので、後払いで問題ありません。消費税率改定のシステム対応がまだのお客さまはこの方法を選択されています。請求書は契約終了時に発行します。消費税額は契約終了時の消費税率で計算するだけなのでもっとも手間がかかりません。

契約を3月31日までと4月1日からの2本に分割する

消費税率が5%か8%か確定しない契約はできないというお客さまの場合、契約期限を2014年3月31日で一旦切らなければなりません。そのため2014年1月から3月末まで3ヶ月間10インシデントの契約と2014年4月1日から2014年12月末まで9ヶ月20インシデントの2本の契約に分割しました。しかしこの方法は大きなデメリットがあります。例えば2014年2月28日までに10インシデントを使いきってしまうと、1本目の契約は終了してしまいます。そのため2014年3月にサポート依頼をするためには、再度2014年3月31日までの契約を締結しなければなりません。短い期間で複数の契約を締結するのはお客さまクリアコード双方の事務コストが大きくなってしまいます。

まとめ

今回は、インシデントサポート契約を例に、消費税率改定への対応のため、契約条件をどのように変更したのかを紹介しました。下請法を考慮すると後払いにできないということがわかった時はひやっとしました。前払いから後払いへの変更は受注する側にとって契約条件の不利な変更です。あやうくお客さまを下請法違反にしてしまわないよう注意が必要です。また一度支払い条件を変更すると、もとの条件に戻すことは容易ではありません。不利な条件へ変更する場合は、手許現金の減少など自社の財務内容への影響もあるので、慎重に判断することをおすすめします。

タグ: 会社
2014-01-23

監視統合ビューアHatoholのセットアップ方法

はじめに

最近、クリアコードではHatoholというソフトウェアの開発に参加しています。Hatoholは複数の統合監視システムの情報を一括して表示することを可能とするソフトウェアです。現在対応している統合監視システムはZabbixおよびNagiosです。他の監視システムに対応することも検討しています。

なぜこのようなシステムが必要なのかといった背景や、Hatoholの概要については、ミラクル・リナックス社のサイトや、OSCでのミラクル・リナックス社のセミナー資料などが詳しいので、今回の記事では割愛します。

Hatoholプロジェクトでは広く開発者を募集していますが、Hatoholを動かす前提として、最低でも一つのZabbixあるいはNagiosを用意しておく必要があり、またHatohol自体をソースからインストールして利用するまでの手順もまだこなれていないため、開発に参加するまでのハードルはやや高いと感じています。そこで今回は、Hatoholをソースからのビルドしてインストールする方法について紹介します。

なお、CentOS 6.4用にはRPMパッケージも提供しています。ソースからビルドする気力はないが、とりあえずインストールして使ってみたいという方はこちらを利用する方が簡単でしょう。RPMでのインストール方法については、別途ドキュメントを用意していますので、そちらを参照して下さい。

Hatoholの構成

Hatoholは大きく分けて以下の2つの部分で構成されています。

  • 監視情報収集デーモン(C++)
    • 今回の記事では「Hatoholサーバ」と呼称します
  • Web UI (Djangoアプリケーション)
    • 今回の記事では「Hatoholクライアント」と呼称します

ソースパッケージは一つにまとめられているので両者は一緒にインストールされますが、使用のための設定はそれぞれ施す必要があります。

前提条件

  • OS: Ubuntu 12.04
    • Hatoholの公式なサポート対象はCent OS 6.4およびUbuntu 12.04です*1。今回はUbuntu 12.04に対するインストール方法を紹介します。
  • Zabbix 2.0以上あるいはNagios 3以上
    • ZabbixあるいはNagiosは別途用意する必要があります*2
    • Zabbixを使用する場合は、Zabbix API経由で監視情報を取得しますので、Zabbix APIにアクセスできるアカウントが必要です。 また、Zabbixフロントエンドのパスは現在のところ/zabbixに決め打ちされています(例: http://192.168.1.10/zabbix/)
    • Nagiosを使用する場合は、NDOUtilsを用いてNagiosのデータをMySQLで管理し、そこから監視情報を取得します。

Hatoholのインストール

Hatoholのインストール方法は、ソース内の以下のドキュメントにも記されています。

今回は要点のみをかいつまんで紹介します。

依存パッケージのインストール

まず、Hatoholサーバのビルドに必要なパッケージをインストールします。

$ sudo apt-get install \
    git automake g++ libtool gettext \
    libsoup2.4-dev libjson-glib-dev \
    libsqlite3-dev sqlite3 \
    libmysqlclient-dev mysql-server \
    uuid-dev

次に、Hatoholクライアントの実行に必要なパッケージをインストールします。Djangoの動作に必要なPythonのパッケージはpipでインストールします。

$ sudo apt-get install python-pip python-dev
$ sudo pip install django==1.5.4 mysql-python

Hatoholクライアントの実行には、他にBootstrap が必要です。Bootstarpのインストールについては後述します。

Hatoholのソースコードの取得

HatoholのソースコードはGitHubで公開しています。以下のコマンドで、GitHubから最新のコードを取得して下さい。

$ git clone https://github.com/project-hatohol/hatohol

最新のコードではビルドに失敗するなどの問題がある場合は、リリース時点のコードをチェックアウトして試して下さい。

例) リリースタグの確認およびバージョン13.12のチェックアウト

$ git tag
13.12
$ git checkout 13.12
ビルド手順

ソースディレクトリ下で以下の手順を実行してビルド・インストールします。

$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ sudo /sbin/ldconfig
Bootstrapのインストール

Hatoholクライアントの実行にはBootstrapが必要ですが、Hatoholのソースには含まれていませんので別途インストールする必要があります。本記事執筆時点でのBootstrapの最新版は3.0.3ですが、Hatoholではまだ3系に追従できておりませんので、Bootstrap 2.3.2を取得して下さい*3

取得後、zipアーカイブ内の「css」「img」「js」以下のファイルをそれぞれHatoholクライアントの対応するディレクトリ下にコピーします。

$ unzip bootstrap.zip
$ sudo cp -r bootstrap/* /usr/local/libexec/hatohol/client/static/

上記ではインストール先である/usr/local以下にコピーしていますが、Hatoholクライアントはソースディレクトリから直接実行することもできます。開発中はこちらから実行する方が手軽でしょう。その場合はソースディレクトリ以下にコピーします。

$ cp -r bootstrap/* /path/to/hatohol/client/static/

Hatoholサーバのセットアップおよび実行

Hatoholは以下の2種類のDBを使用します。

  • MySQL: 設定保存用
  • SQLite3: 監視データのキャッシュ用

それぞれ、Hatohol用のDBおよびディレクトリを用意する必要があります。

設定の準備

MySQLへのDB作成および設定の投入は、hatohol-config-db-creatorというコマンドで行うことができます。投入する設定は、テキストファイルで記述します。ソースツリー内の以下のパスにサンプルがありますので、これをコピーして必要な箇所を修正して下さい。

いくつか設定項目がありますが、ひとまず必要なのは、監視するZabbixあるいはNagiosの設定でしょう。以下に該当行のサンプルを示します。

server: 0, localhost, 127.0.0.1, My machine, 80, 30, 10, Admin, zabbix

先頭の"server: "は設定カテゴリ名ですので、このまま記述します。以降はカンマ区切りで各設定項目を記述します。各項目の意味は、順に以下の通りです。

  • サーバ種別 (0: Zabbix, 1: Nagios)
  • ホスト名
  • IPアドレス
  • ニックネーム
  • ポート
  • ポーリング間隔(秒)
  • 接続エラー時のリトライ間隔(秒)
  • ユーザー名
  • パスワード
  • DB名(Nagiosのみ)

設定ファイルの準備ができたら、hatohol-config-db-creatorで設定を投入します。

$ hatohol-config-db-creator hatohol-config.dat
キャッシュディレクトリの準備

監視データ(SQLite3のDBファイル)を格納するディレクトリは、デフォルトでは/tmpを使用します。任意のディレクトリに変更することもできますので、変更したい場合はあらかじめディレクトリを作成しておきます。

作成例:

$ sudo mkdir /var/lib/hatohol
Hatoholサーバの実行

以上でHatoholサーバの最低限の準備は完了です。準備が整ったら、以下のコマンドでhatoholサーバを起動します。

$ sudo hatohol

上記のように何もオプションを指定しない場合、hatoholはデーモンモードで起動します。しかし、開発中の場合はコンソールにログを表示しながら実行するのが便利です*4。「--foreground」オプションを付けてhatoholを起動すると、hatoholをフォアグラウンドで実行することができます。

$ sudo hatohol --foreground

キャッシュディレクトリを変更したい場合は、環境変数HATOHOL_DB_DIRを与えてhatoholを起動します。

$ sudo HATOHOL_DB_DIR=/var/lib/hatohol hatohol --foreground

より詳細なデバッグログを出力したい場合は、環境変数MLPL_LOGGER_LEVEL=DBGを与えます。

$ sudo MLPL_LOGGER_LEVEL=DBG hatohol --foreground
動作確認

HatoholサーバはRESTインターフェースを提供していますので、wgetなどで動作を確認することができます。

$ wget http://localhost:33194/hello.html

ただし、Hatoholサーバ上のリソースを取得するためには認証が必要なため、単純に上記のようなアクセス方法ではエラーが返されます。

{"apiVersion":3,"errorCode":22}

ひとまずHatoholサーバが動作していることは上記でも確認できているため、ここではこれ以上深入りしません。

Hatoholクライアントのセットアップおよび実行

セットアップ方法

Hatoholクライアントは、自身の設定をHatoholサーバとは別にMySQLに保持します。このDBについても事前に用意しておく必要があります。

$ mysql -u root
> CREATE DATABASE hatohol_client;
> GRANT ALL PRIVILEGES ON hatohol_client.* TO hatohol@localhost IDENTIFIED BY 'hatohol';

DB作成後、Hatoholクライアントディレクトリ下で以下のコマンドを実行してテーブルを作成します。

$ cd path/to/hatohol/client
$ ./manage.py syncdb
Hatoholクライアントの実行

HatoholクライアントはApacheなどのWebサーバを使用して動作させることを想定していますが、開発中はDjangoの開発サーバを使用するのが手軽です。Hatoholクライアントディレクトリ下で以下のコマンドを実行してWebサーバを起動します。

$ ./manage.py runserver
動作確認

Webブラウザでhttp://localhost:8000/viewer/にアクセスし、起動していることを確認します。hatohol-config.datでユーザーの設定を特に変更していない場合、初期の管理者アカウントは以下になります。

  • ユーザー名: admin
  • パスワード: hatohol

まとめ

Hatoholプロジェクトへの参加者が増えてくれることを期待して、Hatoholのインストールおよび実行方法について駆け足で説明しました。Hatoholは開発がはじまってまだ間もないソフトウェアですので、ソフトウェア自体の完成度の面でも、プロジェクト体制の面でも足りていない部分が多々あります。今回の記事をきっかけに、Hatoholに興味を持って協力して頂ける方が一人でも多く現れてくれることを願っています。

Hatoholプロジェクトの現状や、より詳しい情報ついては、また機会を設けて紹介する予定です。

*1 ちなみに、筆者の現在の開発環境はUbuntu 13.10ですので、厳密にこのバージョンでなければ動かないというわけではありません。

*2 今回の記事ではこれらのセットアップ方法については扱いませんので、環境が無い場合はWeb上の他の記事などを参照して下さい。

*3 ただし、近い将来に3系に移行するはずです。

*4 デーモンモードの場合、ログはsyslogに記録されます。

2014-01-31

«前月 最新記事 翌月»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|