kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

いろいろリリースした 〜Re:VIEW、sabatrapd、mackerel-statsd〜

先月末はいろいろOSSに関わってそれらをリリースできたので、記録がてら。

Re:VIEW

github.com

2月28日にRe:VIEW 5.7.0をリリースした(リリースエンジニアリングしてくださった@takahashimさんありがとうございます)。

リリース解説にも書いたけど、ちょうど転職活動〜順応必死時期と重なって、中身をいじる時間が全然取れず、最低限のエラー対処と安定化を施す程度に留まってしまった。

review-knowledge-ja.readthedocs.io

リアル会合の開発会議でこそドライブする面があるので、今年どっかでやりたいんだよなー。

Dockerイメージについては @vvakame さんから反応を早くいただいているのですぐに更新対応がなされるんだけど、技術書典でよく参照される ReVIEW-Template のほうの更新体制に心配がある(@mhidaka さんが超絶忙しそうだ)。EPUBのvalidationエラーとMEMOまわりがあるので早めにマージしたいのと、今後も同様のときにサッと更新したい。あと、紙面的チャレンジも何か盛り込めないかなぁと思ったりしている。

sabatrapd

SNMP Trapのメッセージを監視サービスのMackerelに送りたいねーという雑談からシュシュッと生まれたOSS。2月26日にリリースした。SNMP Trapを受け付けて、Mackerelのアラートとして即時投稿する。

github.com

社内で困りごとを聞く→17日にkmutoが妄想設計書→19日にysetoさんがベース実装→20日にkmutoが機能追加要望→同日にysetoさんが反映実装→24日〜26日でissueとPRを繰り返してプロダクトリリース、という超特急デリバリー。

Go実装やテストフレームワーク・CI/CDはysetoさんにお任せ。私のほうはOSSらしくライセンスやプロダクト名決めたり、ロゴを作ったり、ドキュメント書いたり、systemdサービスユニットやインストーラ書いたり、さまざまに壊れたデータを作って食わせてみてはGoでPANICする部分を捕捉するコードを入れていったり、と周辺整備。

それぞれ得意分野がうまく噛み合ったし、issue/PRだけという非同期縛りのわりには即review approvedが飛び交うライブ感で、プロダクトリリースまで大変楽しく、良い経験。

業務タスクじゃないけどチーム横断的なOSS開発 & バリュー提供ということで、先日金曜に開催された社内の「ほたて賞」で発表して、他の部署からも高評価をいただいた。わいわい。

hatena.co.jp

今後もビビッと来たものには突っ走っていきたいし、OSS開発一緒にやろうず的なお誘いもお待ちしております。

mackerel-statsd

mackerel-statsdは、StatsDプロトコルで届く数値データを受け付けて蓄積し、合計としてのメトリック、あるいは平均/最大/最小としてのメトリックとしてMackerelに1分ごとに投稿するというミドルウェア。2月27日にリリース。

github.com

入社直後に拝見していた社内開発合宿で生まれたOSSで、開発自体には関わっていないんだけど、Mackerelに今足りないものがここにあるやん!(Mackerel自体の粒度は1分ごとなので、1分の間に起きた大きな変動を掴み切れない可能性がある)と期待がふくらんで、合宿には飛び込みでデモを作ったりしていた。

公認のOSS配布物(mackerelio)として名乗るにはいろいろ完成度として厳しいが、素材として良さそうなのでOSS公開してみよう(mackerelio-labs)ということで、このたびmackerel-statsdも公開となった。

自分的に期待感が超高いOSSではあるもののREADMEなしでは紹介しづらい! ということで、ドキュメントを書いてPRして取り込んだ。

荒削りなところはあるけれども可能性はきっといろいろあるはずなので、ぜひ遊んでほしい。

Happy Hacking!

『Web+DB PRESS Vol.133』を読んだ

ようやく読み終わり。また雑なメモで。

gihyo.jp

  • 「サバンナ便り」
    • テストピラミッドの話。コストと忠実性が高く、実行速度と決定性が低いテストはケース数を減らすべき、という考え方。end-to-endのようなユーザー視点に近いテストは決定性が低く、信頼不能テストにつながる。下段のテストを信頼性高くしておく。上段はLargeテスト、中段にMiddleテスト、最下段にSmallテストを配置する。下段中段上段は70:20:10を目安にし、規模拡大につれて80:15:5を目指す。
  • 「TypeScript最新活用」
    • うひょさんらの執筆記事。
    • satisfies構文。式が制約を満たすかどうかをチェックできる。従来の const priceTable: Record<string, number> = { apple: 150, orange: 200 } だとキー情報は使われず priceTable.grapes はエラーにならない。const priceTable = { apple: 150, orange: 200 } satisfies Record<string, number> だとキーも保持されて priceTable.grapes が型エラーになってくれる。
    • 変性アノテーション<T>のところを<in T>(入力されるもの)、<out T>(出力されるもの)、<in out T>(入出力されるもの)と明示できる。使わなくても型推論されるのであまり困らないが、意図が明確でコンパイルエラーでも検出できる。
    • --module node16オプション。Node.jsのES Modules機能取り込み。CommonJS用.cts、ES Modules用.mts。拡張子なしimportをコンパイルエラー。package.jsonのexportsでimport制御をより細かく。
    • moduleSuffixesオプション。React Nativeから使いやすい。
    • 5.0先取り情報。@〜のデコレータ、たとえばバリデーションに使える。--module Resolution bundlerでpackage.json関連の機能のみを利用できる。TS解釈できるバンドラなら.tsのままインポートできる。
    • リンタESLint、フォーマッタPrettier。分離しているのを無理矢理統合していて設定がわかりにくい、パフォーマンスがいまいち。
    • Rustで書かれた統合ツールRome、現在はフォーマッタとリンタが実装。ランタイムDeno、Rust記述で、ツールにフォーマッタとリンタを含む。ともあれ、どちらもまだ未成熟で普及には時間がかかりそう。
    • ESLintのルール。Possible Problems/Suggestions/Layout&Formatting。typescript-eslintプロジェクト。
    • ESLintとPrettierの設定。eslint-config-prettierによる設定方法。確かに手順が複雑…。
    • トランスパイラとバンドラ。古いiPhone持ちのユーザーがOS更新をせず第二のIE化…。開発効率のために高速性を求められる。Next.js/SWC/turbopackのVercel社の勢い。SWCはプラグインが強力。フロントエンドにもRustの波がくる可能性(それはそれで大変そう…)。
    • ランタイム。Deno・Bun・workerdいろいろ出てきてる。Web APIによる相互運用性。NestJSが筆者推し。GraphQLとの組み合わせ。
    • Edge Worker。オリジン手前でリクエストをハンドリング(フィールド値の正規化など)し、キャッシュヒット率を向上。オリジンサーバの処理の委譲。リクエストの事前検証、(否定的だが)コンテンツレンダリングサードパーティスクリプト実行。
  • 「速習Ruby 3.2」
    • mameさんの記事。
    • WebAssembly/WASI対応。最近そういえばどっかでWebAssemblyの話を聞いたな? ruby.wasmがCDNにあるので、「<script type="text/ruby">puts "Hello, world!</script>"」が簡単にできる。DOMのほうに書き出すにはjsブリッジライブラリを使う。生JSがちょっと透ける感じはあるけど、JS慣れしてるとまぁそうか、という感想。課題となっているフットプリントが大きいのは確かにちょっと辛そうなところはありそう。
    • ReDoS脆弱性対応。正規表現によるリソース枯渇。失敗を記録して無駄に計算する前に即時失敗させる。失敗記録にメモリを使うが確保は遅延なので通常はメモリ消費しない。後方参照・先読み・固定繰り返しの繰り返し・巨大な固定繰り返しには適用できない。Regexp.timeoutによるタイムアウト秒数対策。
    • 文法拡張。エラー対処
      • Ruby 3.0では「...」による引数のメソッド丸渡し、3.1でブロックだけに特化した&渡し、そして3.2で通常の引数だけの*と、キーワード引数だけの**が導入。通常引数とキーワード引数だけを委譲する、たとえばfooからbarに丸々引き渡すならdef foo(*, **); bar(*, **); endとなる。不気味な気もする…
      • findパターンで[*, pattern, *]が正式サポート。if ary in [*pre, 10, *post]で要素10の前後をpre, postの配列、if ary in [*, 5, x, *]で要素5の後をxにといった書き方ができる。あー、これ便利そう。事前にsort & uniqしとくといいのかな。
      • Dataクラス。値オブジェクト。フィールドをdefineで定義しておき、キーワード引数でnew。比較はオブジェクト同一性ではなくフィールド値になる(これは比較するの楽だな)。withインスタンスメソッドでフィールドを置き換えられる。機能的には既存のStructクラスをイミュータブル制約したのに近い(実装は全然別)。
      • syntax_suggest gemのデフォルトロード。実行時エラーヒント。error_highlight gem。3.1から入っているが、さらにArgumentErrorやTypeErrorでも情報表示化。ERBコードカバレッジ。そういえばRe:VIEWのERBについてはユーザー側でなんか簡単にエラーチェックできる方法がほしいな。
      • setのデフォルトロード化。
    • 新しいメソッド。全体にイイのが多い。
      • MatchData#deconstruct, MatchData#deconstruct_keys導入。いまいちわからなかったんだけど、とみたさんがいい記事書いてくれてた https://zenn.dev/tmtms/articles/202212-ruby32-13
      • Time.newで文字列から時間作れるの、最オブ高(なんだっけーとparseを探さなくていい。むしろなぜ今までなかったのかというコロンブス)。
      • Enumerator.productは便利ケースありそう。
      • byteindex, byterindex, byteoffset, bytesplice これ前職でほしかったやつだ!
      • ceildev 切り上げ除算
      • IO#timeout うぉー、これ助かりみありそう。Queue#pop, SizedQueue#pop/pushにもタイムアウト導入。
      • String#dedup freezedなStringのコピー。ただし同じ内容のStringがあったらオブジェクトを返すことで重複しない。
      • FileUtils.ln_sr 相対パスsymlink。階層の異なるsymlink参照側から参照先のリンクパスの指定時に、いちいちUnixのFSやsymlinkの仕草に思いをはせなくて済む。よさそう。
      • CGI.escapeURIComponent, CGI.unescapeURIComponent。ほぼCGI.escapeと同じだが空白を+ではなく%20にする。確かに今は%20のほうがよく見るか。
      • メタプログラミング用メソッドが増えてるけど、この領域に手を出してはいけない気持ちがあるので、読むだけにしておく。リファインメントはもしかして使うことあるかな。
      • フレームワークツール開発者向けメソッド。Rubocopのほか、VS Codeの強化につながりそう。
    • libyaml・libffiのバンドルヤメ。psychがビルドされない。これはRe:VIEWにもそのうち影響あるかな? とはいえ、libyamlないとgems, rdocが困るので結局必須とのこと。3末にRuby 2.7がEOL(とはいえDebian stableはまだあるのでそっちはsecurity backport patchだね)。パッチレベル表示廃止。YJIT/MJITの向上。
  • 「Tailwind CSS実践入門」
    • CSSフレームワークのTailwindの話。なるほど、これは確かに不気味さはある。手元でEPUBCSSまわりはobsoleteと言われるCompassをまだ使っていて、次候補は探している。アプローチ的にもTailwindだと合わないなという結論ではあった。
  • 「今こそシェルスクリプト
    • 記事が悪いというわけでは全然なくて、Linuxコンテナ化全盛の状況なのでわかりはするんだけど、SunOStelnetして使っていたのからウィンドウシステム! ブラウザ! という世界へ進化していったのかなと思ったら、またSunOSの時代に戻ってしまって「私たちは本当にこれでいいのかな…?」という感覚がある。宇宙世紀になってもシェルスクリプト書いている可能性がある。
  • 「Goに入りては……」
    • Go 1.20で導入された、複数エラーを1つにまとめる機能の話。goroutineからのエラーをerrors.Join で配列格納できる(エラーがなければnilになる)。errors.Isで指定のエラーかどうかを比較。errors.Asでエラーのフィールドも取得。
    • エラーの値か型の公開が前提。設計時に注意する。
  • Ruby 3標準添付ライブラリ紹介」
    • ベンチマーク。これまであまりパフォーマンスは気にしていなかったけど、benchmark_driverとか使ってみていきたい。
  • Perl Hackers Hub」
    • momochiさん記事。Perlで動的解析だと確か読み込み時即実行できる命令があったので変なもの突っ込まれないかなーとか、ロードで登録するのはいいけどGoみたいに消えてくれないと困らんかなーとか、と読み進めていったらちゃんとその説明があって安心!
  • 「フロントエンドコンポーネント解説」
  • 「SREで開発を加速させる」
    • masayoshiさん記事、最終回。SREのキャリアへ踏み出すにあたっての技術領域、求められるスキル。SREingは総合格闘技
    • ソフトウェア技術スキル: スクリプト・IaCの読み書き。メトリックプラグイン作成。プロダクトコードリーディングと、ログ出力やAPMのための修正追加。パフォーマンス/メンテナンス/信頼性向上のリファクタリング・機能追加。
    • インフラ技術スキル: Webサービスインフラ環境設計・クラウド構築。リソースモニタリング・調査。分散システムなどの複雑なシステムインフラ・モニタリングの設計構築運用。未知の障害への適切な障害対応・ポストモーテム。
    • ソフトスキル: 障害対応コミュニケーション。POやdev-teamとのSLO策定。
    • キャリア形成。ソフトウェアスキルかインフラスキル両方必要で、得意なほうがレベル3以上、もう一方は1以上あたりが最低ラインか。広く浅くというのもアリ。さまざまな技術領域に興味を持って関わっていく好奇心。
    • 基本課題。httpbin/WordPressのようなWebアプリのローカル構築。それをIaC化する。SLOを考えて計測してみる。K8sAPIサーバ化などをやってみる。
    • 障害対応訓練。エンドポイント確認、ログ参照、ロールバックや再デプロイ。SLO観点の説明能力。
    • SRE記事、どれもたいへんよかった。ぜひ膨らませて単行本化しようず。