ホームページ > バックエンド開発 > Python チュートリアル > AppSignal for Python による高度な Open edX モニタリング

AppSignal for Python による高度な Open edX モニタリング

Susan Sarandon
リリース: 2024-11-29 19:54:12
オリジナル
893 人が閲覧しました

このシリーズの最初の部分では、AppSignal が Open edX プラットフォームの堅牢性をどのように大幅に強化できるかを検討しました。私たちは、Open edX がスケールするにつれて直面する課題と、リアルタイムのパフォーマンス監視や自動エラー追跡などの AppSignal の機能が DevOps チームに不可欠なツールをどのように提供するかを確認しました。私たちのウォークスルーでは、AppSignal と Open edX の初期セットアップと統合について説明し、この強力な可観測性フレームワークの即時的な利点を強調しました。

この 2 回目の投稿では、AppSignal が提供する高度な監視機能について詳しく説明します。これには、Open edX から AppSignal へのログのストリーミング、Celery によるバックグラウンド ワーカーの監視、Redis クエリの追跡が含まれます。これらの機能をどのように活用して特定の運用上の課題に対処し、さまざまな状況下でも学習プラットフォームがフェールセーフであることを保証する方法を示します。

この記事を読み終えるまでに、Open edX プラットフォームのパフォーマンスと信頼性を維持および向上させるために AppSignal を最大限に活用する方法がわかるでしょう。

AppSignal へのログのストリーミング

AppSignal の最も強力な機能の 1 つは、一元的なログ管理です。

Open edX では通常、サポート チームがサイトの問題を報告し、エンジニアはすぐにサーバーに SSH 接続して、Nginx、Mongo、MySQL、Open edX のアプリケーション ログを確認できます。

サーバーに SSH 接続する必要なくログを保管する一元的な保管場所は、非常に強力な機能です。問題の重大度に基づいて通知を設定することもできます。

次に、Open edX から AppSignal にログをストリーミングする方法を見てみましょう。

ソースを作成する

ロギング セクションで、ソースの管理 をクリックし、HTTP をプラットフォームとして、JSON を使用して新しいソースを作成します。形式。ソースを作成した後、AppSignal はログを POST できるエンドポイントと API KEY を提供します。

ログ送信をより詳細に制御するには、ローカルの Open edX からログを読み取り、前処理して、重要なログを AppSignal に移動する単純な Python スクリプトを作成します。たとえば、エラー ログのみを AppSignal に移動する次のスクリプトを作成しました (情報ログと警告ログはスキップします)。

import requests
import json
from datetime import datetime
import logging

# Setup logging configuration
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# File to keep track of the last processed line
log_pointer_file = '/root/.local/share/tutor/data/lms/logs/processed.log'
log_file = '/root/.local/share/tutor/data/lms/logs/all.log'

# APpSignal API KEY
api_key = "MY-API-KEY"  # Replace with your actual API key
# URL to post the logs
url = f'https://appsignal-endpoint.net/logs?api_key={api_key}'

def read_last_processed():
    try:
        with open(log_pointer_file, 'r') as file:
            content = file.read().strip()
            last_processed = int(content) if content else 0
            logging.info(f"Last processed line number read: {last_processed}")
            return last_processed
    except (FileNotFoundError, ValueError) as e:
        logging.error(f"Could not read from log pointer file: {e}")
        return 0

def update_last_processed(line_number):
    try:
        with open(log_pointer_file, 'w') as file:
            file.write(str(line_number))
            logging.info(f"Updated last processed to line number: {line_number}")
    except Exception as e:
        logging.error(f"Could not update log pointer file: {e}")

