Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するClassi株式会社の開発者ブログです。

Classiの技術選定に対するスタンス

VPoTの丸山です。本日はClassiがいまのところどういうスタンスで技術選定に臨んでいるのかについてお話しします。これは「いまのところ」のスタンスであり、未来永劫このようなスタンスでいくかどうかというのは定かではありませんが、考え方のひとつとして参考になれば幸いです。

技術選定にハードリミットはかけない

結論から言うと、Classiでは「この技術スタックを必ず使ってください」という制限はかけていませんし、かけるつもりもいまのところありません。その理由は大きくふたつあります。

ひとつは、組織全体の視点でみた時に、技術スタックに関する健全な新陳代謝の機会を奪わないため、もうひとつは、メンバーレベルの視点でみても、複数の技術に触れる機会が成長につながるからです。

新陳代謝を行う機会を奪わない、というのは、どういうことでしょうか。

ひとつの技術スタックを極めていくことにも良い点はあります。ノウハウ、知識が集約されるので、高い効率で業務を進めていくことができるのはその最たる例でしょう。一方、すべての技術にはその得意とするところと苦手とするところがあります。たとえば、Go言語などは、高い並行性が求められるような要件に対しては得意だが、一方でコレクション処理を楽にかけた方が嬉しいような領域については少し苦手とするところ(まあ腕力でかけばいいので、そんなに問題にならない、という見方もできますが)でしょう。そして、プロダクトに技術的に必要とされることは決して現在過去未来を通じて一定ではありません。世の趨勢が変わり始めたときに、求められる要件に柔軟に対応していくためには、社内での技術の新陳代謝が健全に行われる必要があるでしょう。これはそんなに難しく考えなくても、たとえばEC2でapp serverを動かしていたのをECS Fargateで動かすようにしていくというような例を考えたらわかりやすい話だと思います。実行基盤のみに限らず、フレームワークや言語などについても「変化のための余白」を残しておくことは重要です。

もちろん、これが「正解のスタンス」だとは思っておらず、Classiにとってはそのほうがよい、というだけなので、採用戦略や、現在のメンバーの人数など様々な変数を見た結果、ノウハウ、知識が集約されるメリットを取るような判断も十分にあり得るはずです(この技術といえばこの会社! というのは強いですよね)。

では「メンバーにとっても複数の技術に触れる機会が成長につながる」というのはどういうことでしょうか。

この話題は、事実判断ではなくてかなり価値判断よりの話になってしまうのですが、すくなくとも私は、異なった思想をもった言語や、異なった思想をもったフレームワーク、あるいは実行環境を学んだときが、エンジニアとして非連続な成長を実感できるときでした。それもそのはずで、エンジニアリングというのは常に判断の連続です。ある変数の名前をどういう名前にするのかだって判断ですし、どういうクラスをつくてどうモデリングするのかも判断の連続です。「正解」が用意されていてそれを選べばいいだけの仕事ではなく「より良い方法」を常に探し続けるのがエンジニアの仕事のはずです。そのとき、異なった考え方、異なった視座を身につけていることは、とても強力な武器になります。ひとつの問題を複数の視点から検討することで、「より良い正解」に辿り着けるはずです。言い方を変えれば、ひとつの見方しかできないエンジニアは「正解」に従うことしかできないが、複数の見方を身につけている場合複数の選択肢から「より良い正解」を導ける可能性がぐんと上がるはずです。

もちろん、業務で使っている技術スタック以外にもプライベートで学習することでこのような複数の見方を身につけることは可能ですが、結局のところ業務で扱うのが一番よく身に付く、というのはあると思います。

別の考え方として「ひとつの技術を深く掘っていった方が、隣接領域をすぐに理解できる」という考え方もあり、それはそれで十分に合理的な考え方だと思いますが、少なくとも弊社としては「業務で複数の考え方に触れるチャンスがある(必ずしも全員が触れるわけではないが……)」というほうがより良いだろう、という価値判断をしています。

どうやってガバナンスを効かせるか

一方、技術スタックを制限しない場合、無制限に好き勝手技術スタックを選択されてしまうと、今度は管理上の問題が生まれます。「やる気のあるメンバーがめっちゃ新しい技術スタックでキラキラした開発をおこなったけど、それをメンテ、運用できる知見は誰ももっていないあるいはだれにも継承されず、あとには触るに触れないコンポーネントが残った……」というような話は、残念ながらよく聞く話ではないでしょうか。

いまのところ、Classiでは「新しいことやるときは相談してね」くらいのゆるいガバナンスで運用しており、大きな問題につながっていませんが、そろそろこのあたりのガバナンス設計あるいは知識の流通の設計を始めていかないと、結局のところ先に見たメリット(組織としても新陳代謝ができるし、個人の成長にもつながるよね)も得られないという未来が見えつつあります。そのあたりはマネージャー陣と相談しながら、今後の課題として取り組んでいく必要がありそうです。

まとめ

今回はClassiの技術選定に対するスタンスと、今後課題になりそうな部分を紹介しました。技術選定についてはかなりいろいろな要因が絡む難しい話題であり、それこそその組織の置かれている状況によって「より良い解」が異なるトピックです。Classiのスタンスをあくまで一例として紹介しましたが、なにか参考になるような部分が少しでもあれば幸いです。

Classi初の新卒データサイエンティストが研修を終えて

こんにちは、今年の4月にClassi初の新卒データサイエンティストとして入社した白瀧です。 私が入社して2ヶ月強の新卒研修を終えた振り返りを書きたいと思います。

アウトプット会をgatherで開催した時の図

新卒研修をやるにあたっての私の心構え

新卒入社前にインターン生としてデータAI部にjoinしていたため、データAI部でのオンボーディングや研修は済んでいました(インターン内容はインターン体験記に書いています)。そのため新卒研修ではエンジニア研修に参加する形になりました。
学生時代はPython, R, SQLくらいしか触ったことがなく、エンジニアっぽいことを全くしたことがない状態でした。(なんなら避けてきてました…)

エンジニア研修をやることで以下のようなメリットがあると考えました。

  • 今後のキャリアを考えるとエンジニアのスキルもあると良さそう
  • 各言語やサービスでどういうことができるのかを知っておくと視点の幅が広がりそう
  • コードをなんとなく読める状態にしておくとできることの幅も広がりそう、エンジニアと多少の会話ができそう
  • データサイエンティストとしてのキャリアで進んだら、今後経験できる機会がなさそう

この考えから、とにかく知見を増やすことと、幅広く体験してみることを意識して研修を受けるようにしました。

新卒研修の内容

新卒研修を進めていく中で、先輩エンジニアが新卒それぞれにサポーターとして付いていただき、いつでも質問ができるような環境でした。 新卒研修での主な内容は以下になります。

  • Git & GitHub
    • 今まで個人開発が多く、割と適当に使っていたので体系的に学び直すいい機会だった
  • HTTP + Webセキュリティ
    • アウトプット会の実施
  • HTML & CSS & JavaScript
    • 自己紹介ページの作成(人生初のwebページ作成)
  • AWS
  • Ruby on Rails
  • Webセキュリティ
    • KENRO
    • アウトプット会の実施
  • SQL
  • データベース設計
  • RSpec
  • CI
  • Docker
    • ずっと後回しにしていたので、しっかり勉強できてよかった
  • TDDBootCamp
  • 万葉カリキュラム
  • メンタルヘルス研修の一環で外部の人に協力してもらった
  • 社内の方からの講義
    • webセキュリティ講義
    • そーだい塾
    • igaigaさんによるRuby, Rails, テーブル設計講義
    • 金融教育講座
    • アジャイル研修
    • 質問力研修

研修に使用した参考書

私は配属や配属後に参加するプロジェクトも決まっていたことから、研修期間内に以下のようなことも行いました。

その他にも、雑談タイムやウェルカムランチ(話してみたい人とランチをする会)などを通して様々な人と交流する機会も多くありました。 このような研修期間中に社内の情報をキャッチアップできたため、研修から実務へもスムーズに移行することができました。

新卒研修を通して学び/感じたこと

学んだことを書こうと思うとほぼ全部書くことになってしまうので、今回は技術的なところ以外での学びや気づきを書きます。

エンジニア研修での学び

「新卒研修をやるにあたっての私の心構え」で記載した知見を増やす・幅広く体験してみるという目標を設定していました。 この目標についてサポーターの方と認識が揃っていたため、すごく動きやすかったです。また進捗に応じてスケジュール調整していただき、自分のペースでじっくり作業ができたため周辺知識を得ながら幅広く経験できたと思います。

またデータベースを含めたアプリケーションの開発は、データサイエンティストとして働く上でエンジニアとの関わりが重要になる部分だと感じました。それを自分で設計から考えたというのは今後エンジニアの方とのコミュニケーションを図る上でもいい経験になったのではないかと思います。

アクションを起こせ

とにかくやってみる、聞いてみる、手を上げてみるということを学びました(これが一番の学びかもしれない)。 この学びのきっかけをいくつか挙げてみます

  • 同期の行動力
  • アクションを起こした時にリアクションが多い
    • 新卒カードも追い風か?
  • アクションを起こした時に応援してくれる
  • アクションを起こした後、サッとサポートしてくれる

アクションを起こしやすい環境であり、アクションが推奨されていることを実感しました。ClassiのValueであるMake Happenはこういうことなのかなと学びました。

私自身も2ヶ月後面談で「良い意味で空気を読まない方がいい」ということを部長から言われて、少しずつアクションが起こせるようになってきているのかなと感じています。 具体的に私が起こしたアクション例は以下です。

  • 読んでおいた方がいいと言われた記事をまとめる
  • サービスを触ってみる会の企画
  • ペアプロのドライバーを名乗り出た
  • 依頼された分析タスクに手を上げた

この姿勢をこれからも続けて、よりアクションを起こせるように頑張っていきたいです!

Classiを触ってみる会を告知した時の社内のリアクション

サポートの仕方

サポーターの方に質問した時に、サポーターの方はすぐに答えを教えるのではなく、その人の力で解決できるようにサポートしていただきました。自分で解決する力も必要ですし、そういう仕方のサポートがいいな!と思いました。 具体的には以下のような方法でした。

  • この資料とか参考になるかも?
  • こうやって調べてみるとなんかいいかもよ
  • この辺りのドキュメントを探ると良さそう
  • 「なにが原因だと思う?」などの質問を通して状況を整理してもらう

これによって、どういうところがわからない時に何をどうやって調べると良さそうかを学ぶことができました。自分がサポートする時にはこのスキルを身につけたいです。

最後に

このブログをまとめている中で、あっという間の2ヶ月だったなと思うと同時にすごいたくさんのことに触れることができたいい機会だったなと感じました。 それも充実したカリキュラムを用意していただき、スケジュールを柔軟に調整して、手厚いサポートがあったおかげです。ありがとうござました!!!

この恩を配属後のチームで還元していきます!!新卒らしく色々動いて、スポンジのように吸収していきます!

アラート対応で気をつけていること

こんにちは!開発本部の id:lime1024 です。

アラート対応について社内で esa にまとめていたところ、参考になると社内でフィードバックをいただいたので開発者ブログでも紹介します。

前提として、平日日勤帯でのアラート発生を想定しています。

対応するときに気を付けていること

初動は早くする

アラートが発生しているという状況を把握して報告するのは、一分一秒でも早くするように心がけています。

Classi では Datadog の Monitor を使っており、その通知先が Slack になっています。基本的には各アプリケーションのオーナーであるチームにメンションが飛ぶようになっているので、メンションが飛んできたらまずは該当のアラートを「見ること」を、アラート対応のためのチャンネルに書きます。 「見ること」を書くことで、アラートが出ても誰も見ていないという状態を防ぐことや、一人で見る自信は無いけれど誰かと一緒であれば見てみたいという人も反応しやすくなります。

なにはともあれ反応する

自分にメンションが飛んできているということは、対応する必要があるからです。もし、メンションが来ているけれど反応しない・または反応する必要がないときは、メンションを投げる先が間違えているか、しきい値が間違っているのでアラートがオオカミ少年にならないように見直しを行います。

もしも、通話中だったり忙しいときは今やっていることが障害対応より優先されるものかどうかをまず考えます。とは言え、本当に忙しくて対応が難しいときはあるので、そのときは "誰か見れませんか?" と書きます。

何を見ているか・何を対応しているかを外からわかるようにする

アラートに対していま何をしているかは、アラート対応のためのチャンネルでオープンにやるようにしています。オープンにやるというのは以下の 2 点です。

  • 基本的には Slack のスレッドには書かない・書いてもスレッドの外に出す (Also sent to #channel)
  • アラート対応のためのチャンネル以外で対応しない

アラート対応の様子が気になって後から覗きに来た人の目線で考えると、Slack のスレッド機能では状況が見えにくいです。ただし、すでに収束していて調査内容をまとめるときや状況整理を行うとき等はスレッドに書くこともあります。同様にアラート対応のためのチャンネル以外に状況が記載されていると後から来た人がキャッチアップをしづらくなります。

また、どんなに対応が進んでいても、状況が書かれていないと外から見ても分からないため、定期的に対応状況のサマリを書くようにしています。特に複数人で通話しながら対応しているときに通話内で情報共有が進み、通話外の人への共有漏れが発生しがちになるため、気を付けるようにしています。

アラートの内容がわからないとき

わからないことを表明する

わからないからアラート対応をしなくてもいいわけではないので、わからないときはわからないことを表明するようにしています。すると、人がわらわら集まってきます。

もし誰も集まらなかったときは、ちょっとドキドキしますが Slack で @channel します。

何がわからないか深堀りする

いま出ているアラートに対して、自分がわからないのはアラートの内容なのか、それともアラートが発生しているアプリケーションのドメイン知識が無いのかを深堀りします。

アラート発生時の初動の時点では、アプリケーションのことはわからなくてもある程度はなんとかなりますし、アラート内容のこともアプリケーションのこともわからなくても見れるものはあります。自分がドメイン知識を持っていないアプリケーションでアラートが発生したときは以下のことを確認しています。

  • 該当のアプリケーションがいま動いているのか・体感で遅くなっていないかをブラウザから実際にアクセスして確認する
  • レスポンスタイムが遅くなっているのであれば、それはどのエンドポイントなのかを Datadog から特定する
  • 5xx エラーが出ているのであれば、それは ALB からなのか ECS からなのかを確認する
  • 該当のアプリケーションの ECS コンテナは生きているか・再起動を繰り返していないか
  • 該当のアプリケーションで直近でリリースは無かったか

以上のことを確認している間に、アラートに気付いた他の人達が集まってくれるはずです。

解決しようとしない

わからないものはわからないので、アラートに反応して対応もしたけど解決できなかった...と思わないようにしています。実際に解決する人・解決できる人の一助になれたら良いくらいの温度感でいるようにしています。

さいごに

アラートが発生してどうしよう!?となったときにこの記事を思い出して頂けたら嬉しいです。

社内向けのデータ基盤から集計結果をReverse ETLしてサービスに組み込んだ話

こんにちは、データエンジニアの滑川(@tomoyanamekawa)です。
Classiでは2022年5月に学校内のユーザー利用状況を集計し可視化したダッシュボード機能をリリースしました。
この機能のデータ集計は既存の社内用データ基盤からのReverse ETLで実現しました。
そのアーキテクチャの説明と「社内用データ基盤」から「ユーザー影響あるシステムの一部」になったことによる変化について紹介します。

ダッシュボード機能とは

  • 概要
    • 先生のみが利用可能な機能
    • 先生と学年・クラスごとの生徒の利用状況を可視化したダッシュボードを提供する機能
  • 要件・制約
    • アプリケーションはAWS上で動かす
    • 前日までの利用状況がアプリケーション上で朝8時までに閲覧可能になっていること
    • 学校/学年/クラスごとで集計する
    • 学校を横断した集計はしない

既存の社内用データ基盤とは

社内でのデータ分析を主な用途としているBigQueryを中心にした基盤のことです。
この記事の範囲では「AWS上で動いているアプリケーションのデータを日次でBigQueryに集約し、集計している」ということがわかれば十分です。
もし詳しく知りたい場合はこちらの記事で紹介しています。

Reverse ETLとは

各アプリケーション等からデータ基盤に集約・集計(ETL処理)したデータを、アプリケーションで二次利用するためにアプリケーション側の何らかのデータベースに書き戻す処理のことです。

もっと適切な定義があるかもしれませんが、当記事ではこの認識で進めます。
もしReverse ETLについて知りたい場合はこのあたりの記事がいいと思います。

この記事で話さないこと

  • アプリケーションの実装などのReverse ETLより後段のシステムについて
  • ダッシュボード機能のUIや集計内容含めた詳細
  • 既存のデータ基盤の詳細

Reverse ETLのアーキテクチャ

データ基盤のアーキテクチャ図

処理の説明

上記のアーキテクチャで日次のバッチ処理でデータを連携しています。
赤枠部分がReverse ETLに関連する部分です。

全体のワークフローはCloud Composerで管理しています。
DataLake側からDAGをトリガーして、下記の処理を順番に行うようになっています。

  • BigQuery上でqueryを実行しテーブルを作成
  • 集計結果のvalidation
  • AWS Step Functionsの実行をトリガーする

トリガーされたAWS Step Functionsが集計結果の書き込みを担っていて下記のような処理をしています。

  • 書き込み先の新しいテーブルをRDSに作成
  • 学校ごとにLambda jobを作成し、各LambdaがBigQueryからのデータ取得・RDSへの書き込みを行う
  • 全学校分の処理が正常に終わった場合にアプリケーションから参照するテーブルを新しいテーブルに切り替える

このアーキテクチャになるまでの背景

なぜアプリケーション上で直接集計せずに既存のデータ基盤を経由する選択をしたのか?

  • 複数のDBをまたぐ必要があり、1つのアプリケーションから横断的にアクセスするには既存の全体インフラ構成から変更が必要だった
  • 今後ログデータも集計に使う可能性があり、集約場所・データ量の観点からBigQueryが必要になりそうだった
  • 既存のデータ基盤でデータ集約や管理体制などがすでにある程度整っていて流用可能そうだった

データ基盤からのReverse ETL以外で検討した(が選ばなかった)選択肢

  • SaaSのBIツールを用いてデータ基盤上のデータから直接ダッシュボードを作成して、アプリケーションにembeddedする

    • そもそもアプリケーション側での可視化の実装がいらなくなり、ユーザー側で任意の集計が可能になるなどのメリットがあったが費用面から断念した
  • アプリケーションから直接BigQueryに接続する

    • BigQueryからのレスポンスが遅く、アプリケーションとして許容できなかった
    • BigQuery上での計算時間に関してはBI Engineやアプリケーション側でのキャッシュ等での高速化は可能だが下記の観点で不十分だった
      • この方法では初回の計算時間がかかってしまうことは避けられず、機能の特性上「1日1回見る」というユースケースが想定されるため、ユーザーの初回アクセス時に時間がかかることを許容できなかった
      • そもそもBigQuery上での計算時間以外の接続等でも時間がかかっていて、高速化の限界があった

Reverse ETLする上で他に検討した(が選ばなかった)選択肢

  • 書き戻し先をRDB以外にする

    • 集計の軸やデータの集計期間から今後のデータ量を考えるともRDBMS(postgreSQL)で対応できそうだった
    • 一般的なRDBMSで対応できそうであればその他のデータベースを優先する大きな理由がなかった
  • 書き戻し先をCloud SQLにする

    • Cloud SQLも選択肢に入ったが下記の理由からRDSを選択した
      • BigQueryからのwriteは1回/日なのに対してアプリケーションからのreadはもっと多いので、RDBはBigQueryよりアプリケーションに近い位置にあるほうが良かった
      • 社内的にCloud SQLよりRDSのほうが運用ノウハウがあった

社内用データ基盤からユーザー影響のあるシステムになったことによる変化

当たり前ですが、障害が起きた場合にユーザーにご迷惑をおかけしてしまうのでシステムを安定稼働させることの重要性が上がりました。
そのため社内用データ基盤であった時に設けていた基準よりも一段厳しくする必要がありました。
その対応内容を下記に示しますが、振り返ってみると新規の大きな問題は発生しておらず、元々それなりのレベルでデータ基盤を運用できていたという自画自賛をチームでしました。

気にしたこと・対応したこと

  • 社内用の分析のための処理とユーザー影響のある処理の分離

    • Google Cloudのリソースの観点では元々datalake用のprojectと社内ユーザーが利用するprojectは分けていたため問題なかった
    • Cloud Composer上のワークフロー(DAG)では処理が混ざっていたので、DAGの分離とコード整理をして気軽にデプロイしていい範囲とそうでない範囲をコードベースで分けた
  • データ基盤のSLO計測

    • もともと取り組んでいたので、計測・可視化自体は問題なかった
    • ダッシュボード機能の要件を元に基準にしている時刻・稼働率を引き上げるのみで済んだ
  • alert基準・通知の見直し

    • 何らかの想定外があった時は後続の処理でalertが飛べばいいという前提でalertを仕込めていなかった部分があったが、各処理ごとにalertが飛ぶようにした
    • errorは起きていないが、処理が遅れている時に気づくために遅延通知を導入した
  • デプロイフローの強化

    • CIでのチェックの強化
    • devからprodに上げる際の運用の明文化

残課題

  • 処理時間が長いため、障害時の復旧に時間がかかる
    • 現状では数時間かかる処理が含まれており、大幅短縮するためにはアーキテクチャレベルでの変更が必要だが着手できていない
  • このデータ基盤での障害発生時に対応できる人が少ない
    • 普段からデータ基盤を触っているデータエンジニアは障害から復旧させられるが、他のエンジニアでは権限や前提知識など様々な理由で状況を把握することができない
    • 以前はデータエンジニア内だけで十分であったが、データエンジニアも人数が少ないので安定稼働の観点では心許ない
  • データ品質の担保
    • データマネジメント文脈で「データ品質」と言うと様々な観点が出てくるのでここだけでは書ききれませんが、ユーザー影響のあるシステムになったことでデータ品質の要素の網羅性や各要素で求める基準が上がったがまだ改善途中という点で課題が残っている
    • 例えば有効性の観点では、集計後の一番最後の段階でユニーク性や値の範囲を確認して一定の担保はしているが、データが変換される各フェーズごとでチェックするほうが望ましい

データ基盤としての今後

このリリースによってデータの価値をユーザーに直接届けられるようになりました。
以前は社内の意思決定など間接的な形でしかユーザーに価値を届けることが出来なかったので、これはデータ基盤にとって大きな一歩です。
今後も機械学習などを含めた様々な形でデータからユーザーに価値提供することを考えています。

データ基盤に閉じた範囲では、肥大化したデータ基盤をデータメッシュをベースにした形でのリアーキテクチャを検討しています。
現状のデータ基盤はdatalakeにデータを集約して1つのデータパイプラインに載せるというモノリシックな構成になっています。
また、各層でデータを実体化させて保持しており、データの二重持ちによる無駄が発生してしまっています。
この状態では、今後データの入力・出力ともに増えたきた時に不要な依存関係や権限の管理コストが大きくなってしまうことが想定されるので、この問題に向き合います。

上記のようにまだまだやることがあるので、一緒に進めてくれる方を募集しています!
興味を持った方はこちらからどうぞ!

新サービスのブランド「tetoru」策定に至るまで

こんにちは。UXデザイン部の原田です。小中学校向けに「tetoru」というプロダクト開発に携わっています。 2022年4月に「tetoru」は正式リリースをいたしました。

corp.classi.jp

今回はこの生まれたてのサービスがどのようなプロセスを経て「tetoru」というネーミングやロゴになったのか、新サービスのブランド策定/開発プロジェクトの経緯を含めてお話をしたいと思います。

そもそも「tetoru」とはどんなサービス?

箇条書きでまとめてみました。

  • tetoruは小中学校の先生と保護者向けの連絡サービスです
  • 弊社 Classiと校務支援システムのEDUCOM社の2社で共同開発しています
  • 学校の先生にはWebサービス、保護者の方にはスマホアプリを提供しています
  • 「学校連絡」「欠席連絡」といった機能があり先生-保護者間の連絡をデジタル上で行うことができます
  • 先生は業務効率の向上、保護者は学校連絡をアプリに集約することができます
  • 煩雑なやりとりの負荷を軽減することができ、子どもの成長を見守る時間と機会の増加につながります

図にするとこのような形です。

tetoru_service

サービスブランドをちゃんとしたいという危機感

そのようなサービスの「tetoru」ですが、約2年前のチーム立ち上げ当初はサービス名称を考える暇もなくプロダクト開発をしてました。 リリース時期が2022年春ということに決まった頃、サービス名称が決まらないまま開発を優先するのは「やばい」と感じました。新しいサービスを世に出すには「なぜこのサービスが必要なのか」「それに賭ける想いや熱意」また「そのサービスが広く浸透した世界観がどうあるべきか」など、新サービスをひとことで表現できるブランドアイデンティ(BI)とビジュアルアイデンティティ(VI)が絶対必要です。

当時のメンバーはプロダクト開発で手一杯な状況で、サービスブランドを策定するリソースは社内にはとてもありませんでした。プロダクトとブランドの両輪がしっかりした状態でリリースするには、リリース時期から逆算で考えて十分に余裕を持ったマイルストーンを引く必要があります。プロダクトが良くても、ブランドが中途半端だと多くの人に知っていただけず機会損失にもつながるし、かといってリソースをブランド策定に割いてプロダクトが疎かになってしまったら本末転倒です。

また、このtetoruというプロダクトは弊社だけではなく、子会社のEDUCOM社との共同開発によるサービスです。ブランドは2社にとって愛着があるものにならなければ本当の意味で強いサービスにはなりません。

とてもじゃないが片手間にやるようなことではない、だって世に放たれたら一生続くものになるんだから! そういった危機感があり、今回は企業や商品などのブランディングのプランニング&クリエイティブを主に手がけるハイライツ株式会社というデザイン会社さまと一緒に新サービスのブランド策定/開発プロジェクトを立ち上げました。

www.highlights.jp

新サービスのブランド策定/開発プロジェクトで創意工夫した点

プロジェクトを立ち上げるにあたり、大きく4つの点を意識しました。

  1. RFPを元にコンペを開催し、お願いしたい会社の選定
  2. 経営層を巻き込んだ関係者インタビューの実施
  3. ネーミングおよびロゴを客観的かつ多角的に評価するシートを作成
  4. 会議中は「全員発話」で相互理解を促す

ここからはそれぞれの項目ごとにご紹介できればと思います。

1.RFPを元にコンペを開催し、お願いしたい会社の選定

これは最初から決めていたのですが、このプロジェクトはコンペを開催し複数の会社の中からパートナー会社を選定しました。私自身ブランド策定に関するプロジェクト知見を持っていなかったため、このブランドを託し、一緒に考えることのできる仲間を探す必要性を感じたからです。

そこで2〜3ヶ月程度かけて調査をしてパートナー候補会社に対し問い合わせを実施。オンラインMTGにて会社のことや事業理解、ケーパビリティや体制面などざっくばらんに対話を行い、一緒にこのプロジェクトをやっていきたいかどうかを判断した上でコンペ参加依頼をしました。 またコンペ開催に際しRFP(提案依頼書)もイチから作成しました。

前職はクライアントワークを主体としてましたので、しっかりと練られたRFPがあるだけでもパートナー会社さまの提案がよりシャープになるという経験則があったからです。書面として文書化することによって、メンバー内でも共通見解を整理することもでき、発注-請負間で言った言わないの水掛け論にもつながりづらくなるのでこの作業はプロジェクト開始前からしっかり準備をしててよかったなぁと思います。

提案内容のプレゼンテーションにはプロジェクトメンバー全員が参加、採点とコメントを記入し「どの会社、どの人と一緒に新サービスのブランドを考えたいか」といったところを基準に最終的には全員が納得できる会社を選定していました。

2.経営層を巻き込んだ関係者インタビューの実施

社内には定性面/定量面のユーザーリサーチ資料がありましたが、それらを踏まえつつさまざまな役職/職能のメンバー12名の関係者にデプスインタビューを実施しました。インタビュー対象者は弊社とEDUCOM社の2社からそれぞれ選出。経営層/事業責任者から始まり、営業やCS、PdM、ディレクター、UXデザイナー、エンジニアなど全方位をカバー。インタビュアーも教育関係に強い方に担当いただき、業界特有の事情も話しやすいように配慮いただきました。

インタビュー内容に関してもそれぞれの会社のことからサービスのこと、関わるヒトのことなど網羅的に話をしました。役職や立場、人によっては同じ新サービスについて話しても見えている景色や世界観のイメージは異なります。それぞれの気持ちをインタビューを通して発散していただき、最終的に印象的だった80程度のキーワードを抽出し集約。このシートは各社の経営層含む12名の気持ちがひとつにまとまっているものであり、この要素をもとに「tetoru」で実現したい世界やコンセプトを立案、方向性を整理してBIおよびVIの策定につなげていきました。

要所要所で進捗を共有していたこともあり、ちゃぶ台返しのような波乱は起こることもなかったです。日々のコミュニケーションはとても大事だなと感じます。

3.ネーミングおよびロゴを客観的かつ多角的に評価するシートを作成

サービスを表すネーミングやロゴって評価するのがすごく難しいです。基準を設けなければ主観的な感覚の評価になりがちで、ある特定の人の意見に流されて全員が納得できずに決まってしまう可能性もあります。そういった事態は絶対に避けたく、客観的に評価できる採点シートを作成しました。

採点シートを作成する際はこちらの記事を参考にしてカスタマイズしました。

takejune.com

参考にネーミングの採点シートを掲載しますが、今回は「単体評価」と「外部要因評価」の2項目に大きく分けて採点をしています。

tetoru_review

単体評価とはそのネーミングそのものの評価、外部要因評価はネーミングにまつわる外部影響になります。ネーミングそのものが良くても、似たような名称が世の中から見てすでにどこかにあると、浸透するのに時間がかかる可能性もあります。そういった異なる視点を持った上で◯なら1点、△なら0.5点、×なら0点の採点を行いスコアリングしました。特に単体評価は人によって意見が分かれることもあるので評価する際も誰かの独断で行うのではなく、各社で分かれて採点を行い、その内容を内部定例にてシェア。対話を行った上で、ひとつの意見としてまとめて最終評価をしています。

このシートがあることでその字面や第一印象だけではなく、音の響きや発音のしやすさ、印象の残りやすさなど五感を意識した評価を行うことができました。また単体評価が良くても外部要因評価で阻害要因があるかどうか(ドメイン名や類似サービスの有無)を事前に確認することができました。

結果として多角的にかつ公平に見極めることができ「tetoru」というネーミングが確定。ロゴも同様の手順で進めました(せっかくなので最終案に決定する前の検証バリエーションをお見せします)。

tetoru_variation
tetoruのロゴバリエーション
tetoru_variation2
アクセントカラーの比較

4.会議中は「全員発話」で相互理解を促す

コロナ禍ということもあり、プロジェクトは完全オンラインで行いました。ここでよく陥りがちなことは主要メンバーしか喋る機会がなく、会議中ひとことも発言しないメンバーがいることです。

このプロジェクトに関しては毎回の定例会議では「顔出し&必ず発言する」ことをマストにしました。とはいえ、発言を強要する訳ではなく、シンプルに思ったことをシェアしてもらうといった側面が大きく、相互理解を促す役割が大きいです。流れを簡単にご紹介します。

  1. パートナー会社から会議の主題の内容を共有いただく(方向性案やロゴ案など)
  2. いただいた内容に対し、PMである自分がまず最初に感想やコメントをシェア
  3. 終わったら、自分以外のプロジェクトメンバーを指名する
  4. 指名された人が同様に感想やコメントをシェア
  5. 以降、全員が喋り終わるまで繰り返し

ここでいう「感想やコメント」は文字通りそのまま感じたことを共有してもらっています。私自身、tetoruのネーミング案の提案をいただいた回では提案の数やバリエーション、ひとつひとつの案に込める想いを聞いて「プロの仕事って本当に凄くて泣きそうになりました」という子どものような感想も会議の場で伝えています(笑)。でもそれでいいのです、だって全員発話の目的は相互理解することなので。

言葉にならないモヤモヤでも、話を聞いて感じたことを素直に言葉にして共有するだけでも誰かの感性を刺激することにもなります。実際、まとまらない状態のまま吐き出すことによって議論が大きく盛り上がることもよくありました。本当の意味での言いたいことを言い合える関係性を構築し、誰かの不満が蓄積しないよう全員の気持ちを尊重した上で和気藹々と進めていました。

対話と検討を重ねて、ついに「tetoru」誕生

こうしたやりとりを経て、新サービスのブランド「tetoru」は誕生しました。 タグラインやステートメントまで私たちの想いが織り込まれ、そのDNAが随所に刻まれております。

tetoru_logo tetoru_statement

「tetoru」という言葉には学校の先生と保護者、また社内の職種や領域を超えて互いが手と手を取り合い、子どもたちの未来につながるサービスになってほしいという願いが込められてます。ロゴの印象的な赤・緑・黄色の3つのアクセントは子ども・先生・保護者を表してます。それらがしなやかにつながり、成長と発見をかなえ、人肌のある、あたたかなサービスを目指しています。

今回のご担当いただいたハイライツ株式会社のみなさまには感謝の気持ちでいっぱいで、このプロジェクトを通して日々の業務に邁進するための「核」が生まれたような気がしてます。それぞれの職能は異なれど、この核のために仕事に打ち込み、何か迷ったり困ったりしたらこのステートメントに立ち返ることのできる指針のようなものになりました。

※ハイライツ株式会社さまのWebサイトでもプロジェクト事例としてご紹介いただいておりますのでぜひご覧ください。

www.highlights.jp

その後のリアクション

プロジェクト関係者は自分たちで検討を重ねたため馴染んでいるのが当たり前のことですが、それ以外のメンバーもこの想いを汲み取ってくれているのでブランドの力ってすごいなぁって感じています。

また、リリース後にとある学校さまにインタビューを行った際には「プロダクトのあたたかみを感じる」と答えてくださった方もいて、感謝の気持ちでいっぱいです。 今後もこれに満足することなくtetoruで実現したい世界に向けてプロダクトとコミュニケーションの拡充を、この核を中心に展開していければと思います。

人材募集中です

今回はtetoruが誕生するまでの経緯と工夫したポイントについてご紹介しました。 最後に採用の紹介だけさせてください。 弊社の小中学校事業領域は実現したい未来に対しまだまだ人材が足りておらず、絶賛メンバー募集中です! カジュアル面談から受け付けておりますのでご興味のある方はぜひお問い合わせください。

hrmos.co

Datadogで深夜バッチの失敗アラートを営業時間に受け取る方法

深夜の定期バッチの監視

Webサービスのオフピーク時に重たい処理を実行させるというのは一般的なプラクティスといえます。

特に深夜〜早朝は多くのサービスでバッチ処理を実行させているのではないでしょうか。

Webサービスだけではなく、当然バッチ処理も監視して失敗したらそれを発見し対処したいです。

しかし、失敗を発見しても即座にユーザ影響がないので対応は後でも良いという場合、素朴に監視ルールを作るとバッチが失敗した深夜・早朝にアラートが発報されることになります。

発報されたアラートを見て「これは今すぐに対応してなくても良いな」と判断するのであれば、それは狼少年アラートといえるのではないでしょうか。

悪貨が良貨を駆逐すると言われるように、狼少年アラートがはびこれば良貨のアラートもいずれ無視されるようになってしまうことは容易に想像できます。

Datadogの timeshift 関数でアラートの発報タイミングを変える

この狼少年アラート問題を解決するためには 事象が起きたタイミングとアラート発報のタイミングを変える ことができたらよさそうです。

まず最初の案として、当社は監視サービスとしてDatadogを利用しているので、定期的にCustom Checkを投稿・実行することを考えました。

しかし対象のバッチ処理はAWS Step FunctionsAWS Lambdaを組み合わせたシステムで、DatadogのAWS連携でStep Functionsの失敗数は既にメトリクスとしてDatadogに収集されており、これと重複する処理を作るのはナンセンスです。

通常のメトリクス監視で通知だけずらせたらシンプルで合目的なのですが、そういった解決策はないでしょうか?

ところでモニターの設定画面をあれこれ見ていると hour_before() というある時点より1時間前の値をその時点のメトリクス値とする関数が存在することを知りました。

これを使えば、過去のメトリクス値をもとにアラートを発報することもできるはずです。しかし、1時間前あるいは1日前では間隔が短すぎ・長すぎます。 任意の時間だけずらす関数はないのでしょうか?

実はtimeshiftというまさしくそのものの関数があります。というか hour_before() などの XXX_before() 関数はすべて timeshift() 関数へのエイリアスになっています。

我々のバッチシステムは毎朝4時に実行されるので、コアタイムに近い午前10時に通知できれば良いと考え、6時間シフトさせた値を監視することにしました。

実際のクエリは以下のようになります:

timeshift(sum:aws.states.executions_failed{/* snip */} by {stage}.as_count(), -21600)
# 60 * 60 * 6 = 21,600

むすび

Datadogの timeshift() 関数を使い、深夜早朝に実行されるバッチのアラートを実際に対処すべき時間に通知する方法について紹介しました。

今回紹介した方法は「次の営業時間内に対応すればよい」という温度感のアラートを運用の実際に近付けるためのものであって、当然ながら濫用して即時対応すべきアラートを遅延させることを推奨するものではありません。

重要なことは 本当に対応すべきタイミングに必要なアラートを受け取る 仕組み作りであることは疑いようがありません。

当社ではWebサービスの監視について継続的に改善を進めており、過去にはこのブログでも紹介しました。

AWS ECS監視のオオカミ少年化を防ぐために考えたちょっとしたこと Amazon EventBridge(CloudWatch Events)で動かしているバッチをDatadogで監視する仕組みを構築した話

今後もアラートルールを見直しシステムの監視を洗練させ続けたいと思います。

DatadogでECS Fargate TaskのCPU利用率が100%を超えて表示されていたので調べてみた

こんにちは。開発本部の遠藤です。

ClassiではAmazon ECSをアプリケーション実行環境として利用しています。

ECSの各種メトリクスをDatadogを使ってモニタリングしながら、日々安定稼働しているかどうかをチェックしています。

そのうちの一つの重要なメトリクスとして、ECSのFargate TaskのCPU利用率が過度に高まっていないか、があるのですが、ある時期、CPU利用率が100%を超えてしまっていて「一体なにが起きてるんだ??」と疑問を持ちました。

今回はそれについて深堀りしてみたので、ニッチなトピックですが紹介したいと思います。

ECS Fargate TaskのCPU利用率が100%を超えて表示されている

こちらが実際にCPU利用率が100%を超えてしまったときのグラフです。

Datadogのメトリクスは ecs.fargate.cpu.percent です。なお、container_id でコンテナごとにグルーピングして表示しています。

下記図で示すように、AWSの CloudWatch Logs Insights を使用して、上記コンテナが稼働しているECS Fargate Taskの CpuReservedCpuUtilized をもとにCPU利用率を計算してみると、およそ50%ということがわかります。

この違いはどこから来ているのか、あるいはDatadogにCPU利用率が100%を超えうるというバグが存在しているのか、Datadogのメトリクスの算出方法を追って探ってみたいと思います。

DatadogはCPU利用率をどう算出しているのか

Datadogで表示されているこの ecs.fargate.cpu.percent というメトリクスはどのような計算式で算出されているのでしょうか?

Datadogのドキュメント には Percentage of CPU used per container (Linux only) Shown as percent と記載されているのみでした。

ということでソースコードを読んで確認していきます。(以後参照するソースコードについては2022/05/23時点の最新の master/main ブランチのものとなります)

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L220-L222

  cpu_percent = (cpu_delta / system_delta) * active_cpus * 100.0
  cpu_percent = round_value(cpu_percent, 2)
  self.gauge('ecs.fargate.cpu.percent', cpu_percent, tags)

このあたりで算出しているようです。

cpu_deltasystem_delta について見ていきます。

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L141

  request = self.http.get(stats_endpoint)

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L161

  stats = request.json()

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L167-L169

        for container_id, container_stats in iteritems(stats):
            if container_id not in exlcuded_cid:
                self.submit_perf_metrics(container_tags, container_id, container_stats)

submit_perf_metrics の中では以下のような処理を行っています。

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L181-L212

           # CPU metrics
            cpu_stats = container_stats.get('cpu_stats', {})
            prev_cpu_stats = container_stats.get('precpu_stats', {})

            value_system = cpu_stats.get('cpu_usage', {}).get('usage_in_kernelmode')
            if value_system is not None:
                self.rate('ecs.fargate.cpu.system', value_system, tags)

            value_user = cpu_stats.get('cpu_usage', {}).get('usage_in_usermode')
            if value_user is not None:
                self.rate('ecs.fargate.cpu.user', value_user, tags)

            value_total = cpu_stats.get('cpu_usage', {}).get('total_usage')
            if value_total is not None:
                self.rate('ecs.fargate.cpu.usage', value_total, tags)

            available_cpu = cpu_stats.get('system_cpu_usage')
            preavailable_cpu = prev_cpu_stats.get('system_cpu_usage')
            prevalue_total = prev_cpu_stats.get('cpu_usage', {}).get('total_usage')

            # This is always false on Windows because the available cpu is not exposed
            if (
                available_cpu is not None
                and preavailable_cpu is not None
                and value_total is not None
                and prevalue_total is not None
            ):
                cpu_delta = float(value_total) - float(prevalue_total)
                system_delta = float(available_cpu) - float(preavailable_cpu)
            else:
                cpu_delta = 0.0
                system_delta = 0.0

request.json で取得したレスポンスデータを使って計算していて cpu_stats.system_cpu_usageprecpu_stats.system_cpu_usage の差分が system_delta であり、 cpu_stats.total_usageprecpu_stats.total_usage の差分が cpu_delta です。

では request.json はどのendpointにリクエストを投げて取得したデータなのでしょうか?

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L141

  request = self.http.get(stats_endpoint)

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L76

  stats_endpoint = API_ENDPOINT + STATS_ROUTE

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L40-L42

API_ENDPOINT = 'http://169.254.170.2/v2'
METADATA_ROUTE = '/metadata'
STATS_ROUTE = '/stats'

http://169.254.170.2/v2/stats これがendpointのようです。

タスクメタデータエンドポイントバージョン 2

169.254.170.2 v2 でググってみるとAWSのデベロッパーガイドがすぐに出てきました。

タスクメタデータエンドポイントバージョン 2 - Amazon Elastic Container Service

Amazon ECS コンテナエージェントのバージョン 1.17.0 から、さまざまなタスクメタデータおよび [Docker 統計]を、Amazon ECS コンテナエージェントによって指定される HTTP エンドポイントで awsvpc ネットワークモードを使用するタスクで利用できます。

169.254.170.2/v2/stats

このエンドポイントはタスクに関連付けられたすべてのコンテナの Docker 統計 JSON を返します。返される各統計の詳細については、Docker API ドキュメントの「ContainerStats」を参照してください。

つまりDatadogはこのAWSのタスクメタデータエンドポイントを叩いてデータを取得していて、返ってきているのはDocker 統計 JSONということです。

Docker Containers Stats

Docker API ドキュメントの ”ContainerStats” の箇所を見てみます。

Docker Engine API v1.41 Reference

詳細なレスポンスはドキュメントに記載されているので、ここでは気になるものをピックアップします。

先に出てきた cpu_stats です。

"cpu_stats": {
    "cpu_usage": {
        "percpu_usage": [
            8646879,
            24472255,
            36438778,
            30657443
        ],
    "usage_in_usermode": 50000000,
    "total_usage": 100215355,
    "usage_in_kernelmode": 30000000
    },
    "system_cpu_usage": 739306590000000,
    "online_cpus": 4,
    "throttling_data": {
        "periods": 0,
        "throttled_periods": 0,
        "throttled_time": 0
    }
},

疑問

DatadogはこのAWSのタスクメタデータエンドポイントを叩いてデータを取得していることがわかりました。 ではもともとの疑問であった100%を超えるCPU利用率の表示というのはDatadogのバグではないということになるのでしょうか?

もう一度Datadogの計算式を見てみます。

https://github.com/DataDog/integrations-core/blob/4cf0f7dc759683b454cf46b9ff5e2de561a58339/ecs_fargate/datadog_checks/ecs_fargate/ecs_fargate.py#L220

  cpu_percent = (cpu_delta / system_delta) * active_cpus * 100.0

これをタスクメタデータエンドポイントのレスポンスのkeyを使用して表現すると以下のようになります。

((cpu_stats.total_usage - precpu_stats.total_usage)
/ (cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage))
* cpu_stats.online_cpus
* 100.0

response sample の percpu_usage のarrayのvalueの合計が total_usage のvalueと一致することから total_usage はその名の通りコンテナ全体のCPU消費時間を指しているはずです。

そうであるなら、 稼働しているCPUコア数を指す cpu_stats.online_cpus を乗算する必要性がどうしても見いだせず、以下の計算式で十分に思えました。

cpu_percent = (cpu_delta / system_delta) * 100.0

なぜ cpu_stats.online_cpus を乗算しているのでしょうか?

そう思ってる人が他にもいた

そもそもDatadogがなぜこの計算式を採用しているのかというと、docker stats のそれに準じているからだと推測されます。

https://github.com/docker/cli/blob/14962747e4af2c992bca55008c27387cd2268620/cli/command/container/stats_helpers.go#L180

  cpuPercent = (cpuDelta / systemDelta) * onlineCPUs * 100.0

そしてこの計算式について異議を唱えるissueがありました。

https://github.com/docker/cli/issues/2134

docker stats CPU shows values above 100%

I don't think there is a system monitor tool (linux or windows) that shows CPU usage above 100%. Conceptually, 100 percent means maximum value.

So what is the reason to multiply by the number of cpus? Seem that is not required because total_usage already accounts for them.

なおこのissueに対して明確な回答はなさそうでしたが、以下のようなコメントがあります。

This is not an issue. If you have N CPU cores, the CPU usage can be up to N * 100%.

これだけだと納得がいかなかったのですが、mobyのissueにそれらしい回答がありました。

https://github.com/moby/moby/issues/29306#issuecomment-405293005

That's not really something that can be changed easily, as it will break many users; this output was modelled after how top works on Linux; https://unix.stackexchange.com/questions/34435/top-output-cpu-usage-100

top コマンドをモデルにしているようです。

top command の Irix mode

言及されているリンクを見てみます。

linux - top output: cpu usage > 100% - Unix & Linux Stack Exchange

You are in a multi-core/multi-CPU environment and top is working in Irix mode. That means that your process (vlc) is performing a computation that keeps 1.2 CPUs/cores busy. That could mean 100%+20%, 60%+60%, etc.

Irix mode を知らなかったので調べてみます。

https://man7.org/linux/man-pages/man1/top.1.html

I :Irix/Solaris-Mode toggle When operating in Solaris mode ('I' toggled Off), a task's cpu usage will be divided by the total number of CPUs. After issuing this command, you'll be told the new state of this toggle.

Irix mode と Solaris mode があり、Solaris modeはcpu usageをCPUコア数で割った数が表示されるようです。 つまりdefaultのIrix mode はcpu usageをCPUコア数で割らないということを意味することがわかります。

これが docker stats のCPU使用率算出の計算式のモデルになっているようです。

まとめ

Irix mode ではcpu usageをCPUコア数で割らない値をCPU使用率として表示しています。 たとえばCPUコア数が4のサーバであれば、最大400%として表示され得るということです。

docker stats も Datadog の ecs.fargate.cpu.percent のメトリクスもこの表示方式を踏襲し、以下の計算式を採用していることがわかりました。

  cpu_percent = (cpu_delta / system_delta) * active_cpus * 100.0

つまりわざわざCPUコア数を乗算することで、top コマンドの Irix mode でのCPU利用率の値を表現していたのです。

冒頭の疑問にやっとここで返ってこれるのですが、該当のECS Fargate Task はcpuを4096 = 4vCPU(CPUコア数:4) で設定し稼働させているので、100%を超える値が表示されていたということです。

なのでこのコンテナは実質的には4で割った値である 50 ~ 60% あたりで稼働していると考えてよさそうですし、CloudWatchで取得した値と近しくて納得感があります。

ただし、どのCPUコアがそれぞれ何%なのかまではわからず、いずれかが100%近くまでCPUを利用している可能性は大いにあり得るので、注意は必要です。

Datadogの ecs.fargate.cpu.percent で検索してもなかなか今回の事象について情報が得られなかったのですが、コードリーディングすることで納得感が得られ、とてもスッキリしました。

加えて、Datadogが実際なにをしているかを垣間見れたことでDatadogへの理解が深まり、芋づる式にECS、Docker、topコマンドについても知見を得られたので学びが多かったです。

同じような事象に遭遇し、疑問を持った方の参考になれば幸いです。

© 2020 Classi Corp.