つばくろぐ @takamii228

知は力なり

ライブラリやプラグインを使うときに気にしていること

アプリケーション開発において実装したい機能を実現するために、世の中に公開されているライブラリやプラグインを使ってフルスクラッチでの実装の手間を省くことがあります。その一方で、プラグインを理由にプラットフォームのアップデートを断念したり塩漬けにしているシーンをよく見かけました。

これまでJenkins、WordPress、Flutterとプラグインを選定する場面が多くあったなーと思っていて、知らず知らずのうちに自分の中での選び方の基準みたいなものができつつあったのでここで言語化しておこうと思います。

なお機能的な要件を満たすことは大前提となるのでここでは省きます。

1. 公式のプラットフォームで公開されていること

野良プラグインは怪しさ満点です。公式のマーケットプレイスで公開されているもの、さらに言えば公式が認めているもの(公式バッチがついている、メンテナーが企業になっている等)を使いましょう。

また実際にどう動いているのかソースが追えるようにGitHubでソース公開されているものを利用しましょう。

2. 評価が高く、利用実績が豊富であること

他の人も利用していて、かつ評価が高ければ、信頼度もあります。

3. ドキュメントが充実していること

2の裏返しかもしれませんが、ドキュメントがあると使いやすいですよね。

4. ライセンスの自由度が高いこと

MITやApache2.0など、再利用に関して自由度が高いものが法的リスクが低いです。

5. 更新が活発であること

プラグインが動作するプラットフォームや依存するソフトウェアに追従できていないと、あっという間に負債になってしまいます。

GitHubを見に行ってcommit数が順調に伸びていたり、Issueに対してきちんと対応されているかを見ましょう。

6. プラグインの内部のライブラリの依存リスクが明確になっていること

利用しているライブラリやプラグインが依存するものが大きいと、結局そこがボトルネックになってしまいます。

プラグインの中で依存するライブラリの中に、枯れたライブラリがないか目を通しておきましょう。

7. いざとなったら自分たちでメンテナンスできること

最終的に利用を続けるとなったときに、自分たちでパッチを充てたり修正していける内容なのかを見ましょう。

仮にそうだったとして、そのプラグインを使い続けるのか、余裕のあるときに自分で独自実装してしまうのかは再度立ち返って考えてみるといいと思います。


結局はソフトウェアのバージョンアップライフサイクルを考えたときに、それに依存するものを切り分けて、メンテナンス対象としてどう扱っていくかをきちんと考えよう ということなのだと思います。最近は言語やFWのバージョンアップライフサイクルは早く、1年も経てばあっという間に古くなってしまいます。

三者の成果物を利用することは実装の手間を省くことができる一方で、時間が経ってから自分たちが取り扱えなくなったり依存関係によって更新できない負債と化すリスクもあるので十分注意しながら選定したいものです。

App StoreとGoogle Playの評価を日時で通知する

自分たちが関わっているサービスに関する世の中からのフィードバックを確認することは、そのアプリのマーケットでの立ち位置の把握や開発チームのモチベーションを維持する上で重要です。

iOSであればAppStore、AndroidであればGoogle Play上でユーザから5段階評価とコメントが載せられています。

ここの情報をチャット上に日時で通知する仕組みを作ってみたのでまとめます。

Nodeのモジュールでスクレイピング結果を取得する

いろいろ検索してみたら、ちょうどよさそうなnpmモジュールがあったので、Node.jsで書くことにしました。

www.npmjs.com

www.npmjs.com

こんな感じでアプリケーションのIDと言語を指定するだけでスクレイピング結果をJSONオブジェクトとして取得できます。今回はサンプルとしてChromeアプリを使います。

const store = require('app-store-scraper');

const iosAppId = '535886823';
const iosReview = store.app({id: iosAppId, country: 'jp'});

iosReview.then(function(value){
    console.log(value);
});

Google Playの場合

const gplay = require('google-play-scraper');

const androidAppId = 'com.android.chrome';
const androidReview = gplay.app({appId: androidAppId, lang: 'ja', country: 'jp'})

androidReview.then(function(value){
    console.log(value);
});

Androidの方はscoreGoogle Playで表示されている値がとれそうですが、iOSの方はappではscoreの値は0.5刻みで丸め込まれているようなので、ratingsから自分で平均点を計算します。

const store = require('app-store-scraper');

const iosAppId = '535886823';
const iosRatings = store.ratings({id: iosAppId, country: 'jp'});

iosRatings.then(function(value){
    console.log(value);
   // 自分で平均点を計算
    var rate = (1*value['histogram']['1'] + 2*value['histogram']['2']
    + 3*value['histogram']['3'] + 4*value['histogram']['4'] + 5*value['histogram']['5']) / value['ratings'];
    console.log(rate);
});

結果

{
  ratings: 8103,
  histogram: { '1': 1998, '2': 918, '3': 1269, '4': 1426, '5': 2492 }
}
3.184622979143527

チャットへPOSTする

あとはこの結果をSlackやMattermostへ連携するだけです。それぞれWebhookのURLを発行し、POSTのリクエストを組めばOKです。

slack.com

docs.mattermost.com

今回はMattermost用に作っていて、Slackでも使えるように拡張しようと調べたときに気づいたのですが、Slackの投稿領域のMarkdownって結構制約があるんですね。表が使えない。

www.markdownguide.org

コード一式はGitHubにまとめました。よかったら参考にしてみてください。

github.com

実行するときはnodeコマンドでスクリプトを実行すればOKです。

$ npm install
$ node app.js

f:id:takamii228:20200223163229p:plain

f:id:takamii228:20200225123453p:plain

無事表示されました。

これをAWS LambdaやGitLab CI/JenkinsのScheduledジョブに設定しておくことで、毎日のストア評価の変化を追うことができるようになります。

ポストモーテムを書いて障害対応による修正・改善のWhyを残す

障害や問題が発生したときに行う振り返りのことをポストモーテムと呼び、SRE本の15章でも紹介されています。

また、実際に実践している会社の事例もブログで紹介されています。

inside.pixiv.blog

developer.hatenastaff.com

quipper.hatenablog.com

私の今のチームの開発でも活用すべく、上記を参考にポストモーテムのサンプルのテンプレを作ってみました。

# 1.起きた事象

発生した事象を事実ベースで時系列で書く。
起きた事象がひと目でわかるタイトルをつけるとよい(「テレビ放映でアクセス増加に伴うDBダウン」など)

# 2.影響範囲

起きた事象によって発生したサービスに対する直接的、間接的影響を列挙する。

# 3.暫定対処

発生した事象を復旧させるあたって暫定的に対処した内容を書く。

## 3-1. 対応策候補

暫定対処として候補にあげた解決策を列挙し、最終的にその選択肢を選択した理由を書く。

## 3-2.アクション事項

暫定対処を完遂するために実際に行ったアクションを書く。

# 4.原因分析

## 4-1.直接原因

事象が発生した直接的な原因を書く。

## 4-2.根本原因

事象が発生した根本の原因を書く。

# 5.恒久対処

## 5-1.対応策候補

恒久対処として候補にあげた解決策を列挙し、最終的にその選択肢を選択した理由を書く。

## 5-2.アクション事項

恒久対処を完遂するために実際に行ったアクションを書く。

# 6.その他

上記以外の内容があれば書く。

実際に書くときは判断や対処のWhyを残すことを念頭において、事実と仮説を分けて記述することおよび最終的な意思決定に至った過程を残すことを重視しています。

なぜなら、そのとき行った対処が1年後・2年後も正しいとは限りませんし、実際に開発・運用するメンバーが入れ替わってチームのスキルレベルが変われば最適な策は変わりえます。

なので今その設定になっている根拠や捨てた選択肢を残すことは将来的に技術的負債にならないための予防策と言えます。

今負債になってないものが将来も負債にならない保証はないのです。

似たような思想で設計のWhyを残すADR(Architecture Decision Record)もありますね。

adr.github.io

kawashima さんの日本語訳

https://gist.github.com/kawasima/e325eda1c910d2abc5fb5f69d6a692e2

簡易ポストモーテム / ADRでちょっとした修正・Whyを残す

ポストモーテムやADR開発プロセスや運用プロセスに組み込んで使うことを想定しているもののため、結構腰を据えて時間をかけて書かないといけません。

そのまま使うと結構重そうだったので、ちょっとした内容を残すときにも使えるように簡易的なテンプレートを作ってみました。 この簡易的なものをドキュメントに残す文化を作っておくと、属人的で暗黙的になっているちょっとした知識をチームの集合知として昇華できるのでおすすめです。

例えば開発の初期段階での検討事項の一部が漏れていて、終盤になってちょっとした問題が発覚したケースや、QAで発覚した軽微なバグ修正の横展開のメモを残すような用途を想定しています。

30分~1時間くらいで書けるくらいシンプルな内容にするため、事象・原因・対処の三点セットがあればよいでしょう。これらの内容はIssueや修正のPull Request、チケットなどに記述し、あとで参照可能な状態にしておくことが大事です。

# タイトル

ひと目でわかるタイトルを書く

## 発生事象

何が起きたかを書く。

## 原因 

事象が発生した原因を書く

## 対処

解決策を書く

例えばGitLab CIがエラーでジョブが失敗したケースは以下のような内容を書きます。

# GitLab CIがJob's log exceeded limit of 4194304 bytesで失敗する

## 事象

GitLab CIのジョブが「Job's log exceeded limit of 4194304 bytes」のエラーが発生して失敗する。

## 原因

ログの上限設定がデフォルト値(4096KB)のままになっていて、GitLab CIのログ上限に達してジョブが失敗した。

## 対処

GitLab CI Runnerの設定で.gitlab-runner/config.toml のoutput_limitを拡張する。

...
  executor = "shell"
  output_limit = 16384
...


参考 : https://gitlab.com/gitlab-org/gitlab-runner/issues/1024

これがチームメンバ一人ひとりが自律的に書けるようになるチームを目指して、引き続きEM業を頑張りたい所存です。

SRE Next行きたかったな・・・。。。