def parse_log_line(line):
    if 'ERROR' in line:
        parts = line.split('ERROR', 1)
        timestamp = parts[0].strip()
        message_parts = parts[1].strip().split(' - ', 1)
        message = message_parts[1] if len(message_parts) > 1 else ''
        attributes_part = message_parts[0].strip('[]').split('] [')
        # Flatten attributes into a dictionary with string keys and values
        attributes = {}
        for attr in attributes_part:
            key_value = attr.split(None, 1)
            if len(key_value) == 2:
                key, value = key_value
                key = key.rstrip(']:').replace(' ', '_').replace('.', '_')  # Replace spaces and dots in keys
                if len(key)  last_processed:
                json_data = parse_log_line(line)
                if json_data:
                    response_code = post_logs(json_data)
                    if response_code == 200:
                        update_last_processed(i)
                    else:
                        logging.warning(f"Failed to post log, HTTP status code: {response_code}")

if __name__ == '__main__':
    logging.info("Starting log processing script.")
    process_logs()
    logging.info("Finished log processing.")
ログイン後にコピー
ログイン後にコピー

スクリプトの仕組みは次のとおりです:

  1. ログ ファイル管理: 講師は、すべてのログを /root/.local/share/tutor/data/lms/logs/all.log ファイルに保存します。このファイルには、MySQL、LMS、CMS、Caddy、Celery、およびその他のサービスが含まれています。このスクリプトは、最後に処理された行を追跡するポインター /root/.local/share/tutor/data/lms/logs/processed.log ファイルを使用します。これにより、各ログが 1 回だけ処理されることが保証されます。
  2. エラー フィルタリング: 前述したように、AppSignal にはエラー ログのみが送信されます。
  3. データの解析とフォーマット: 各エラー ログが解析されて、タイムスタンプやエラー メッセージなどの重要な情報が抽出されます。スクリプトは、このデータを送信に適した JSON 構造にフォーマットします。
  4. ログ送信: フォーマットされたログ データは、HTTP POST リクエストを使用して AppSignal に送信されます。

重要: 個人を特定できる情報をエンドポイントに送信しないようにしてください。

次に、このスクリプトを実行すると、エラー ログが AppSignal に移動されます:

Advanced Open edX Monitoring with AppSignal for Python

エラーなどの特定のイベントが発生したらすぐに通知する新しいトリガーを作成することもできます。

Advanced Open edX Monitoring with AppSignal for Python

AppSignal を使用して Celery と Redis を監視する

Celery (分散タスク キュー) は Open edX の重要なコンポーネントであり、グレーディング、証明書の生成、一括メールの送信などのバックグラウンド タスクの管理を担当します。 Redis は多くの場合、Celery のブローカーとして機能し、タスク キューを管理します。どちらのシステムも非同期処理には不可欠であり、使用率が高い場合にはボトルネックになる可能性があります。 AppSignal を使用してこれらのサービスを監視すると、タスクの実行とキューの状態に関する貴重な洞察が得られ、潜在的な問題に事前に対処するのに役立ちます。 Celery と Redis を監視する方法を見てみましょう。

まず、必要なパッケージをインストールします。 .local/share/tutor/config.yml ファイルの OPENEDX_EXTRA_PIP_REQUIREMENTS 変数に以下を追加します:

import requests
import json
from datetime import datetime
import logging

# Setup logging configuration
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# File to keep track of the last processed line
log_pointer_file = '/root/.local/share/tutor/data/lms/logs/processed.log'
log_file = '/root/.local/share/tutor/data/lms/logs/all.log'

# APpSignal API KEY
api_key = "MY-API-KEY"  # Replace with your actual API key
# URL to post the logs
url = f'https://appsignal-endpoint.net/logs?api_key={api_key}'

def read_last_processed():
    try:
        with open(log_pointer_file, 'r') as file:
            content = file.read().strip()
            last_processed = int(content) if content else 0
            logging.info(f"Last processed line number read: {last_processed}")
            return last_processed
    except (FileNotFoundError, ValueError) as e:
        logging.error(f"Could not read from log pointer file: {e}")
        return 0

def update_last_processed(line_number):
    try:
        with open(log_pointer_file, 'w') as file:
            file.write(str(line_number))
            logging.info(f"Updated last processed to line number: {line_number}")
    except Exception as e:
        logging.error(f"Could not update log pointer file: {e}")

