首頁 > 後端開發 > Python教學 > 使用 AppSignal for Python 進行進階 Open edX 監控

使用 AppSignal for Python 進行進階 Open edX 監控

Susan Sarandon
發布: 2024-11-29 19:54:12
原創
892 人瀏覽過

在本系列的第一部分中,我們探討了 AppSignal 如何顯著增強 Open edX 平台的穩健性。我們看到了 Open edX 在擴充時面臨的挑戰,以及 AppSignal 的功能(包括即時效能監控和自動錯誤追蹤)如何為 DevOps 團隊提供重要工具。我們的演練涵蓋了 AppSignal 與 Open edX 的初始設定和集成,強調了這個強大的可觀察性框架的直接好處。

在第二篇文章中,我們將深入探討 AppSignal 提供的進階監控功能。這包括將日誌從 Open edX 串流傳輸到 AppSignal、使用 Celery 監控後台工作人員以及追蹤 Redis 查詢。我們將示範如何利用這些功能來解決特定的操作挑戰,確保我們的學習平台在不同情況下保持故障安全。

讀完本文後,您將了解如何充分利用 AppSignal 來維護和提高 Open edX 平台的效能和可靠性。

將日誌串流傳輸到 AppSignal

AppSignal 最強大的功能之一是集中式日誌管理。

在 Open edX 中,支援團隊通常會報告網站問題,工程師可以立即透過 SSH 連接到伺服器來檢查 Nginx、Mongo、MySQL 和 Open edX 應用程式日誌。

無需透過 SSH 連接到伺服器即可保存日誌的集中儲存位置是一項非常強大的功能。我們也可以根據問題的嚴重性設定通知。

現在讓我們看看如何將日誌從 Open edX 串流到 AppSignal。

建立來源

日誌記錄部分下,點選管理來源並建立新來源,使用HTTP作為平台,JSON作為格式。建立來源後,AppSignal 提供一個端點和 API KEY,我們可以POST我們的日誌到。

為了更好地控制日誌傳輸,我們可以編寫一個簡單的 Python 腳本,從本機 Open edX 讀取日誌,對其進行預處理,然後將重要的日誌移至 AppSignal。例如,我編寫了以下腳本,僅將錯誤日誌移至 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. 日誌檔案管理:Tutor 將所有日誌保存在 /root/.local/share/tutor/data/lms/logs/all.log 檔案中。該檔案包含MySQL、LMS、CMS、Caddy、Celery 和其他服務。此腳本使用指標 /root/.local/share/tutor/data/lms/logs/processed.log 檔案來追蹤最後處理的行。這確保每個日誌僅處理一次。
  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 套件。

現在,我們可以使用worker_process_init來偵測Celery,以將其指標報告給AppSignal。

Advanced Open edX Monitoring with AppSignal for Python

回到 AppSignal 中的儀表板,我們應該在 效能 部分看到 Celery 和 Redis 報告,其中 background 作為命名空間。

Advanced Open edX Monitoring with AppSignal for Python

對於Redis查詢,您可以點選慢速查詢

Advanced Open edX Monitoring with AppSignal for Python

實用監控:使用 AppSignal 增強 Open edX

在本節中,我們將重新審視本系列第一部分中概述的初始問題,並應用實用的 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 秒。另外,我們應該注意,這僅適用於一名活躍用戶。如果我們有更多的並髮用戶,回應時間就會增加。我們的第一個解決方案是為伺服器添加更多資源(CPU 和記憶體)並進行另一次效能測試。

辨識出平均反應時間超過 1 秒的操作後,考慮效能最佳化策略,例如:

  • 最小化 JavaScript 執行
  • 將 CDN 用於靜態內容
  • 實作快取技術。

伺服器資源監控

我們在上一篇文章中討論了異常偵測和主機監控。讓我們為以下項目新增觸發器:

  • CPU 使用率
  • 磁碟使用情況
  • 記憶體使用量
  • 網路流量
  • 錯誤率

自訂指標

我們平台的兩個非常重要的指標是我們的活躍用戶數量和註冊人數。讓我們看看如何使用 AppSignal 來衡量這些指標。

首先,將increment_counter加入common/djangoapps/student/views/management.py和openedx/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 秒。

總結

在這個由兩部分組成的系列中,我們將 AppSignal 與 Open edX 整合以增強其監控功能。我們從基礎知識開始 - 設定和了解 AppSignal 的基本功能,包括錯誤追蹤和效能監控。

在本文中,我們解決瞭如何有效地將日誌從各種 Open edX 服務串流傳輸到 AppSignal,確保所有相關資訊集中且易於存取。我們也監控了 Celery 和 Redis 處理的關鍵非同步任務。

最後,我們解決了一些現實世界的挑戰,例如網站響應緩慢、註冊量高期間的資源瓶頸,以及樣式損壞等意外問題。

現在,您應該全面了解如何利用 AppSignal 來監控並顯著提高 Open edX 平台的效能和可靠性。

如果您對 Open edX 有任何疑問或需要進一步協助,請隨時造訪 cubite.io 或直接透過 amir@cubite.io 與我聯繫。

P.S.如果您想在 Python 文章發布後立即閱讀,請訂閱我們的 Python Wizardry 時事通訊,不錯過任何一篇文章!

以上是使用 AppSignal for Python 進行進階 Open edX 監控的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板