使用 AppSignal for Python 進行進階 Open edX 監控
在本系列的第一部分中,我們探討了 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.")
腳本的工作原理如下:
- 日誌檔案管理:Tutor 將所有日誌保存在 /root/.local/share/tutor/data/lms/logs/all.log 檔案中。該檔案包含MySQL、LMS、CMS、Caddy、Celery 和其他服務。此腳本使用指標 /root/.local/share/tutor/data/lms/logs/processed.log 檔案來追蹤最後處理的行。這確保每個日誌僅處理一次。
- 錯誤過濾:如前所述,我們僅將錯誤日誌傳送到 AppSignal。
- 資料解析和格式化:解析每個錯誤日誌以提取關鍵訊息,例如時間戳記和錯誤訊息。該腳本將此資料格式化為適合傳輸的 JSON 結構。
- 日誌傳輸:使用 HTTP POST 要求將格式化的日誌資料傳送到 AppSignal。
重要提示:請確保您沒有向端點發送任何個人識別資訊。
現在運行此腳本,它應該將錯誤日誌移至 AppSignal:
您也可以建立一個新的觸發器,以便在發生錯誤等特定事件時立即通知您:
使用 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。
回到 AppSignal 中的儀表板,我們應該在 效能 部分看到 Celery 和 Redis 報告,其中 background 作為命名空間。
對於Redis查詢,您可以點選慢速查詢:
實用監控:使用 AppSignal 增強 Open edX
在本節中,我們將重新審視本系列第一部分中概述的初始問題,並應用實用的 AppSignal 監控解決方案,以確保我們的 Open edX 平台保持強大且可靠。這是一個細分。
網站效能改進
我們首先評估網站的整體表現。在效能部分的問題清單下,我們可以看到所有訪問過的URL的關鍵指標:
- 回應時間:透過測量處理和回應請求所需的時間來直接反映使用者體驗。影響這一點的因素包括資料庫查詢和中間件操作。
- 吞吐量:表示在給定時間範圍內處理的請求數量。
- 平均回應時間:提供對特定端點的所有請求的平均回應時間。任何超過 1 秒的平均反應時間都是一個潛在問題,並突出顯示需要優化的區域。
- 90% 回應時間:例如,GET store/ 的 90% 回應時間為 7 毫秒,表示 90% 的請求在 7 毫秒或更短時間內完成。
現在讓我們根據平均值對所有操作進行排序。任何超過 1 秒的項目都應被視為危險信號:
如我們所見,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中,以在有新事件時追蹤和增加登入和註冊的數量。
現在讓我們登入 Open edX 並註冊課程。接下來,讓我們前往 AppSignal 中的儀表板。點選新增儀表板,然後建立儀表板,並為其指定名稱和描述。
點選新增圖表,輸入活躍使用者作為標題,選擇新增指標並使用login_count:
您的儀表板應如下所示:
您可以按照相同的步驟使用 enrollment_count 指標新增註冊圖表。
確保風格一致
為了確保我們網站的樣式保持一致,讓我們為 static/tailwind/css/lms-main-v1.css 添加新的正常運行時間檢查,並在 URL 損壞時收到通知:
電子郵件傳送和錯誤處理
在儀表板的錯誤部分,我們可以查看所有錯誤,為其設定通知,並儘快修復以防止用戶受到負面影響。
評分的後台工作效率
在本文的監控 Celery 和 Redis 部分中,我們了解如何使用 AppSignal 來偵測 Celery 和 Redis。讓我們按照相同的步驟啟用 AppSignal,以便我們可以看到分級任務。在 lms/djangoapps/grades/tasks.py 檔案中,新增以下行:
我們現在應該在表現 -> 下看到一些需要評分的項目。 問題列表。
如您所見,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中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

每天學習Python兩個小時是否足夠?這取決於你的目標和學習方法。 1)制定清晰的學習計劃,2)選擇合適的學習資源和方法,3)動手實踐和復習鞏固,可以在這段時間內逐步掌握Python的基本知識和高級功能。