def parse_log_line(line):
    if 'ERROR' in line:
        parts = line.split('ERROR', 1)
        timestamp = parts[0].strip()
        message_parts = parts[1].strip().split(' - ', 1)
        message = message_parts[1] if len(message_parts) > 1 else ''
        attributes_part = message_parts[0].strip('[]').split('] [')
        # Flatten attributes into a dictionary with string keys and values
        attributes = {}
        for attr in attributes_part:
            key_value = attr.split(None, 1)
            if len(key_value) == 2:
                key, value = key_value
                key = key.rstrip(']:').replace(' ', '_').replace('.', '_')  # Replace spaces and dots in keys
                if len(key)  last_processed:
                json_data = parse_log_line(line)
                if json_data:
                    response_code = post_logs(json_data)
                    if response_code == 200:
                        update_last_processed(i)
                    else:
                        logging.warning(f"Failed to post log, HTTP status code: {response_code}")

if __name__ == '__main__':
    logging.info("Starting log processing script.")
    process_logs()
    logging.info("Finished log processing.")
ログイン後にコピー
ログイン後にコピー

次のようになります:

- opentelemetry-instrumentation-celery==0.45b0
- opentelemetry-instrumentation-redis==0.45b0
ログイン後にコピー

ご覧のとおり、Celery と Redis 用の opentelemetry パッケージをインストールしています。

これで、ワーカー_プロセス_init を使用して Celery を計測し、そのメトリクスを AppSignal に報告できるようになりました。

Advanced Open edX Monitoring with AppSignal for Python

AppSignal のダッシュボードに戻ると、パフォーマンス セクションに 背景 が名前空間として表示される Celery レポートと Redis レポートが表示されます。

Advanced Open edX Monitoring with AppSignal for Python

Redis クエリの場合は、遅いクエリ:

をクリックします。

Advanced Open edX Monitoring with AppSignal for Python

実践的なモニタリング: AppSignal による Open edX の強化

このセクションでは、このシリーズの第 1 部で概説した最初の問題を再検討し、実用的な AppSignal 監視ソリューションを適用して、Open edX プラットフォームの堅牢性と信頼性を確保します。内訳は次のとおりです。

サイトのパフォーマンスの向上

サイト全体のパフォーマンスを評価することから始めましょう。 パフォーマンス セクションの 問題リスト で、アクセスしたすべての URL の主要な指標を確認できます。

  • 応答時間: リクエストの処理と応答にかかる時間を測定することで、ユーザー エクスペリエンスを直接反映します。これに影響を与える要因には、データベース クエリやミドルウェア操作が含まれます。
  • スループット: 指定された時間枠内に処理されたリクエストの数を示します。
  • 平均応答時間: 特定のエンドポイントに対するすべてのリクエストの平均応答時間を提供します。平均応答時間が 1 秒を超える場合は潜在的な懸念があり、最適化が必要な領域が浮き彫りになります。
  • 90 パーセンタイル応答時間: たとえば、GET store/ の 90 パーセンタイル応答時間が 7 ミリ秒である場合、リクエストの 90% が 7 ミリ秒以下で完了することを示します。

次に、平均値に基づいてすべてのアクションを順序付けしましょう。 1 秒を超える項目は危険信号とみなされます:

Advanced Open edX Monitoring with AppSignal for Python
Advanced Open edX Monitoring with AppSignal for Python

ご覧のとおり、Celery は生徒の試行を再スコアしてリセットするタスク、LMS はコース コンテンツを表示するリクエスト、および一部の API には 1 秒以上かかっています。また、これは 1 人のアクティブ ユーザーのみを対象としていることに注意してください。同時ユーザーが増えると、この応答時間は長くなります。最初の解決策は、サーバーにリソース (CPU とメモリ) を追加し、別のパフォーマンス テストを実行することです。

平均応答時間が 1 秒を超えるアクションを特定したら、次のようなパフォーマンスの最適化戦略を検討します。

  • JavaScript の実行を最小限に抑える
  • 静的コンテンツに CDN を使用する
  • キャッシュ技術を実装します。

サーバーリソースの監視

