Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Djangoアプリケーション運用のリアル〜問題発生から可視化、最適化への道〜 / django...
Search
Kashun Yoshida
October 07, 2023
Programming
300
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Djangoアプリケーション運用のリアル〜問題発生から可視化、最適化への道〜 / django-application-realities
https://djangocongress.jp/
#djangocongress
Kashun Yoshida
October 07, 2023
More Decks by Kashun Yoshida
See All by Kashun Yoshida
サプライチェーン攻撃対策「層を重ねて落ちない壁」を10日間で組み上げた話 #TechLeadConf2026
kashewnuts
1
630
AIとペアプロして処理時間を97%削減した話 #pyconshizu
kashewnuts
1
520
企業がDjangoを使う際に、特にセキュリティで気をつけること
kashewnuts
1
300
Django Ninja による API 開発効率化とリプレースの実践
kashewnuts
1
2.4k
Django NinjaによるAPI開発の効率化とリプレースの実践
kashewnuts
2
1.5k
Djangoアプリケーション 運用のリアル 〜問題発生から可視化、最適化への道〜 #pyconshizu
kashewnuts
2
1.8k
開発環境の垣根を超えるLanguage Server Protocol入門 / Introduction to Language Server Protocol beyond the boundaries of the development environment
kashewnuts
2
4.5k
Django で始める PyCharm 入門
kashewnuts
1
120
Other Decks in Programming
See All in Programming
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
130
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
130
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
110
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
300
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
56
37k
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
200
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
130
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
430
Building an Out-of-Order CPU
latte72
1
750
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
Swift愛好会100回記念 第1回を振り返る
jollyjoester
0
120
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
600
Featured
See All Featured
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
350
Navigating Team Friction
lara
192
16k
GitHub's CSS Performance
jonrohan
1033
470k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.9k
エンジニアに許された特別な時間の終わり
watany
108
250k
Building AI with AI
inesmontani
PRO
1
1.2k
HDC tutorial
michielstock
2
860
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
The World Runs on Bad Software
bkeepers
PRO
72
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Darren the Foodie - Storyboard
khoart
PRO
3
3.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Transcript
Djangoアプリケーション運用 のリアル 〜問題発生から可視化、最適化への道〜 DjangoCongress JP 2023 @kashew_nuts
お品書き • 会社と登壇者について紹介 • 発表の動機とゴール • アプリケーションを運用している中でのつらみ共有 • つらみをどのように解消できるようにしていったか •
取り組みの結果できるようになったこと • まとめ
Who am I? / お前誰よ • 吉田花春 (Yoshida Kashun) •
@kashew_nuts • BeProud Inc. • Software Developer • 開発環境整備とボルダリングが趣味
What's • Pythonメインで受託開発・研修・自社サービスの運営 • 私は主にconnpassの開発/運営をしています • フルリモートワーキング (5days/week)
発表の動機 • 開発が完了し、リリース後に不具合対応で土日出勤した 経験があった • それ以降も調査するための材料が足りなくて、非常に調 査が時間がかかることがあった • 運用に乗ってからも改善する中で見えることもあった が、まとめたりしていなかった
• 過去の自分や似通った人の導入になればと思った
想定する聞き手 • 現在アプリケーションの開発をしているが、リリースさ れた後の運用について知見を深めたい人 • アプリケーションの運用をもっと楽にしたい人 • 運用時のつらみを共有したい人
アプリケーションを運用する中でのつらみ • ユーザーからシステムエラーが発生したと言われたが、エラー が発生した箇所がわからない • ログが出力されていなくて、何が発生したのか調査できない • ログメッセージが適切でなく、対処方法がわからない • CPUやメモリの使用率が張り付いているが、原因がわからない
• エラー通知が鳴り続けて現場が疲弊する • アラートの調査に時間が取られて、開発の時間が取れない
システムで何が起きて いるか調査できるよう にしたい
つらみをどのように観測していくか 1. エラーやログを取得する 2. APM(Application Performance Monitoring)を活用して ボトルネックを解消する 3. カスタムメトリクスを計装して、問題の原因を把握でき
るようにする
1. エラーやログを取得 する
【現実】ログから判断できない • 例外をキャッチして握りつぶしていて、何が起きている かわからない • アプリ側でログ出力の設定が未整備 • どの操作でAPIが呼ばれているかわからない • DEBUGしか出力しておらず、本番では出力されない
• エラーメッセージから何をしたらいいかわからない
【理想】ログから判断できるようにする • 5W1Hがわかる:特にエラーログ ◦ 「いつ」「どこで」「だれが」「なぜ」「何が起きて」「何をす ればいいのか」 • (例) ◦ 「request_id:
xxx 10:00 INFO 指示書の確定処理が完了」 ◦ 「request_id: yyy 11:00 WARNING 既存システムとの接続に 失敗。〇〇に連絡してください。」
【対策】ログから判断できるようにする 1. INFO、ERROR だけでなくログレベルを使い分ける 1.1. CRITICAL:システム全体や連携システムに影響する重大な問題発生時の情報 1.2. ERROR:プログラム上の処理が中断したり、停止した場合の情報 1.3. WARNING:プログラムの処理は続いているが何か良くないデータや通知の情報
1.4. INFO:プログラムの状況やデータ数など後で挙動を把握しやすくする情報 1.5. DEBUG:ローカル環境で開発するときだけつかう情報 2. APIリクエストのstart/end時にログを出力 2.1. リクエストID, 日時, エンドポイント, ステータスコード 2.2. django-structlogのような構造化ロギングを可能にするライブラリを活用する 3. 5W1Hがわかるようにメッセージ内容を修正する
django-structlogでのログ出力設定例 1. $ pip install django-structlog 2. getting_startedを例にsettings.pyに設定を追加 3. Pythonコードからログを出力する
>>> import structlog >>> logger = structlog.get_logger(__name__) >>> logger.warning("既存システムとの接続に失敗。〇〇に連絡してください。 ") {"request_id": "3a8f801c-072b-4805-8f38-e1337f363ed4", "user_id": 1,"ip": "0.0.0.0","level": "warning", "event": "既存システムとの接続に失敗。〇〇に連絡してください。 ", "timestamp": "2023-10-07T10:07:31.089925Z", "logger": "my_awesome_project.my_awesome_module"}
Tips: ロギングフォーマットのミスを防ぐ RuffやFlake8 拡張を使って記述ミスを防ぐ $ pip install ruff # flake8-logging-format(G)とflake8-logging(LOG)を確認
$ ruff check --select G,LOG path/to/code/
【現実】エラー発生時すぐ検知できない • ユーザーからエラーが発生したと連絡がくる • 渡されたエラーログはgrepした1行目の画面キャプチャ ◦ せめてトレースバックください..... • ログだとどんなrequestデータだったのかわからない •
調査にはサーバーにVPNつないでssh接続して、 journalctlコマンドで.... • 調査してる間に別のエラーが....つらい....
【理想】エラーがあったときすぐ検知できる • ERRORやWARNINGがあったらSlackに通知が届く! ◦ だれでも調査開始できる • 問い合わせが来る前に原因把握と対策の検討まで終わっ てる!
【対策】エラーがあったときすぐ検知できる • Sentry の導入 ◦ エラートラッキングサービスを活用 • ERRORやWARNINGがあったら Slackに通知がくる! ◦
だれでも調査開始できる • ログ情報にとどまらず、様々な情報 がすぐわかる ◦ エラーが発生した環境 ◦ POSTされたデータや発行された SQL ◦ エラー発生頻度
Sentryの導入例 1. $ pip install sentry-sdk 2. settings.pyに以下の内容を追記 import sentry_sdk
sentry_sdk.init( dsn="<your DSN here>", traces_sample_rate=1.0 ) 3. Sentry側の設定を有効にした後、エラー発生時はSentryに通知 4. ORM用の設定する際はDjango integrationの設定を参考にする
SentryでDjango integrationの設定 import sentry_sdk.utils sentry_sdk.utils.MAX_STRING_LENGTH = 2048 # monkey patch
first import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.logging import LoggingIntegration # デフォルトでは ERROR 以上しかevent登録されないので、WARNING以上にする sentry_logging = LoggingIntegration(level=logging.INFO, event_level=logging.WARNING) sentry_sdk.init( dsn=SENTRY_DSN, integrations=[sentry_logging, DjangoIntegration()], # Associate users to errors (if using django.contrib.auth) send_default_pii=True, _experiments={'record_sql_params': True} )
SentryのSlack通知例
2. APMを活用して ボトルネックを解消する
【現実】アプリケーションがなぜか重い • お客さんから画面を開くのが遅いと報告がくる • メトリクスをみると何故かCPU利用率やI/Oが高い • 開発時は問題なかったが、データ量が増えると重い • コードをよく読むとN+1問題のあるコードが散在 •
非同期処理を活用できていなくてボトルネック化 ◦ ex) メール送信、ファイル操作
【理想】アプリのどこが重いかがわかる • ツールを活用してAPIや画面のボトルネックが測定できる ◦ スロークエリの発見 ◦ リクエストIDごとに、処理にかかった時間を集計する • パフォーマンスに問題があったらSlackに通知が届く ◦
N+1が発生している箇所がわかる
【対策】APMを活用してボトルネック解消 • APM:アプリケーションパフォーマンスモニタリング ◦ SentryのPerformance Monitoring ◦ DatadogのAPM • CloudWatch
Logs Insightsで使ったログデータの分析も 便利 ◦ スロークエリの発見
Sentryの導入例 1. $ pip install sentry-sdk 2. settings.pyに以下の内容を追記 import sentry_sdk
sentry_sdk.init( dsn="<your DSN here>", traces_sample_rate=1.0 ) 3. エラー発生時にSentryに通知される
None
None
SentryからN+1が発生したSlack通知例
CloudWatch Logs Insightsでの分析例
ちょっと休憩
イベントに参加すると聞かれること Q. って人を募集してるんですか?
A. 募集しています!!! We Are Hiring ! Pythonエンジニア https://www.beproud.jp/careers/python/ カジュアル面談 https://onl.tw/LPVc2hd
休憩終わり
3. カスタムメトリクスを 計装し問題の原因を把握
【現実】メトリクスはあるが原因が不明 • メトリクス:システムのパフォーマンスに関するデータ ◦ ex) CPUやメモリ、Diskなどリソース使用状況 • DBの使用率が突然高くなった ◦ 特定IPアドレス/UserAgentからの過度なアクセス
◦ 通知用のCeleryキューが溜まっている
【理想】カスタムメトリクスで把握できる • 取得したログからメトリクスを作成できる • メトリクスはダッシュボードを活用して一覧化 • 各メトリクスの関連性をともなった状況を把握できる • 状況が把握できると、問題解決のために対策を打てる
【対策】Datadogを活用する • ログ分析やAPM、各サービスとのインテグレーション、 カスタムメトリクスなど多種多様な機能を提供するSaaS • ダッシュボードを作成することで対象のメトリクスから どのようにシステムが連携しているかわかる
Datadog導入例 1. $ pip install ddtrace 2. settings.pyのLOGGINGにDatadog用の記述追加(後述) 3. #
ログ分析と統合したAPMを有効にしている例 4. $ DD_LOGS_INJECTION=1 \ ddtrace-run gunicorn myapp.wsgi:application 5. Datadogのエージェントを有効にしメトリクスとログを収集
settings.py: python-json-loggerの設定例 LOGGING = { "formatters": { "json": { "class":
"pythonjsonlogger.jsonlogger.JsonFormatter", "format": "%(pathname)s %(lineno)d %(asctime)s %(process)d %(thread)d %(levelname)s %(module)s %(message)s %(name)s %(dd.env)s %(dd.service)s %(dd.version)s %(dd.trace_id)s %(dd.span_id)s", }, }, "loggers": {"ddtrace": {"level": "WARNING"}}, # 以降略 }
Tips: manage.pyコマンドもトレース # https://github.com/DataDog/dd-trace-py/issues/1341 # manage.py import sys import ddtrace
name = sys.argv[1] if len(sys.argv) > 1 else None @ddtrace.tracer.wrap(name=name) def main(): # 略
監視項目をダッシュボードで一覧表示
取り組みの結果 できるようになったこと
問題を観測し、解消できるようになってきた 1. エラーやログを取得して何が起きているか把握できる ✅ 2. APM(Application Performance Monitoring)を活用して ボトルネックを特定・解消できる ✅
3. カスタムメトリクスを計装し、問題が把握できる ✅
実現できたこと • Sentry: エラートラッキング • Datadog: ログ分析やモニタリング、アラート • Aurora(MySQL): レーテンシー、メモリ低下、コネクション増加
• ElastiCache(Redis):Auroraの項目+SwapUsage • ELB: 5xx response, unhealthy • OpenSearch(ElasticSearch): 死活監視 • Celeryのワーカー数/キュー数 • IPアドレス/UserAgent: アクセス数
可視化できるようになり楽になったこと • メンバー(nonエンジニア)が直接調査できる ◦ 開発者が開発に専念しやすい • ログやAPM、メトリクスなど各機能を横断して閲覧 • 各画面をパーマリンクで開けるのでチームへの共有が楽 •
リソースの負荷が高まったときに何が原因かわかる ◦ 人数が多いイベントの通知のキュー数 ◦ 特定のIPアドレス/UserAgentからの攻撃の発生 ◦ 想定外に実行時間がかかっているSQLの発見
TL;DR • 問題を調査しやすい環境づくりをしていきましょう ◦ これから用意するなら、まずはログから • アプリケーションをよく理解して計測していきましょう ◦ 自分たちのサービスを改善していくのは自分たち •
状況は人それぞれ違うので一歩一歩改善してきましょう ◦ 銀の弾丸はない。ツールは頼りになるが評価し試していく
参考URL • 自走プログラマー • 入門監視 • エキスパートPythonプログラミング 改訂4版 • オブザーバビリティ・エンジニアリング
• Python | Sentry Documentation • Datadog Docs • ddtrace documentation
ご清聴ありがとうございました!! We Are Hiring ! Pythonエンジニア https://www.beproud.jp/careers/python/ カジュアル面談 https://onl.tw/LPVc2hd