SlideShare uma empresa Scribd logo
1 de 91
Baixar para ler offline
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
趣味と仕事の違い、
現場で求められるアプリケーションの可観測性
株式会社LIFULL 相原 魁
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
目次
5.おまけ(時間があれば)
4.アプリケーションの可観測性の勘所
3.仕事のアプリケーションで求められるもの
2.趣味のアプリケーションでやりがちなこと
1.紹介
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
- 株式会社LIFULL 相原 魁
- ソフトウェアエンジニア スペシャリスト(Platform Engineering, SRE)
- 仕事ではKubernetesをベースとした内製PaaS KEELを開発・運用
- 趣味では主にRustを書いています
- 全文検索ライブラリ
- 分散検索エンジン
- eBPF
自己紹介
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
- 株式会社LIFULL 相原 魁
- ソフトウェアエンジニア スペシャリスト(Platform Engineering, SRE)
- 仕事ではKubernetesをベースとした内製PaaS KEELを開発・運用
- 趣味では主にRustを書いています
- 全文検索ライブラリ
- 分散検索エンジン
- eBPF
自己紹介
可観測性のプラットフォームも開発する立場
分散システムを開発する中で可観測性に注力
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
「したい暮らしに、出会おう。」をコンセプトに掲げ、簡単で便利な住まい探しをお手伝いする不動産・住宅情報の総合サービスです。

物件の探しやすさや住まいに関する情報の見つけやすさ、検討がしやすくなるように、様々な機能や情報を拡充していきます。

今後も、ユーザーに寄り添いながら、ともに理想の住まい探しを実現します。

Copyright© LIFULL Co.,Ltd. All Rights Reserved.
LIFULLの内製PaaS KEEL
- コマンドを1発叩くだけで完璧なアプリケーション実行環境が手に入る内製PaaS
- デプロイ、セキュリティ、可観測性、信頼性、パフォーマンス
- コードジェネレータを中心とした開発者体験の提供
- Pull Requestを作成するとプレビューできる機能やLint, Content Trustまで備える
- https://www.lifull.blog/archive/category/Kubernetes
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
本日のゴール
可観測性に優れたアプリケーションを実装できるようになる
※少しWebに寄った話になります
※後でリファレンスとして使えるよう説明的な資料にしているので今全てを理解する必要はないです
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
趣味のアプリケーションでやりがちなこと
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
retval, err := maybeError()
if err != nil {
log.Printf("an error occurred: %+v", err)
}
return retval
}
エラーをとりあえずでロギングするだけ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
retval, _ := maybeError()
return retval
}
そもそもエラーをハンドリングをしない
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
fn doSomething() RetVal {
let result: Result<RetVal> = maybeError();
let retval = result.unwrap();
retval
}
Rustだったらunwrap()するだけとか
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
def doSomething do
maybeError
rescue
{}
end
Rubyなら全ての例外をもみ消したり
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
start := time.Now()
retval := maybeSlow()
elapsed := time.Since(start)
log.Printf("maybeSlow took: %s", elapsed)
return retval
}
実行時間の計測をログで頑張る
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
retval := maybeSlow()
return retval
}
そもそも実行時間を気にしない
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func main()
retval, err := doSomething()
if err != nil {
fmt.Fprintf(os.Stderr, "%+v", err)
}
}
func doSomething() (*RetVal, error) {...}
折角もらったエラーを適当に標準エラーする
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
仕事のアプリケーションで求められるもの
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
趣味と仕事の違い
- 開発者である自分自身だけが未来永劫メンテナンスし続けるわけではない
- 実装に詳しくない人が状況を判断できる必要がある
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
趣味と仕事の違い
- 開発者である自分自身だけが未来永劫メンテナンスし続けるわけではない
- 実装に詳しくない人が状況を判断できる必要がある
ソースコードを読むことも書き換えることもなく必要な情報を取得できる
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
可観測性
- 可観測性(observability)とは、システムの外部出力を観測することでシステムの内部状態を推
測可能かどうかの尺度である。
- 引用: 状態空間 (制御理論)#可観測性
- microservicesの流行などによってシステムの構成が複雑化して重要性が増してきている
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Primary Signals
Metrics
Traces Logs
可観測性の基本的な3つのシグナル
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Metrics
Traces Logs
- 特にフォーマットのないテキストデータ
- 出力方法
- アプリケーションからファイルに書き込む
- アプリケーションから標準出力・標準エラーする
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
アプリケーションログ
- エラーをはじめアプリケーション内のイベントを記録するログ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
HTTPサーバのアクセスログ
- HTTPのサーバがリクエストを受けた時のログ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
監査ログ
- 誰が何をしたかというイベントを記録するログ
- 主に認証のあるアプリケーション等で出力する
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Metrics
Traces Logs
- インデックス付きの数値データ
- OpenMetricsで標準化が進んでいる
- 数値データであるためLogsと比較して安価
- 出力方法
- エージェントが外部から観測して出力
- アプリケーション内で計測して出力
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: OpenMetrics
- Prometheusというモニタリングシステムを参考に標準化されたフォーマット
- summary, gauge, counter, statesetといったいくつかのデータタイプでMetricsを表現
- エージェントあるいはアプリケーションがこのフォーマットに従って出力する
- Datadogをはじめ多くのモニタリングシステムがサポート
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
CPU, Memory Usage
- Linuxでは /proc から取得することができる
- /proc はプロセスの情報を持つ擬似ファイルシステム
- /proc/<PID>/statでは14, 15個目がCPUに関する情報
- 実際はエージェントが勝手に収集してくれていることが大半
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
アプリケーションのエラー数
- アプリケーション内部のエラー数のカウンタ
- Logsでも表現できるがコストの観点からMetricsであるとよい
引用: kubernetes/autoscaler
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Garbage Collectorに関する情報
pp GC.stat
#{:count=>13,
# :heap_allocated_pages=>50,
# :heap_sorted_length=>69,
# :heap_allocatable_pages=>19,
# :heap_available_slots=>20383,
# :heap_live_slots=>20256,
# :heap_free_slots=>127,
# :heap_final_slots=>0,
# :heap_marked_slots=>17090,
# :heap_eden_pages=>50,
# :heap_tomb_pages=>0,
# …}
- ランタイム内に持っているGCの情報
- アプリケーション内で収集して出力する
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
ミドルウェアの各種情報
- ミドルウェアによって出力されているMetrics
- e.g. ngx_http_stub_status_module
- エージェントが収集しに行って出力する
- ミドルウェア自身が直接出力するケースも増えてきている
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: Prometheus Exporter
- Metricsを出力するためのPrometheus用のエージェント
- PrometheusのMetrics表現はOpenMetricsと互換性があるため広く利用できる
- OSSとして多くのPrometheus Exporterが存在する
- MySQL Server Exporter
- Redis Exporter
- NGINX Prometheus Exporter
- cAdvisor
- 利用するミドルウェアに対応するPrometheus Exporterを探すことができる
- EXPORTERS AND INTEGRATIONS
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
インデックスとカーディナリティ
- MetricsはラベルというKey-Valueを元にインデックスする
- ラベルの数が多いとカーディナリティが高くなりコスト増
- e.g. {uri=”/items/1”}, {uri=”/items/2”}, … {uri=”/items/9999”}
- こういった詳細な情報の表現はLogsの方が向く
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Metrics
Traces Logs
- 依存関係を持つメタデータの有向非巡回グラフ
- Spanというデータ構造の集合からなる
- OpenTelemetryで標準化が進んでいる
- 計測も保存も比較的コストが高い
- サンプリング(間引き)をすることが一般的
- 出力方法
- アプリケーション内で計測して出力
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: OpenTelemetry
- OpenTracingとOpenCensusが統合されて生まれたプロジェクト
- OpenTracingはTracesの標準化をしていたプロジェクト
- OpenCensusはTracesとMetricsの収集を補助するライブラリ
- OpenTracingはベンダー中立にPropagationするための仕様を策定していた
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
引用: Jaeger documentation
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
引用: Jaeger documentation
Span
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
引用: Jaeger documentation
Span
Trace
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Span
- 開始・終了のタイムスタンプとKey-Valueのラベル等を持つ
- 0つ以上の親となるSpanを持つことができる
引用: OpenTracing Specification
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Propagation
- アプリケーションをまたいだ依存関係を持つことができる
- アプリケーション間の依存関係はHTTPヘッダで引き回す
- W3C Trace Context
- traceparent Header
- trace-id
- parent-id
- sampled
- microservicesの依存関係を可視化することができる
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
start := time.Now()
retval := maybeSlow()
elapsed := time.Since(start)
log.Printf("maybeSlow took: %s", elapsed)
return retval
}
実行時間の計測をログで頑張る
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
start := time.Now()
retval := maybeSlow()
elapsed := time.Since(start)
log.Printf("maybeSlow took: %s", elapsed)
return retval
}
実行時間の計測をログで頑張る
maybeSlowが複雑な依存関係を持つ場合Metricsだけでは調査しづらい
Tracesも収集することで依存関係のボトルネックを探せるようにしたい
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
OpenMetricsとExemplars
- OpenMetricsは外部のデータに対する参照を持つことができる
- ExemplarsというKey-Value
- MetricsとTracesを関連付けることができる
引用: Exemplars | Grafana Labs
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
ここまでのまとめ
- 実装に詳しくない人が状況を判断できるよう可観測性が重要
- 可観測性には3つの性質の違う主要なシグナルがある
- Logs: 自由度が高くフォーマットを持たないテキストデータ
- Metrics: 詳細な情報を安価に表現するインデックスつきの数値データ
- Traces: 複雑な依存関係を表現できるメタデータの有向グラフ
- それぞれ補完しあう関係にあるため組み合わせて使う
- Metricsはコストが安いが詳細情報や依存関係を持てない
- Logsは詳細情報を持てるがコストが高い
- Tracesは依存関係を持てるが表現が限定的でコストが少し高い
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: 周辺エコシステム
- Logs
- Grafana Loki, ElasticSearch
- Amazon CloudWatch Logs
- Cloud Logging
- Metrics
- Prometheus(Cortex)
- Amazon CloudWatch
- Cloud Monitoring
- Traces
- Grafana Tempo, Jaeger
- AWS X-Ray
- Cloud Trace
- All-in-one
- Datadog
- NewRelic
- Grafana(?)
- OSSのObservability Platform
- Loki, Cortex, TempoのGrafana Labsが開発
OpenMetrics, OpenTelemetry含め殆どがCNCF周りのもの
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: CNCF
- > Cloud Native Computing Foundationは、オープンソースでベンダー中立プロジェクトのエコシ
ステムを育成・維持して、このパラダイムの採用を促進したいと考えてます。 私たちは最先端
のパターンを民主化し、これらのイノベーションを誰もが利用できるようにします。
(https://github.com/cncf/toc/blob/main/DEFINITION.md)
引用: CNCF Landscape
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
引用: CNCF Landscape
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
ケーススタディ: レスポンス速度の遅延
1.どうやらレスポンス速度が遅くなっているらしいと監視から通知を受け取る
2.まずはMetricsからどんなアプリケーションのどのリクエストが遅延したか確認
foo Applicationの /bar が遅延していた
3.次はLogsでfoo Applicationの /bar でエラーログが出力されていないかどうかを確認
このリクエストはrequestid=bazでこのrequestidにエラーログはなかった
4.Tracesでrequestidを調べるとMySQLにクエリしていてその速度が遅延していた
5.MySQLに関するMetricsを確認すると同時間帯に接続数が増大していた
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
アプリケーションの可観測性の勘所
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
エラーハンドリング
指針
1. エラーをどう取り扱うかは呼び出し元に決めさせる
- Logs, Metricsはエラーを起点とすることが多い
- エラーハンドリングを正しくしていないと出力しづらい
2. 必要なコンテキストを付与する
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
retval, err := maybeError()
if err != nil {
log.Printf("an error occurred: %+v", err)
}
return retval
}
エラーをとりあえずでロギングするだけ
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
retval, _ := maybeError()
return retval
}
そもそもエラーをハンドリングをしない
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
fn doSomething() RetVal {
let result: Result<RetVal> = maybeError();
let retval = result.unwrap();
retval
}
Rustだったらunwrap()するだけとか
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
def doSomething do
maybeError
rescue
{}
end
Rubyなら全ての例外をもみ消したり
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() (*RetVal, error) {
retval, err := maybeError()
if err != nil {
return nil, xerrors.Errorf("failed to execute maybeError: %w", err)
}
return retval, nil
}
指針
1. エラーをどう取り扱うかは呼び出し元に決めさせる
2. 必要なコンテキストを付与する
①
② 独自のエラー型・例外でラップするなど
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: 例外を乱用しない
- 例外でラップする例を挙げたが例外は乱用してはならない
- フロー制御として使うにはコストが高い
- 例外はあくまで”例外”であるため普段起こりうるフローでは利用しない
- Replacing Throwing Exceptions with Notification in Validations
- エラーハンドラ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Logs
指針
1. ユーザの個人情報など秘匿情報を記録しない
- 秘匿情報が記録されたログは閲覧者が制限される
- 可観測性が満たされない
2. どのイベントに紐づくログであるかを記録する
3. 分析のしやすいフォーマットにする
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
HTTPのURIに秘匿情報を含めない
- アクセスログにそのままpasswordが記録されてしまう
GET /secrets?password=foobar HTTP/1.1
Host: example.com
User-Agent: curl/7.58.0
Accept: */*
指針: ユーザの個人情報など秘匿情報を記録しない
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
外部からの入力をそのままログにしない
- パラメータとしてユーザの電話番号を受け取っていた場合ログに出力されてしまう
def validation(parameters)
parameters.each do |parameter|
if rules[parameter[:key]].valid?(parameter[:value])
STDERR.puts "#{parameter[:value]} is invalid"
end
end
end
指針: ユーザの個人情報など秘匿情報を記録しない
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func main()
retval, err := doSomething()
if err != nil {
fmt.Fprintf(os.Stderr, "%+v", err)
}
}
func doSomething() (*RetVal, error) {...}
折角もらったエラーを適当に標準エラーする
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
HTTPサーバならRequestIDを含める
- 慣例的にHTTPではX-Request-Idというヘッダでリクエストを一意に識別する
- 最前段のHTTPサーバで発行して、各HTTPクライアントはそれを引き回す
- これをアクセスログやエラーログに含めておくとリクエストをまとめて検索できる
指針: どのイベントに紐づくログであるかを記録する
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
ログの出力元やStack Traceを含める
- ソースコードのどこで原因となるイベントが発生したかを調べられる必要がある
- Stack Traceはデータ量が大きい反面、情報量が多い
- ログを見た後、詳細な調査が必要なエラーでStack Traceを出力することが多い
- 前述の通り呼び出し元がエラーを受け取りStack Traceを出力する
指針: どのイベントに紐づくログであるかを記録する
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
必要に応じてJSONで出力する
- 主要なLogsのObservability PlatformはJSONをParseする機能を備えている
- HTTPサーバのアクセスログなどログを元に分析する場合はJSONが好ましい
- syslogやLTSVなどその他のフォーマットもあるがPlatformのサポートが厚いのはJSON
指針: 分析のしやすいフォーマットにする
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: ログレベル(持論)
- ログレベルとは対象のログの深刻度を示すもの
- 一般に以下のようなログレベルが採用されることが多い
- DEBUG
- INFO
- WARN
- ERROR
- CRITICAL
- ログは前述の通りコストが高いため無視されるログは必要がない
- 不用意にログレベルを増やすと無視されるログを増やすことに繋がる
- 全てのエラーは等しく対応をすべきだとして以下のみから始めることが多い
- DEBUG
- INFO
- ERROR
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Metrics
指針
1. USEメソッド
- Utilization
- Saturations
- Errors
2. REDメソッド
- Rate
- Errors
- Duration
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
USEメソッド
Worker Worker
Worker
Master
- Brendan Greggによって提唱されたMetrics収集の方法論
- あるリソースに対してUtilization, Saturations, Errorsを収集する
- 各リソースのMetricsの例示は The USE Method を参照
- ハードウェアリソースはエージェントが既に収集していることが多い
- エージェントの不足分やソフトウェアリソースをUSEメソッドに従って収集する
- 古典的なTCPサーバで考えた場合
- Utilization: ActiveなWorker数 / 総Worker数
- Saturations: Backlogに積まれたIn-QueueなConnection数
- Errors: ECONNREFUSEDが返った数
ECONNREFUSED
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
引用: The USE Method
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
REDメソッド
- USEメソッドがリソース単位であることに対してREDメソッドはサービス単位
- REDメソッドの適用先はより限定的
- It is fair to say this method only works for request-driven services(The RED Method)
- あるサービスに対してRate, Errors, Durationを収集する
- microservicesの場合はデータストア含む依存するサービスに対して収集を考える
- 検索エンジンで考えた場合
- Rate: 検索エンジンに対するRequests per second
- Errors: レスポンスのエラー数
- Duration: レスポンスのレイテンシ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
start := time.Now()
retval := maybeSlow()
elapsed := time.Since(start)
log.Printf("maybeSlow took: %s", elapsed)
return retval
}
実行時間の計測をログで頑張る
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
func doSomething() *RetVal {
start := time.Now()
retval := maybeSlow()
elapsed := time.Since(start)
log.Printf("maybeSlow took: %s", elapsed)
return retval
}
実行時間の計測をログで頑張る
この手のものはMetricsとして管理してコストを安くしたい
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
出力の方法
- アプリケーションがOpenMetrics形式でMetricsを出力する
- Prometheusのクライアントライブラリを入れるなど
- アプリケーションのMetricsをエージェントが収集して出力する
- nginxの/nginx_statusをNGINX Prometheus Exporterが出力するなど
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
メソッドに従うことのメリット
- Metricsは収集した後に監視・可視化をするが、処理を共通化させやすい
- 抜け漏れなくMetricsを収集することができる
- これらはあくまで指針であるためアプリケーション固有のものは別途収集する
- Garbage Collectorの情報
- アプリケーションの状態
- ランタイム固有のグリーンスレッドの数
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
- CPUの使用率にPod間の偏りが存在する(Sticky Session下での過負荷など)
- cgroupで設定したlimits.memoryまでメモリを使い切れていない
- メトリクスの収集に失敗している
- NetworkのReceiveでパケットが落とされている
- NetworkのTransmitでパケットが落とされている
- Podがrestartを短時間に繰り返している
- Podがスケジュール待ちなど不正な状態が継続している
- PodのHealthCheckが失敗している
- 全てのPodのHealthCheckが失敗している
- PodがImageの取得に失敗するなどして待機状態になっている
- Podのメモリが不足し始めている
- Nodeのリソース不足などが原因でPodが大量に退避させれている
- Podがスケールアウトの限界に近付いている
- Podのエラーレートが増加している
- Podの特定のURIのエラーレートが増加している
and more...
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Traces
指針
1. とりあえずOpenTelemetryを使っておく
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: OpenTelemetry
- OpenTracingとOpenCensusが統合されて生まれたプロジェクト
- OpenTracingはTracesの標準化をしていたプロジェクト
- OpenCensusはTracesとMetricsの収集を補助するライブラリ
- OpenTracingはベンダー中立にPropagationするための仕様を策定していた
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
余談: OpenTelemetry
- OpenTracingとOpenCensusが統合されて生まれたプロジェクト
- OpenTracingはTracesの標準化をしていたプロジェクト
- OpenCensusはTracesとMetricsの収集を補助するライブラリ
- OpenTracingはベンダー中立にPropagationするための仕様を策定していた
再掲
OpenTelemetryもOpenCensusに引き続き各言語向けにライブラリを提供
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
OpenTelemetry SDKの機能
- OpenMetrics, OpenTracing(OpenTelemetry)に準拠したMetrics, Tracesの出力
- Prometheusのクライアントライブラリを別途入れる必要なし
- 各種クライアントの自動Metrics, Traces収集, 自動Propagation
- HTTPクライアント
- DBクライアント
- とりあえずOpenTelemetryを入れるだけで外部IOへのTracesは概ね完了
- IOを伴わない部分のTracesは後から考えれば十分
- 個別でSpanを埋める対応が必要となる
- Metricsは自身での追加のMetricsの収集が必要
- Log Data ModelでログのサポートもあるがSDK側は未実装が多い
- 将来はこれだけでLogsまで任せられる可能性も
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
HTTPサーバならRequestIDを含める
- 慣例的にHTTPではX-Request-Idというヘッダでリクエストを一意に識別する
- 最前段のHTTPサーバで発行して、各HTTPクライアントはそれを引き回す
- これをアクセスログやエラーログに含めておくとリクエストをまとめて検索できる
指針: どのイベントに紐づくログであるかを記録する
再掲
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
HTTPサーバならRequestIDを含める
- 慣例的にHTTPではX-Request-Idというヘッダでリクエストを一意に識別する
- 最前段のHTTPサーバで発行して、各HTTPクライアントはそれを引き回す
- これをアクセスログやエラーログに含めておくとリクエストをまとめて検索できる
指針: どのイベントに紐づくログであるかを記録する
再掲
OpenTelemetry導入後は代わりにtrace-idを利用することができる
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
まとめ
エラーハンドリング
1. エラーをどう取り扱うかは呼び出し元に決めさせる
2. 必要なコンテキストを付与する
Logs
1. ユーザの個人情報など秘匿情報を記録しない
2. どのイベントに紐づくログであるかを記録する
3. 分析のしやすいフォーマットにする
Metrics
1. USEメソッド
2. REDメソッド
Traces
1. とりあえずOpenTelemetryを使っておく
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
最後に
- 可観測性は実装に詳しくない人が状況を判断するために必要
- 仕事の現場では自身だけがメンテナンスし続けるわけにはいかない
- 指針に従ってPrimary Signalsを収集することで可観測性を向上させることができる
- それぞれは補完しあうためどれも欠けてはならない
可観測性やパフォーマンスのような非機能要件こそ腕の見せ所
可観測性に優れたアプリケーションを実装しましょう
CNCFでも可観測性(Observability)は大きなトピックで投資価値は十分あると思います
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
おまけ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
プロファイラ
- プログラム実行中の関数の呼び出し回数や実行時間などを計測するためのソフトウェア
- 実行時にオーバーヘッドを伴うものが多く開発時に利用することが一般的
- プログラムのボトルネックを特定できる
- 代表的なソフトウェア
- Linux perf
- Valgrind
- google/pprof
- Go
- V8’s sample-based profiler(google/pprof-nodejs)
- Node.js
引用: https://github.com/google/pprof
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
sample-based profiler
- 統計的なアプローチで精度と引き換えにオーバーヘッドを最小化するプロファイラ
- google/pprof
- V8’s sample-based profiler(google/pprof-nodejs)
- 定期的にコールスタックを読んで収集する
- Event profilerは精度が高い一方でイベント数が多くオーバーヘッドが大きい
- Linux perfは両方に対応している
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
継続的プロファイリング
- プロファイラはオーバーヘッドが大きく開発時しか利用できなかった
- sample-based profilerと言えどもオーバーヘッドはある
- それらを利用した継続的プロファイリングを提供するサービスが開始
- Cloud Profiler
- Datadog Continuous Profiler
- 継続的プロファイリングでは1分間に10秒間だけのようにプロファイリングする
- Tracesと比較して個別で対応することなく関数のボトルネックを探すことができる
- プロファイリングはネットワークを跨ぐことはできないためその点でTracesは有用
- 可観測性を更に向上させるSignalの一つとなりつつある
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
eBPF
- eBPFはLinuxカーネルにおけるJavaScriptのようなもの
- JavaScriptと同様にサンドボックスなVM上で稼働する
- JavaScriptがHTMLにすることと同様にLinuxカーネルのイベントに処理をアタッチする
- C言語でeBPFプログラムを記述するとそれがカーネル空間で安全に実行される
- ユーザ空間に渡す必要がないから高速
- 様々なイベントに対応していて可観測性に対して大きな力を持つ
- kprobe/kretprobe: カーネルの関数呼び出し・終了
- uprobe/uretprobe: バイナリの任意のオフセットの関数の呼び出し・終了
- 可観測性の他にセキュリティ分野でも注目されていてCNCFの熱いトピックの一つ
- アプリケーションに影響を与えることなく危険なsyscallの実行を監視したり
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
PyroScope
- オープンソースの継続的プロファイリングのプラットフォーム
- Cloud Profiler他と同様にgoogle/pprofなどを使いながら継続的プロファイリングをする
- eBPFのサポートもありより小さいオーバーヘッドでの実行が期待できる
- ※ 現時点ではbccに依存していていくつかの問題がある
- 興味があれば: BPF Portability and CO-RE
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
LIFULLの内製PaaS KEEL
- コマンドを1発叩くだけで完璧なアプリケーション実行環境が手に入る内製PaaS
- デプロイ、セキュリティ、可観測性、信頼性、パフォーマンス
- コードジェネレータを中心とした開発者体験の提供
- Pull Requestを作成するとプレビューできる機能やLint, Content Trustまで備える
- https://www.lifull.blog/archive/category/Kubernetes
再掲

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

アーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーションアーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーション
 
Apache Hadoop YARNとマルチテナントにおけるリソース管理
Apache Hadoop YARNとマルチテナントにおけるリソース管理Apache Hadoop YARNとマルチテナントにおけるリソース管理
Apache Hadoop YARNとマルチテナントにおけるリソース管理
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
 
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
 
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
 
webエンジニアのためのはじめてのredis
webエンジニアのためのはじめてのrediswebエンジニアのためのはじめてのredis
webエンジニアのためのはじめてのredis
 
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
 
Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ (Hadoop / Spark Conference Japan 2019)
Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ (Hadoop / Spark Conference Japan 2019)Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ (Hadoop / Spark Conference Japan 2019)
Hadoop/Spark で Amazon S3 を徹底的に使いこなすワザ (Hadoop / Spark Conference Japan 2019)
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once Semantics
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
異次元のグラフデータベースNeo4j
異次元のグラフデータベースNeo4j異次元のグラフデータベースNeo4j
異次元のグラフデータベースNeo4j
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
 

Semelhante a 趣味と仕事の違い、現場で求められるアプリケーションの可観測性

Intalio会社概要とIntalio Bopの特長 030109
Intalio会社概要とIntalio Bopの特長 030109Intalio会社概要とIntalio Bopの特長 030109
Intalio会社概要とIntalio Bopの特長 030109
Tomoaki Sawada
 

Semelhante a 趣味と仕事の違い、現場で求められるアプリケーションの可観測性 (20)

ログについて改めて考えてみた
ログについて改めて考えてみたログについて改めて考えてみた
ログについて改めて考えてみた
 
第104回 php勉強会@東京 Laravel
第104回 php勉強会@東京 Laravel第104回 php勉強会@東京 Laravel
第104回 php勉強会@東京 Laravel
 
Aerospike deep dive LDTs
Aerospike deep dive LDTsAerospike deep dive LDTs
Aerospike deep dive LDTs
 
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
 
perfを使ったPostgreSQLの解析(後編)
perfを使ったPostgreSQLの解析(後編)perfを使ったPostgreSQLの解析(後編)
perfを使ったPostgreSQLの解析(後編)
 
2016年2月4日 空間OSの設計コンセプトと先端IT
2016年2月4日 空間OSの設計コンセプトと先端IT2016年2月4日 空間OSの設計コンセプトと先端IT
2016年2月4日 空間OSの設計コンセプトと先端IT
 
【Logic Apps編】ノンコーディングでデキる!お問い合わせフォーム機能拡張
【Logic Apps編】ノンコーディングでデキる!お問い合わせフォーム機能拡張【Logic Apps編】ノンコーディングでデキる!お問い合わせフォーム機能拡張
【Logic Apps編】ノンコーディングでデキる!お問い合わせフォーム機能拡張
 
Spring tools4
Spring tools4Spring tools4
Spring tools4
 
スマートニュースの世界展開を支えるログ解析基盤
スマートニュースの世界展開を支えるログ解析基盤スマートニュースの世界展開を支えるログ解析基盤
スマートニュースの世界展開を支えるログ解析基盤
 
RとWeb API
RとWeb APIRとWeb API
RとWeb API
 
MuleアプリケーションのCI/CD
MuleアプリケーションのCI/CDMuleアプリケーションのCI/CD
MuleアプリケーションのCI/CD
 
perfを使ったPostgreSQLの解析(前編)
perfを使ったPostgreSQLの解析(前編)perfを使ったPostgreSQLの解析(前編)
perfを使ったPostgreSQLの解析(前編)
 
140917運用管理勉強会job scheduler
140917運用管理勉強会job scheduler140917運用管理勉強会job scheduler
140917運用管理勉強会job scheduler
 
ServerlessConf Tokyo2018 サーバーレスなシステムのがんばらない運用監視
ServerlessConf Tokyo2018 サーバーレスなシステムのがんばらない運用監視ServerlessConf Tokyo2018 サーバーレスなシステムのがんばらない運用監視
ServerlessConf Tokyo2018 サーバーレスなシステムのがんばらない運用監視
 
Getting Started with Graph Database with Python
Getting Started with Graph Database with PythonGetting Started with Graph Database with Python
Getting Started with Graph Database with Python
 
ログブラウズ、解析サービスSumologicの紹介
ログブラウズ、解析サービスSumologicの紹介ログブラウズ、解析サービスSumologicの紹介
ログブラウズ、解析サービスSumologicの紹介
 
solr勉強会資料
solr勉強会資料solr勉強会資料
solr勉強会資料
 
Intalio会社概要とIntalio Bopの特長 030109
Intalio会社概要とIntalio Bopの特長 030109Intalio会社概要とIntalio Bopの特長 030109
Intalio会社概要とIntalio Bopの特長 030109
 
Apache Kuduを使った分析システムの裏側
Apache Kuduを使った分析システムの裏側Apache Kuduを使った分析システムの裏側
Apache Kuduを使った分析システムの裏側
 
XPagesDay 2015 RESTの総復習
XPagesDay 2015 RESTの総復習XPagesDay 2015 RESTの総復習
XPagesDay 2015 RESTの総復習
 

Mais de LIFULL Co., Ltd.

㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと
㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと
㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと
LIFULL Co., Ltd.
 

Mais de LIFULL Co., Ltd. (20)

20220319_新卒から活躍し続けるエンジニアが大切にしている5つのこと
20220319_新卒から活躍し続けるエンジニアが大切にしている5つのこと20220319_新卒から活躍し続けるエンジニアが大切にしている5つのこと
20220319_新卒から活躍し続けるエンジニアが大切にしている5つのこと
 
Kubernetesセキュリティの歩き方
Kubernetesセキュリティの歩き方Kubernetesセキュリティの歩き方
Kubernetesセキュリティの歩き方
 
LIFULLの全社アプリケーション実行基盤 KEEL について
LIFULLの全社アプリケーション実行基盤 KEEL についてLIFULLの全社アプリケーション実行基盤 KEEL について
LIFULLの全社アプリケーション実行基盤 KEEL について
 
Kubernetesクラスタバージョンアップを支える技術
Kubernetesクラスタバージョンアップを支える技術Kubernetesクラスタバージョンアップを支える技術
Kubernetesクラスタバージョンアップを支える技術
 
LIFULL HOME'SでのSolrの構成と運用の変遷
LIFULL HOME'SでのSolrの構成と運用の変遷LIFULL HOME'SでのSolrの構成と運用の変遷
LIFULL HOME'SでのSolrの構成と運用の変遷
 
LIFULLでは新卒エンジニアに 丸一日のテスト研修を行なっている
LIFULLでは新卒エンジニアに 丸一日のテスト研修を行なっているLIFULLでは新卒エンジニアに 丸一日のテスト研修を行なっている
LIFULLでは新卒エンジニアに 丸一日のテスト研修を行なっている
 
SaPID を導入するまでとそれから
SaPID を導入するまでとそれからSaPID を導入するまでとそれから
SaPID を導入するまでとそれから
 
3D間取りを支える技術
3D間取りを支える技術3D間取りを支える技術
3D間取りを支える技術
 
LIFULL HOME'Sのおとり広告予測モデルの開発
LIFULL HOME'Sのおとり広告予測モデルの開発LIFULL HOME'Sのおとり広告予測モデルの開発
LIFULL HOME'Sのおとり広告予測モデルの開発
 
大企業でアジャイル開発を推進できる条件とその心構え
大企業でアジャイル開発を推進できる条件とその心構え大企業でアジャイル開発を推進できる条件とその心構え
大企業でアジャイル開発を推進できる条件とその心構え
 
スクラムを利用したアジャイルオフショア開発のとりくみ
スクラムを利用したアジャイルオフショア開発のとりくみスクラムを利用したアジャイルオフショア開発のとりくみ
スクラムを利用したアジャイルオフショア開発のとりくみ
 
実践 マーケティングテクノロジーエンジニア
実践 マーケティングテクノロジーエンジニア実践 マーケティングテクノロジーエンジニア
実践 マーケティングテクノロジーエンジニア
 
エンジニア × マーケティングテクノロジー が必要な理由
エンジニア × マーケティングテクノロジー が必要な理由エンジニア × マーケティングテクノロジー が必要な理由
エンジニア × マーケティングテクノロジー が必要な理由
 
「空飛ぶホームズくん」を実現するVR技術
「空飛ぶホームズくん」を実現するVR技術「空飛ぶホームズくん」を実現するVR技術
「空飛ぶホームズくん」を実現するVR技術
 
ニオイセンサで思索する街の新たな指標
ニオイセンサで思索する街の新たな指標ニオイセンサで思索する街の新たな指標
ニオイセンサで思索する街の新たな指標
 
Well-beingを測る「LIFE WILL」開発の舞台裏
Well-beingを測る「LIFE WILL」開発の舞台裏Well-beingを測る「LIFE WILL」開発の舞台裏
Well-beingを測る「LIFE WILL」開発の舞台裏
 
㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと
㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと
㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと
 
ウェブアクセシビリティ推進活動はじめました
ウェブアクセシビリティ推進活動はじめましたウェブアクセシビリティ推進活動はじめました
ウェブアクセシビリティ推進活動はじめました
 
大きめレガシープロジェクトのフロント行く末
大きめレガシープロジェクトのフロント行く末大きめレガシープロジェクトのフロント行く末
大きめレガシープロジェクトのフロント行く末
 
新しい検索体験とデザインシステム
新しい検索体験とデザインシステム新しい検索体験とデザインシステム
新しい検索体験とデザインシステム
 

趣味と仕事の違い、現場で求められるアプリケーションの可観測性

  • 1. Copyright© LIFULL Co.,Ltd. All Rights Reserved.
  • 2. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 趣味と仕事の違い、 現場で求められるアプリケーションの可観測性 株式会社LIFULL 相原 魁
  • 3. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 目次 5.おまけ(時間があれば) 4.アプリケーションの可観測性の勘所 3.仕事のアプリケーションで求められるもの 2.趣味のアプリケーションでやりがちなこと 1.紹介
  • 4. Copyright© LIFULL Co.,Ltd. All Rights Reserved. - 株式会社LIFULL 相原 魁 - ソフトウェアエンジニア スペシャリスト(Platform Engineering, SRE) - 仕事ではKubernetesをベースとした内製PaaS KEELを開発・運用 - 趣味では主にRustを書いています - 全文検索ライブラリ - 分散検索エンジン - eBPF 自己紹介
  • 5. Copyright© LIFULL Co.,Ltd. All Rights Reserved. - 株式会社LIFULL 相原 魁 - ソフトウェアエンジニア スペシャリスト(Platform Engineering, SRE) - 仕事ではKubernetesをベースとした内製PaaS KEELを開発・運用 - 趣味では主にRustを書いています - 全文検索ライブラリ - 分散検索エンジン - eBPF 自己紹介 可観測性のプラットフォームも開発する立場 分散システムを開発する中で可観測性に注力
  • 6. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 「したい暮らしに、出会おう。」をコンセプトに掲げ、簡単で便利な住まい探しをお手伝いする不動産・住宅情報の総合サービスです。
 物件の探しやすさや住まいに関する情報の見つけやすさ、検討がしやすくなるように、様々な機能や情報を拡充していきます。
 今後も、ユーザーに寄り添いながら、ともに理想の住まい探しを実現します。

  • 7. Copyright© LIFULL Co.,Ltd. All Rights Reserved. LIFULLの内製PaaS KEEL - コマンドを1発叩くだけで完璧なアプリケーション実行環境が手に入る内製PaaS - デプロイ、セキュリティ、可観測性、信頼性、パフォーマンス - コードジェネレータを中心とした開発者体験の提供 - Pull Requestを作成するとプレビューできる機能やLint, Content Trustまで備える - https://www.lifull.blog/archive/category/Kubernetes
  • 8. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 本日のゴール 可観測性に優れたアプリケーションを実装できるようになる ※少しWebに寄った話になります ※後でリファレンスとして使えるよう説明的な資料にしているので今全てを理解する必要はないです
  • 9. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 趣味のアプリケーションでやりがちなこと
  • 10. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { retval, err := maybeError() if err != nil { log.Printf("an error occurred: %+v", err) } return retval } エラーをとりあえずでロギングするだけ
  • 11. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { retval, _ := maybeError() return retval } そもそもエラーをハンドリングをしない
  • 12. Copyright© LIFULL Co.,Ltd. All Rights Reserved. fn doSomething() RetVal { let result: Result<RetVal> = maybeError(); let retval = result.unwrap(); retval } Rustだったらunwrap()するだけとか
  • 13. Copyright© LIFULL Co.,Ltd. All Rights Reserved. def doSomething do maybeError rescue {} end Rubyなら全ての例外をもみ消したり
  • 14. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { start := time.Now() retval := maybeSlow() elapsed := time.Since(start) log.Printf("maybeSlow took: %s", elapsed) return retval } 実行時間の計測をログで頑張る
  • 15. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { retval := maybeSlow() return retval } そもそも実行時間を気にしない
  • 16. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func main() retval, err := doSomething() if err != nil { fmt.Fprintf(os.Stderr, "%+v", err) } } func doSomething() (*RetVal, error) {...} 折角もらったエラーを適当に標準エラーする
  • 17. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 仕事のアプリケーションで求められるもの
  • 18. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 趣味と仕事の違い - 開発者である自分自身だけが未来永劫メンテナンスし続けるわけではない - 実装に詳しくない人が状況を判断できる必要がある
  • 19. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 趣味と仕事の違い - 開発者である自分自身だけが未来永劫メンテナンスし続けるわけではない - 実装に詳しくない人が状況を判断できる必要がある ソースコードを読むことも書き換えることもなく必要な情報を取得できる
  • 20. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 可観測性 - 可観測性(observability)とは、システムの外部出力を観測することでシステムの内部状態を推 測可能かどうかの尺度である。 - 引用: 状態空間 (制御理論)#可観測性 - microservicesの流行などによってシステムの構成が複雑化して重要性が増してきている
  • 21. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Primary Signals Metrics Traces Logs 可観測性の基本的な3つのシグナル
  • 22. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Metrics Traces Logs - 特にフォーマットのないテキストデータ - 出力方法 - アプリケーションからファイルに書き込む - アプリケーションから標準出力・標準エラーする
  • 23. Copyright© LIFULL Co.,Ltd. All Rights Reserved. アプリケーションログ - エラーをはじめアプリケーション内のイベントを記録するログ
  • 24. Copyright© LIFULL Co.,Ltd. All Rights Reserved. HTTPサーバのアクセスログ - HTTPのサーバがリクエストを受けた時のログ
  • 25. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 監査ログ - 誰が何をしたかというイベントを記録するログ - 主に認証のあるアプリケーション等で出力する
  • 26. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Metrics Traces Logs - インデックス付きの数値データ - OpenMetricsで標準化が進んでいる - 数値データであるためLogsと比較して安価 - 出力方法 - エージェントが外部から観測して出力 - アプリケーション内で計測して出力
  • 27. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: OpenMetrics - Prometheusというモニタリングシステムを参考に標準化されたフォーマット - summary, gauge, counter, statesetといったいくつかのデータタイプでMetricsを表現 - エージェントあるいはアプリケーションがこのフォーマットに従って出力する - Datadogをはじめ多くのモニタリングシステムがサポート
  • 28. Copyright© LIFULL Co.,Ltd. All Rights Reserved. CPU, Memory Usage - Linuxでは /proc から取得することができる - /proc はプロセスの情報を持つ擬似ファイルシステム - /proc/<PID>/statでは14, 15個目がCPUに関する情報 - 実際はエージェントが勝手に収集してくれていることが大半
  • 29. Copyright© LIFULL Co.,Ltd. All Rights Reserved. アプリケーションのエラー数 - アプリケーション内部のエラー数のカウンタ - Logsでも表現できるがコストの観点からMetricsであるとよい 引用: kubernetes/autoscaler
  • 30. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Garbage Collectorに関する情報 pp GC.stat #{:count=>13, # :heap_allocated_pages=>50, # :heap_sorted_length=>69, # :heap_allocatable_pages=>19, # :heap_available_slots=>20383, # :heap_live_slots=>20256, # :heap_free_slots=>127, # :heap_final_slots=>0, # :heap_marked_slots=>17090, # :heap_eden_pages=>50, # :heap_tomb_pages=>0, # …} - ランタイム内に持っているGCの情報 - アプリケーション内で収集して出力する
  • 31. Copyright© LIFULL Co.,Ltd. All Rights Reserved. ミドルウェアの各種情報 - ミドルウェアによって出力されているMetrics - e.g. ngx_http_stub_status_module - エージェントが収集しに行って出力する - ミドルウェア自身が直接出力するケースも増えてきている
  • 32. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: Prometheus Exporter - Metricsを出力するためのPrometheus用のエージェント - PrometheusのMetrics表現はOpenMetricsと互換性があるため広く利用できる - OSSとして多くのPrometheus Exporterが存在する - MySQL Server Exporter - Redis Exporter - NGINX Prometheus Exporter - cAdvisor - 利用するミドルウェアに対応するPrometheus Exporterを探すことができる - EXPORTERS AND INTEGRATIONS
  • 33. Copyright© LIFULL Co.,Ltd. All Rights Reserved. インデックスとカーディナリティ - MetricsはラベルというKey-Valueを元にインデックスする - ラベルの数が多いとカーディナリティが高くなりコスト増 - e.g. {uri=”/items/1”}, {uri=”/items/2”}, … {uri=”/items/9999”} - こういった詳細な情報の表現はLogsの方が向く
  • 34. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Metrics Traces Logs - 依存関係を持つメタデータの有向非巡回グラフ - Spanというデータ構造の集合からなる - OpenTelemetryで標準化が進んでいる - 計測も保存も比較的コストが高い - サンプリング(間引き)をすることが一般的 - 出力方法 - アプリケーション内で計測して出力
  • 35. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: OpenTelemetry - OpenTracingとOpenCensusが統合されて生まれたプロジェクト - OpenTracingはTracesの標準化をしていたプロジェクト - OpenCensusはTracesとMetricsの収集を補助するライブラリ - OpenTracingはベンダー中立にPropagationするための仕様を策定していた
  • 36. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 引用: Jaeger documentation
  • 37. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 引用: Jaeger documentation Span
  • 38. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 引用: Jaeger documentation Span Trace
  • 39. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Span - 開始・終了のタイムスタンプとKey-Valueのラベル等を持つ - 0つ以上の親となるSpanを持つことができる 引用: OpenTracing Specification
  • 40. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Propagation - アプリケーションをまたいだ依存関係を持つことができる - アプリケーション間の依存関係はHTTPヘッダで引き回す - W3C Trace Context - traceparent Header - trace-id - parent-id - sampled - microservicesの依存関係を可視化することができる
  • 41. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { start := time.Now() retval := maybeSlow() elapsed := time.Since(start) log.Printf("maybeSlow took: %s", elapsed) return retval } 実行時間の計測をログで頑張る 再掲
  • 42. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { start := time.Now() retval := maybeSlow() elapsed := time.Since(start) log.Printf("maybeSlow took: %s", elapsed) return retval } 実行時間の計測をログで頑張る maybeSlowが複雑な依存関係を持つ場合Metricsだけでは調査しづらい Tracesも収集することで依存関係のボトルネックを探せるようにしたい 再掲
  • 43. Copyright© LIFULL Co.,Ltd. All Rights Reserved. OpenMetricsとExemplars - OpenMetricsは外部のデータに対する参照を持つことができる - ExemplarsというKey-Value - MetricsとTracesを関連付けることができる 引用: Exemplars | Grafana Labs
  • 44. Copyright© LIFULL Co.,Ltd. All Rights Reserved. ここまでのまとめ - 実装に詳しくない人が状況を判断できるよう可観測性が重要 - 可観測性には3つの性質の違う主要なシグナルがある - Logs: 自由度が高くフォーマットを持たないテキストデータ - Metrics: 詳細な情報を安価に表現するインデックスつきの数値データ - Traces: 複雑な依存関係を表現できるメタデータの有向グラフ - それぞれ補完しあう関係にあるため組み合わせて使う - Metricsはコストが安いが詳細情報や依存関係を持てない - Logsは詳細情報を持てるがコストが高い - Tracesは依存関係を持てるが表現が限定的でコストが少し高い
  • 45. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: 周辺エコシステム - Logs - Grafana Loki, ElasticSearch - Amazon CloudWatch Logs - Cloud Logging - Metrics - Prometheus(Cortex) - Amazon CloudWatch - Cloud Monitoring - Traces - Grafana Tempo, Jaeger - AWS X-Ray - Cloud Trace - All-in-one - Datadog - NewRelic - Grafana(?) - OSSのObservability Platform - Loki, Cortex, TempoのGrafana Labsが開発 OpenMetrics, OpenTelemetry含め殆どがCNCF周りのもの
  • 46. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: CNCF - > Cloud Native Computing Foundationは、オープンソースでベンダー中立プロジェクトのエコシ ステムを育成・維持して、このパラダイムの採用を促進したいと考えてます。 私たちは最先端 のパターンを民主化し、これらのイノベーションを誰もが利用できるようにします。 (https://github.com/cncf/toc/blob/main/DEFINITION.md) 引用: CNCF Landscape
  • 47. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 引用: CNCF Landscape
  • 48. Copyright© LIFULL Co.,Ltd. All Rights Reserved. ケーススタディ: レスポンス速度の遅延 1.どうやらレスポンス速度が遅くなっているらしいと監視から通知を受け取る 2.まずはMetricsからどんなアプリケーションのどのリクエストが遅延したか確認 foo Applicationの /bar が遅延していた 3.次はLogsでfoo Applicationの /bar でエラーログが出力されていないかどうかを確認 このリクエストはrequestid=bazでこのrequestidにエラーログはなかった 4.Tracesでrequestidを調べるとMySQLにクエリしていてその速度が遅延していた 5.MySQLに関するMetricsを確認すると同時間帯に接続数が増大していた
  • 49. Copyright© LIFULL Co.,Ltd. All Rights Reserved. アプリケーションの可観測性の勘所
  • 50. Copyright© LIFULL Co.,Ltd. All Rights Reserved. エラーハンドリング 指針 1. エラーをどう取り扱うかは呼び出し元に決めさせる - Logs, Metricsはエラーを起点とすることが多い - エラーハンドリングを正しくしていないと出力しづらい 2. 必要なコンテキストを付与する
  • 51. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { retval, err := maybeError() if err != nil { log.Printf("an error occurred: %+v", err) } return retval } エラーをとりあえずでロギングするだけ 再掲
  • 52. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { retval, _ := maybeError() return retval } そもそもエラーをハンドリングをしない 再掲
  • 53. Copyright© LIFULL Co.,Ltd. All Rights Reserved. fn doSomething() RetVal { let result: Result<RetVal> = maybeError(); let retval = result.unwrap(); retval } Rustだったらunwrap()するだけとか 再掲
  • 54. Copyright© LIFULL Co.,Ltd. All Rights Reserved. def doSomething do maybeError rescue {} end Rubyなら全ての例外をもみ消したり 再掲
  • 55. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() (*RetVal, error) { retval, err := maybeError() if err != nil { return nil, xerrors.Errorf("failed to execute maybeError: %w", err) } return retval, nil } 指針 1. エラーをどう取り扱うかは呼び出し元に決めさせる 2. 必要なコンテキストを付与する ① ② 独自のエラー型・例外でラップするなど
  • 56. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: 例外を乱用しない - 例外でラップする例を挙げたが例外は乱用してはならない - フロー制御として使うにはコストが高い - 例外はあくまで”例外”であるため普段起こりうるフローでは利用しない - Replacing Throwing Exceptions with Notification in Validations - エラーハンドラ
  • 57. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Logs 指針 1. ユーザの個人情報など秘匿情報を記録しない - 秘匿情報が記録されたログは閲覧者が制限される - 可観測性が満たされない 2. どのイベントに紐づくログであるかを記録する 3. 分析のしやすいフォーマットにする
  • 58. Copyright© LIFULL Co.,Ltd. All Rights Reserved. HTTPのURIに秘匿情報を含めない - アクセスログにそのままpasswordが記録されてしまう GET /secrets?password=foobar HTTP/1.1 Host: example.com User-Agent: curl/7.58.0 Accept: */* 指針: ユーザの個人情報など秘匿情報を記録しない
  • 59. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 外部からの入力をそのままログにしない - パラメータとしてユーザの電話番号を受け取っていた場合ログに出力されてしまう def validation(parameters) parameters.each do |parameter| if rules[parameter[:key]].valid?(parameter[:value]) STDERR.puts "#{parameter[:value]} is invalid" end end end 指針: ユーザの個人情報など秘匿情報を記録しない
  • 60. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func main() retval, err := doSomething() if err != nil { fmt.Fprintf(os.Stderr, "%+v", err) } } func doSomething() (*RetVal, error) {...} 折角もらったエラーを適当に標準エラーする 再掲
  • 61. Copyright© LIFULL Co.,Ltd. All Rights Reserved. HTTPサーバならRequestIDを含める - 慣例的にHTTPではX-Request-Idというヘッダでリクエストを一意に識別する - 最前段のHTTPサーバで発行して、各HTTPクライアントはそれを引き回す - これをアクセスログやエラーログに含めておくとリクエストをまとめて検索できる 指針: どのイベントに紐づくログであるかを記録する
  • 62. Copyright© LIFULL Co.,Ltd. All Rights Reserved. ログの出力元やStack Traceを含める - ソースコードのどこで原因となるイベントが発生したかを調べられる必要がある - Stack Traceはデータ量が大きい反面、情報量が多い - ログを見た後、詳細な調査が必要なエラーでStack Traceを出力することが多い - 前述の通り呼び出し元がエラーを受け取りStack Traceを出力する 指針: どのイベントに紐づくログであるかを記録する
  • 63. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 必要に応じてJSONで出力する - 主要なLogsのObservability PlatformはJSONをParseする機能を備えている - HTTPサーバのアクセスログなどログを元に分析する場合はJSONが好ましい - syslogやLTSVなどその他のフォーマットもあるがPlatformのサポートが厚いのはJSON 指針: 分析のしやすいフォーマットにする
  • 64. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: ログレベル(持論) - ログレベルとは対象のログの深刻度を示すもの - 一般に以下のようなログレベルが採用されることが多い - DEBUG - INFO - WARN - ERROR - CRITICAL - ログは前述の通りコストが高いため無視されるログは必要がない - 不用意にログレベルを増やすと無視されるログを増やすことに繋がる - 全てのエラーは等しく対応をすべきだとして以下のみから始めることが多い - DEBUG - INFO - ERROR
  • 65. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Metrics 指針 1. USEメソッド - Utilization - Saturations - Errors 2. REDメソッド - Rate - Errors - Duration
  • 66. Copyright© LIFULL Co.,Ltd. All Rights Reserved. USEメソッド Worker Worker Worker Master - Brendan Greggによって提唱されたMetrics収集の方法論 - あるリソースに対してUtilization, Saturations, Errorsを収集する - 各リソースのMetricsの例示は The USE Method を参照 - ハードウェアリソースはエージェントが既に収集していることが多い - エージェントの不足分やソフトウェアリソースをUSEメソッドに従って収集する - 古典的なTCPサーバで考えた場合 - Utilization: ActiveなWorker数 / 総Worker数 - Saturations: Backlogに積まれたIn-QueueなConnection数 - Errors: ECONNREFUSEDが返った数 ECONNREFUSED
  • 67. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 引用: The USE Method
  • 68. Copyright© LIFULL Co.,Ltd. All Rights Reserved. REDメソッド - USEメソッドがリソース単位であることに対してREDメソッドはサービス単位 - REDメソッドの適用先はより限定的 - It is fair to say this method only works for request-driven services(The RED Method) - あるサービスに対してRate, Errors, Durationを収集する - microservicesの場合はデータストア含む依存するサービスに対して収集を考える - 検索エンジンで考えた場合 - Rate: 検索エンジンに対するRequests per second - Errors: レスポンスのエラー数 - Duration: レスポンスのレイテンシ
  • 69. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { start := time.Now() retval := maybeSlow() elapsed := time.Since(start) log.Printf("maybeSlow took: %s", elapsed) return retval } 実行時間の計測をログで頑張る 再掲
  • 70. Copyright© LIFULL Co.,Ltd. All Rights Reserved. func doSomething() *RetVal { start := time.Now() retval := maybeSlow() elapsed := time.Since(start) log.Printf("maybeSlow took: %s", elapsed) return retval } 実行時間の計測をログで頑張る この手のものはMetricsとして管理してコストを安くしたい 再掲
  • 71. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 出力の方法 - アプリケーションがOpenMetrics形式でMetricsを出力する - Prometheusのクライアントライブラリを入れるなど - アプリケーションのMetricsをエージェントが収集して出力する - nginxの/nginx_statusをNGINX Prometheus Exporterが出力するなど
  • 72. Copyright© LIFULL Co.,Ltd. All Rights Reserved. メソッドに従うことのメリット - Metricsは収集した後に監視・可視化をするが、処理を共通化させやすい - 抜け漏れなくMetricsを収集することができる - これらはあくまで指針であるためアプリケーション固有のものは別途収集する - Garbage Collectorの情報 - アプリケーションの状態 - ランタイム固有のグリーンスレッドの数
  • 73. Copyright© LIFULL Co.,Ltd. All Rights Reserved.
  • 74. Copyright© LIFULL Co.,Ltd. All Rights Reserved. - CPUの使用率にPod間の偏りが存在する(Sticky Session下での過負荷など) - cgroupで設定したlimits.memoryまでメモリを使い切れていない - メトリクスの収集に失敗している - NetworkのReceiveでパケットが落とされている - NetworkのTransmitでパケットが落とされている - Podがrestartを短時間に繰り返している - Podがスケジュール待ちなど不正な状態が継続している - PodのHealthCheckが失敗している - 全てのPodのHealthCheckが失敗している - PodがImageの取得に失敗するなどして待機状態になっている - Podのメモリが不足し始めている - Nodeのリソース不足などが原因でPodが大量に退避させれている - Podがスケールアウトの限界に近付いている - Podのエラーレートが増加している - Podの特定のURIのエラーレートが増加している and more...
  • 75. Copyright© LIFULL Co.,Ltd. All Rights Reserved.
  • 76. Copyright© LIFULL Co.,Ltd. All Rights Reserved. Traces 指針 1. とりあえずOpenTelemetryを使っておく
  • 77. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: OpenTelemetry - OpenTracingとOpenCensusが統合されて生まれたプロジェクト - OpenTracingはTracesの標準化をしていたプロジェクト - OpenCensusはTracesとMetricsの収集を補助するライブラリ - OpenTracingはベンダー中立にPropagationするための仕様を策定していた 再掲
  • 78. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 余談: OpenTelemetry - OpenTracingとOpenCensusが統合されて生まれたプロジェクト - OpenTracingはTracesの標準化をしていたプロジェクト - OpenCensusはTracesとMetricsの収集を補助するライブラリ - OpenTracingはベンダー中立にPropagationするための仕様を策定していた 再掲 OpenTelemetryもOpenCensusに引き続き各言語向けにライブラリを提供
  • 79. Copyright© LIFULL Co.,Ltd. All Rights Reserved.
  • 80. Copyright© LIFULL Co.,Ltd. All Rights Reserved. OpenTelemetry SDKの機能 - OpenMetrics, OpenTracing(OpenTelemetry)に準拠したMetrics, Tracesの出力 - Prometheusのクライアントライブラリを別途入れる必要なし - 各種クライアントの自動Metrics, Traces収集, 自動Propagation - HTTPクライアント - DBクライアント - とりあえずOpenTelemetryを入れるだけで外部IOへのTracesは概ね完了 - IOを伴わない部分のTracesは後から考えれば十分 - 個別でSpanを埋める対応が必要となる - Metricsは自身での追加のMetricsの収集が必要 - Log Data ModelでログのサポートもあるがSDK側は未実装が多い - 将来はこれだけでLogsまで任せられる可能性も
  • 81. Copyright© LIFULL Co.,Ltd. All Rights Reserved. HTTPサーバならRequestIDを含める - 慣例的にHTTPではX-Request-Idというヘッダでリクエストを一意に識別する - 最前段のHTTPサーバで発行して、各HTTPクライアントはそれを引き回す - これをアクセスログやエラーログに含めておくとリクエストをまとめて検索できる 指針: どのイベントに紐づくログであるかを記録する 再掲
  • 82. Copyright© LIFULL Co.,Ltd. All Rights Reserved. HTTPサーバならRequestIDを含める - 慣例的にHTTPではX-Request-Idというヘッダでリクエストを一意に識別する - 最前段のHTTPサーバで発行して、各HTTPクライアントはそれを引き回す - これをアクセスログやエラーログに含めておくとリクエストをまとめて検索できる 指針: どのイベントに紐づくログであるかを記録する 再掲 OpenTelemetry導入後は代わりにtrace-idを利用することができる
  • 83. Copyright© LIFULL Co.,Ltd. All Rights Reserved. まとめ エラーハンドリング 1. エラーをどう取り扱うかは呼び出し元に決めさせる 2. 必要なコンテキストを付与する Logs 1. ユーザの個人情報など秘匿情報を記録しない 2. どのイベントに紐づくログであるかを記録する 3. 分析のしやすいフォーマットにする Metrics 1. USEメソッド 2. REDメソッド Traces 1. とりあえずOpenTelemetryを使っておく
  • 84. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 最後に - 可観測性は実装に詳しくない人が状況を判断するために必要 - 仕事の現場では自身だけがメンテナンスし続けるわけにはいかない - 指針に従ってPrimary Signalsを収集することで可観測性を向上させることができる - それぞれは補完しあうためどれも欠けてはならない 可観測性やパフォーマンスのような非機能要件こそ腕の見せ所 可観測性に優れたアプリケーションを実装しましょう CNCFでも可観測性(Observability)は大きなトピックで投資価値は十分あると思います
  • 85. Copyright© LIFULL Co.,Ltd. All Rights Reserved. おまけ
  • 86. Copyright© LIFULL Co.,Ltd. All Rights Reserved. プロファイラ - プログラム実行中の関数の呼び出し回数や実行時間などを計測するためのソフトウェア - 実行時にオーバーヘッドを伴うものが多く開発時に利用することが一般的 - プログラムのボトルネックを特定できる - 代表的なソフトウェア - Linux perf - Valgrind - google/pprof - Go - V8’s sample-based profiler(google/pprof-nodejs) - Node.js 引用: https://github.com/google/pprof
  • 87. Copyright© LIFULL Co.,Ltd. All Rights Reserved. sample-based profiler - 統計的なアプローチで精度と引き換えにオーバーヘッドを最小化するプロファイラ - google/pprof - V8’s sample-based profiler(google/pprof-nodejs) - 定期的にコールスタックを読んで収集する - Event profilerは精度が高い一方でイベント数が多くオーバーヘッドが大きい - Linux perfは両方に対応している
  • 88. Copyright© LIFULL Co.,Ltd. All Rights Reserved. 継続的プロファイリング - プロファイラはオーバーヘッドが大きく開発時しか利用できなかった - sample-based profilerと言えどもオーバーヘッドはある - それらを利用した継続的プロファイリングを提供するサービスが開始 - Cloud Profiler - Datadog Continuous Profiler - 継続的プロファイリングでは1分間に10秒間だけのようにプロファイリングする - Tracesと比較して個別で対応することなく関数のボトルネックを探すことができる - プロファイリングはネットワークを跨ぐことはできないためその点でTracesは有用 - 可観測性を更に向上させるSignalの一つとなりつつある
  • 89. Copyright© LIFULL Co.,Ltd. All Rights Reserved. eBPF - eBPFはLinuxカーネルにおけるJavaScriptのようなもの - JavaScriptと同様にサンドボックスなVM上で稼働する - JavaScriptがHTMLにすることと同様にLinuxカーネルのイベントに処理をアタッチする - C言語でeBPFプログラムを記述するとそれがカーネル空間で安全に実行される - ユーザ空間に渡す必要がないから高速 - 様々なイベントに対応していて可観測性に対して大きな力を持つ - kprobe/kretprobe: カーネルの関数呼び出し・終了 - uprobe/uretprobe: バイナリの任意のオフセットの関数の呼び出し・終了 - 可観測性の他にセキュリティ分野でも注目されていてCNCFの熱いトピックの一つ - アプリケーションに影響を与えることなく危険なsyscallの実行を監視したり
  • 90. Copyright© LIFULL Co.,Ltd. All Rights Reserved. PyroScope - オープンソースの継続的プロファイリングのプラットフォーム - Cloud Profiler他と同様にgoogle/pprofなどを使いながら継続的プロファイリングをする - eBPFのサポートもありより小さいオーバーヘッドでの実行が期待できる - ※ 現時点ではbccに依存していていくつかの問題がある - 興味があれば: BPF Portability and CO-RE
  • 91. Copyright© LIFULL Co.,Ltd. All Rights Reserved. LIFULLの内製PaaS KEEL - コマンドを1発叩くだけで完璧なアプリケーション実行環境が手に入る内製PaaS - デプロイ、セキュリティ、可観測性、信頼性、パフォーマンス - コードジェネレータを中心とした開発者体験の提供 - Pull Requestを作成するとプレビューできる機能やLint, Content Trustまで備える - https://www.lifull.blog/archive/category/Kubernetes 再掲