前回の記事では、異常検出とホスト監視について説明しました。次の項目のトリガーを追加しましょう:

  • CPU 使用率
  • ディスク使用量
  • メモリ使用量
  • ネットワークトラフィック
  • エラー率

カスタムメトリクス

私たちのプラットフォームにとって非常に重要な 2 つの指標は、アクティブ ユーザーと登録者数です。 AppSignal を使用してこれらの指標を測定する方法を見てみましょう。

まず、increment_counter を common/djangoapps/student/views/management.py と opensx/core/djangoapps/user_authn/views/login.py に追加して、新しいイベントが発生したときにログインと登録の数を追跡して増分します。

Advanced Open edX Monitoring with AppSignal for Python

Advanced Open edX Monitoring with AppSignal for Python

次に、Open edX にログインしてコースに登録しましょう。次に、AppSignal のダッシュボードに進みましょう。 ダッシュボードの追加をクリックし、次にダッシュボードの作成をクリックし、名前と説明を入力します。

グラフの追加 をクリックし、タイトルとして アクティブ ユーザー を入力し、メトリックの追加 を選択して、login_count:

を使用します。

Advanced Open edX Monitoring with AppSignal for Python

ダッシュボードは次のようになります:

Advanced Open edX Monitoring with AppSignal for Python

同じ手順に従って、enrollment_count メトリクスを使用して登録のグラフを追加できます。

一貫したスタイルを確保する

サイトのスタイルの一貫性を保つために、static/tailwind/css/lms-main-v1.css に新しい稼働時間チェックを追加して、URL が壊れたときに通知を受け取りましょう:

Advanced Open edX Monitoring with AppSignal for Python

Advanced Open edX Monitoring with AppSignal for Python

電子メールの配信とエラー処理

ダッシュボードの エラー セクションでは、すべてのエラーを表示し、通知を設定し、ユーザーへの悪影響を防ぐためにできるだけ早く修正に取り組むことができます。

グレーディングのためのバックグラウンド ジョブの効率化

この記事の Celery と Redis を監視する セクションでは、AppSignal を使用して Celery と Redis を計測する方法について説明しました。同じ手順に従って AppSignal を有効にして、採点されたタスクを表示できるようにしましょう。 lms/djangoapps/grades/tasks.py ファイルに次の行を追加します:

Advanced Open edX Monitoring with AppSignal for Python

パフォーマンス -> の下に評価する項目がいくつか表示されます。 問題リスト.

AppSignal for Python による高度な Open edX モニタリング

ご覧のとおり、recalculate_subsection_grade_v3 (メインの採点 Celery タスク) には 212 ミリ秒かかります。再グレードの場合、lms.djangoapps.instructor_task.tasks.reset_problem_attempts および lms.djangoapps.instructor_task.tasks.rescore_problem には 1.77 秒かかります。

まとめ

この 2 部構成のシリーズでは、AppSignal を Open edX と統合して、監視機能を強化しました。私たちは基本的なことから始め、エラー追跡やパフォーマンス監視など、AppSignal の基本的な機能をセットアップして理解しました。

この記事では、さまざまな Open edX サービスから AppSignal にログを効率的にストリーミングし、すべての関連情報が一元化され、すぐにアクセスできるようにする方法に取り組みました。また、Celery と Redis によって処理される重要な非同期タスクも監視しました。

最後に、サイトの応答の遅さ、登録者数が多い期間のリソースのボトルネック、スタイルの崩れなどの予期せぬ問題など、現実世界のいくつかの課題に対処しました。

ここまでで、AppSignal を活用して Open edX プラットフォームのパフォーマンスと信頼性を監視するだけでなく大幅に改善する方法を包括的に理解できたはずです。

Open edX についてご質問がある場合、またはさらにサポートが必要な場合は、お気軽に cubite.io にアクセスするか、amir@cubite.io まで直接ご連絡ください。

追伸Python の投稿を報道後すぐに読みたい場合は、Python Wizardry ニュースレターを購読して、投稿を 1 つも見逃さないようにしてください。

以上がAppSignal for Python による高度な Open edX モニタリングの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート