Heim >Backend-Entwicklung >Python-Tutorial >Erweiterte Open edX-Überwachung mit AppSignal für Python

Erweiterte Open edX-Überwachung mit AppSignal für Python

Susan Sarandon
Susan SarandonOriginal
2024-11-29 19:54:12951Durchsuche

Im ersten Teil dieser Serie haben wir untersucht, wie AppSignal die Robustheit von Open edX-Plattformen erheblich verbessern kann. Wir haben gesehen, vor welchen Herausforderungen Open edX bei seiner Skalierung steht und wie die Funktionen von AppSignal – einschließlich Echtzeit-Leistungsüberwachung und automatisierter Fehlerverfolgung – wichtige Tools für DevOps-Teams bereitstellen. Unsere exemplarische Vorgehensweise behandelte die Ersteinrichtung und Integration von AppSignal mit Open edX und verdeutlichte die unmittelbaren Vorteile dieses leistungsstarken Observability-Frameworks.

In diesem zweiten Beitrag werden wir uns eingehender mit den erweiterten Überwachungsfunktionen befassen, die AppSignal bietet. Dazu gehören das Streamen von Protokollen von Open edX an AppSignal, die Überwachung von Hintergrundarbeitern mit Celery und die Verfolgung von Redis-Abfragen. Wir werden zeigen, wie diese Funktionen genutzt werden können, um spezifische betriebliche Herausforderungen zu bewältigen und sicherzustellen, dass unsere Lernplattform unter verschiedenen Umständen ausfallsicher bleibt.

Am Ende dieses Artikels werden Sie wissen, wie Sie AppSignal optimal nutzen können, um die Leistung und Zuverlässigkeit Ihrer Open edX-Plattform aufrechtzuerhalten und zu verbessern.

Streamen von Protokollen an AppSignal

Eine der stärksten Funktionen von AppSignal ist die zentralisierte Protokollverwaltung.

Üblicherweise meldet das Support-Team bei Open edX ein Problem mit der Site, und ein Techniker kann sofort eine SSH-Verbindung zum Server herstellen, um nach Nginx-, Mongo-, MySQL- und Open edX-Anwendungsprotokollen zu suchen.

Ein zentraler Speicherort, der Protokolle speichert, ohne dass Sie eine SSH-Verbindung zum Server herstellen müssen, ist eine wirklich leistungsstarke Funktion. Wir können auch Benachrichtigungen basierend auf der Schwere eines Problems einrichten.

Jetzt wollen wir sehen, wie wir unsere Protokolle von Open edX zu AppSignal streamen können.

Erstellen Sie eine Quelle

Klicken Sie im Abschnitt Protokollierung auf Quellen verwalten und erstellen Sie eine neue Quelle mit HTTP als Plattform und JSON als Plattform das Format. Nach dem Erstellen der Quelle stellt AppSignal einen Endpunkt und einen API-SCHLÜSSEL bereit, an den wir unsere Protokolle POSTEN können.

Um mehr Kontrolle über die Protokollübertragung zu haben, können wir ein einfaches Python-Skript schreiben, das Protokolle aus unserem lokalen Open edX liest, sie vorverarbeitet und die wichtigen Protokolle nach AppSignal verschiebt. Ich habe zum Beispiel das folgende Skript geschrieben, um nur ERROR-Protokolle nach AppSignal zu verschieben (INFO- und WARNING-Protokolle zu überspringen):

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.")

So funktioniert das Skript:

  1. Protokolldateiverwaltung: Tutor speichert alle Protokolle in der Datei /root/.local/share/tutor/data/lms/logs/all.log. Diese Datei enthält MySQL, LMS, CMS, Caddy, Celery und andere Dienste. Das Skript verwendet eine Zeigerdatei /root/.local/share/tutor/data/lms/logs/processed.log, die die zuletzt verarbeitete Zeile verfolgt. Dadurch wird sichergestellt, dass jedes Protokoll nur einmal verarbeitet wird.
  2. Fehlerfilterung: Wie bereits erwähnt, senden wir nur FEHLERprotokolle an AppSignal.
  3. Datenanalyse und -formatierung: Jedes Fehlerprotokoll wird analysiert, um wichtige Informationen wie den Zeitstempel und die Fehlermeldung zu extrahieren. Das Skript formatiert diese Daten in eine für die Übertragung geeignete JSON-Struktur.
  4. Protokollübertragung: Die formatierten Protokolldaten werden mithilfe einer HTTP-POST-Anfrage an AppSignal gesendet.

Wichtig: Bitte stellen Sie sicher, dass Sie keine personenbezogenen Daten an den Endpunkt senden.

Führen Sie nun dieses Skript aus und es sollte FEHLERprotokolle nach AppSignal verschieben:

Advanced Open edX Monitoring with AppSignal for Python

Sie können auch einen neuen Auslöser erstellen, der Sie benachrichtigt, sobald ein bestimmtes Ereignis wie FEHLER eintritt:

Advanced Open edX Monitoring with AppSignal for Python

Überwachen Sie Celery und Redis mit AppSignal

Celery (eine verteilte Aufgabenwarteschlange) ist eine wichtige Komponente von Open edX und verantwortlich für die Verwaltung von Hintergrundaufgaben wie Benotung, Zertifikatserstellung und Massen-E-Mail-Versand. Redis fungiert häufig als Broker für Celery und verwaltet Aufgabenwarteschlangen. Beide Systeme sind für die asynchrone Verarbeitung unerlässlich und können in Zeiten hoher Auslastung zu Engpässen führen. Die Überwachung dieser Dienste mit AppSignal liefert wertvolle Einblicke in die Aufgabenausführung und den Zustand der Warteschlange und hilft Ihnen, potenzielle Probleme präventiv anzugehen. Mal sehen, wie wir Celery und Redis überwachen können.

Installieren Sie zunächst die erforderlichen Pakete. Fügen Sie Folgendes zur Variablen OPENEDX_EXTRA_PIP_REQUIREMENTS in der Datei .local/share/tutor/config.yml hinzu:

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.")

Es sollte wie folgt aussehen:

- opentelemetry-instrumentation-celery==0.45b0
- opentelemetry-instrumentation-redis==0.45b0

Wie Sie sehen können, installieren wir Opentelemetry-Pakete für Celery und Redis.

Jetzt können wir Celery mit worker_process_init instrumentieren, um seine Metriken an AppSignal zu melden.

Advanced Open edX Monitoring with AppSignal for Python

Wenn wir zu unserem Dashboard in AppSignal zurückkehren, sollten wir Celery- und Redis-Berichte im Abschnitt Leistung sehen, mit Hintergrund als Namespace.

Advanced Open edX Monitoring with AppSignal for Python

Für Redis-Abfragen können Sie auf Langsame Abfragen klicken:

Advanced Open edX Monitoring with AppSignal for Python

Praktische Überwachung: Open edX mit AppSignal erweitern

In diesem Abschnitt gehen wir noch einmal auf die anfänglichen Probleme ein, die im ersten Teil dieser Serie beschrieben wurden, und wenden praktische AppSignal-Überwachungslösungen an, um sicherzustellen, dass unsere Open edX-Plattform robust und zuverlässig bleibt. Hier ist eine Aufschlüsselung.

Verbesserung der Website-Leistung

Beginnen wir mit der Bewertung der Gesamtleistung der Website. Im Abschnitt Leistung unter der Problemliste können wir wichtige Kennzahlen für alle besuchten URLs sehen:

  • Reaktionszeit: Spiegelt direkt die Benutzererfahrung wider, indem die Zeit gemessen wird, die für die Bearbeitung und Beantwortung von Anfragen benötigt wird. Zu den Faktoren, die dies beeinflussen, gehören Datenbankabfragen und Middleware-Operationen.
  • Durchsatz: Gibt die Anzahl der Anfragen an, die innerhalb eines bestimmten Zeitraums bearbeitet wurden.
  • Mittlere Antwortzeit: Bietet eine durchschnittliche Antwortzeit für alle Anfragen an einen bestimmten Endpunkt. Jede durchschnittliche Reaktionszeit von mehr als 1 Sekunde stellt ein potenzielles Problem dar und weist auf Bereiche hin, die einer Optimierung bedürfen.
  • 90. Perzentil-Antwortzeit: Eine 90. Perzentil-Antwortzeit von 7 ms für GET store/ deutet beispielsweise darauf hin, dass 90 % der Anfragen in 7 ms oder weniger abgeschlossen werden.

Jetzt ordnen wir alle Aktionen basierend auf dem Mittelwert. Jedes Element, das länger als 1 Sekunde dauert, sollte als Warnsignal betrachtet werden:

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

Wie wir sehen, benötigen Celery-Aufgaben zum erneuten Bewerten und Zurücksetzen von Schülerversuchen, LMS-Anfragen zum Anzeigen von Kursinhalten und einige APIs mehr als 1 Sekunde. Außerdem sollten wir beachten, dass dies nur für einen aktiven Benutzer gilt. Wenn wir mehr gleichzeitige Benutzer haben, erhöht sich diese Reaktionszeit. Unsere erste Lösung besteht darin, dem Server weitere Ressourcen (CPU und Speicher) hinzuzufügen und einen weiteren Leistungstest durchzuführen.

Nachdem Sie Aktionen mit durchschnittlichen Reaktionszeiten von mehr als 1 Sekunde identifiziert haben, überlegen Sie sich Strategien zur Leistungsoptimierung wie:

  • JavaScript-Ausführung minimieren
  • CDNs für statische Inhalte verwenden
  • Implementierung von Caching-Techniken.

Überwachung der Serverressourcen

Wir haben im vorherigen Artikel über Anomalieerkennung und Hostüberwachung gesprochen. Fügen wir Auslöser für die folgenden Elemente hinzu:

  • CPU-Auslastung
  • Festplattennutzung
  • Speichernutzung
  • Netzwerkverkehr
  • Fehlerrate

Benutzerdefinierte Metriken

Zwei wirklich wichtige Kennzahlen für unsere Plattform sind unsere Anzahl aktiver Benutzer und Anmeldungen. Sehen wir uns an, wie wir diese Kennzahlen mit AppSignal messen können.

Fügen Sie zunächst increment_counter zu common/djangoapps/student/views/management.py und openx/core/djangoapps/user_authn/views/login.py hinzu, um die Anzahl der Anmeldungen und Registrierungen zu verfolgen und zu erhöhen, wenn es ein neues Ereignis gibt.

Advanced Open edX Monitoring with AppSignal for Python

Advanced Open edX Monitoring with AppSignal for Python

Jetzt melden wir uns bei Open edX an und melden uns für einen Kurs an. Gehen wir als Nächstes zu unserem Dashboard in AppSignal. Klicken Sie auf Dashboard hinzufügen, dann auf Dashboard erstellen und geben Sie ihm einen Namen und eine Beschreibung.

Klicken Sie auf Grafik hinzufügen, geben Sie als Titel Aktive Benutzer ein, wählen Sie Metrik hinzufügen und verwenden Sie login_count:

Advanced Open edX Monitoring with AppSignal for Python

Ihr Dashboard sollte wie folgt aussehen:

Advanced Open edX Monitoring with AppSignal for Python

Sie können die gleichen Schritte ausführen, um mithilfe einer Enrollment_Count-Metrik ein Diagramm für Registrierungen hinzuzufügen.

Gewährleistung eines einheitlichen Stylings

Um sicherzustellen, dass das Design unserer Website konsistent bleibt, fügen wir eine neue Verfügbarkeitsprüfung für static/tailwind/css/lms-main-v1.css hinzu und werden benachrichtigt, wenn eine URL fehlerhaft ist:

Advanced Open edX Monitoring with AppSignal for Python

Advanced Open edX Monitoring with AppSignal for Python

E-Mail-Zustellung und Fehlerbehandlung

Im Abschnitt Fehler des Dashboards können wir alle Fehler anzeigen, Benachrichtigungen für sie einrichten und so schnell wie möglich an Korrekturen arbeiten, um zu verhindern, dass Benutzer negativ beeinträchtigt werden.

Hintergrundarbeitseffizienz für die Benotung

Im Abschnitt Sellerie und Redis überwachen dieses Artikels haben wir gesehen, wie man Celery und Redis mit AppSignal instrumentiert. Führen Sie die gleichen Schritte aus, um AppSignal zu aktivieren, damit wir benotete Aufgaben sehen können. Fügen Sie in der Datei lms/djangoapps/grades/tasks.py die folgenden Zeilen hinzu:

Advanced Open edX Monitoring with AppSignal for Python

Wir sollten jetzt unter Leistung -> einige zu bewertende Punkte sehen. Problemliste.

Erweiterte Open edX-Überwachung mit AppSignal für Python

Wie Sie sehen können, dauert recalculate_subsection_grade_v3 (unsere Hauptaufgabe zur Bewertung von Sellerie) 212 Millisekunden. Für die Neubewertung benötigen lms.djangoapps.instructor_task.tasks.reset_problem_attempts und lms.djangoapps.instructor_task.tasks.rescore_problem 1,77 Sekunden.

Zusammenfassung

In dieser zweiteiligen Serie haben wir AppSignal mit Open edX integriert, um seine Überwachungsfunktionen zu stärken. Wir begannen mit den Grundlagen – dem Einrichten und Verstehen der grundlegenden Angebote von AppSignal, einschließlich Fehlerverfolgung und Leistungsüberwachung.

In diesem Artikel haben wir uns damit befasst, wie Protokolle von verschiedenen Open edX-Diensten effizient an AppSignal gestreamt werden können, um sicherzustellen, dass alle relevanten Informationen zentralisiert und leicht zugänglich sind. Wir haben auch wichtige asynchrone Aufgaben überwacht, die von Celery und Redis ausgeführt werden.

Schließlich haben wir uns mit einigen realen Herausforderungen befasst, wie z. B. langsamen Reaktionen auf der Website, Ressourcenengpässen während hoher Anmeldezeiten und unerwarteten Problemen wie fehlerhaftem Styling.

Inzwischen sollten Sie ein umfassendes Verständnis dafür haben, wie Sie AppSignal nutzen können, um die Leistung und Zuverlässigkeit Ihrer Open edX-Plattform nicht nur zu überwachen, sondern auch deutlich zu verbessern.

Wenn Sie Fragen zu Open edX haben oder weitere Hilfe benötigen, besuchen Sie cubite.io oder kontaktieren Sie mich direkt unter amir@cubite.io.

P.S. Wenn Sie Python-Beiträge lesen möchten, sobald sie veröffentlicht werden, abonnieren Sie unseren Python Wizardry-Newsletter und verpassen Sie keinen einzigen Beitrag!

Das obige ist der detaillierte Inhalt vonErweiterte Open edX-Überwachung mit AppSignal für Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn