使用 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)

使用FiddlerEverywhere进行中间人读取时如何避免被检测到当你使用FiddlerEverywhere...

如何在10小时内教计算机小白编程基础?如果你只有10个小时来教计算机小白一些编程知识,你会选择教些什么�...

攻克Investing.com的反爬虫策略许多人尝试爬取Investing.com(https://cn.investing.com/news/latest-news)的新闻数据时,常常�...

Python3.6环境下加载pickle文件报错:ModuleNotFoundError:Nomodulenamed...

使用Scapy爬虫时管道文件无法写入的原因探讨在学习和使用Scapy爬虫进行数据持久化存储时,可能会遇到管道文�...
