דוגמה לאינסטרומנטציה של Python

במסמך הזה מוסבר איך להטמיע באפליקציית Python איסוף של נתוני מעקב ומדדים באמצעות OpenTelemetry SDK ו-OpenTelemetry Collector. בנוסף, מוסבר בו איך לכתוב יומנים מובנים בפורמט JSON לפלט רגיל. כדי להתנסות בהטמעה, מורידים ומריצים את האפליקציה לדוגמה. האפליקציה הזו משתמשת ב-Flask, מסגרת האינטרנט, ומפיקה נתוני יומן, מדדים ונתוני מעקב.

כשמשתמשים ב-OpenTelemetry Collector, מוסיפים אינסטרומנטציה לאפליקציה באמצעות ה-SDK וה-OTLP in-process exporter של ה-SDK. הכלי הזה לא תלוי בספק. אתם גם פורסים OpenTelemetry Collector שמקבל טלמטריה מהכלי לייצוא נתונים בתהליך, ואז מייצא את הטלמטריה הזו לפרויקט Google Cloud . מידע נוסף על קולקטורים זמין במאמר בנושא Google-Built OpenTelemetry Collector.

מומלץ להשתמש ב-OpenTelemetry collector כדי לייצא את נתוני הטלמטריה אם הסביבה שלכם תומכת בשימוש ב-collector. בסביבות מסוימות, צריך להשתמש בכלי לייצוא שפועל בתהליך ושולח נתונים ישירות לGoogle Cloud פרויקט. מידע על הטמעה בתהליך זמין במאמר מעבר מ-Trace exporter לנקודת הקצה OTLP.

למידע נוסף על מכשור, אפשר לעיין במסמכים הבאים:

מידע על הטמעה ידנית והטמעה ללא קוד

בשפה הזו, OpenTelemetry מגדיר הוספת מכשור ללא קוד כשיטה לאיסוף נתוני טלמטריה מספריות וממסגרות בלי לבצע שינויים בקוד. עם זאת, יש לכם אפשרות להתקין מודולים ולהגדיר משתני סביבה.

במסמך הזה לא מתוארת הטמעה ללא קוד. מידע על הנושא הזה זמין במאמר Python zero-code instrumentation.

מידע כללי זמין במאמר בנושא OpenTelemetry Instrumentation for Python.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. התקינו את ה-CLI של Google Cloud.

  3. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  4. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  5. יוצרים או בוחרים Google Cloud פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Google Cloud שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  6. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  7. מפעילים את ממשקי ה-API של Cloud Logging,‏ Cloud Monitoring,‏ Cloud Trace וטלמטריה:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, צריך את תפקיד ה-IAM 'אדמין של Service Usage' (roles/serviceusage.serviceUsageAdmin), שכולל את ההרשאה serviceusage.services.enable. איך מקצים תפקידים

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com telemetry.googleapis.com
  8. התקינו את ה-CLI של Google Cloud.

  9. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  10. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  11. יוצרים או בוחרים Google Cloud פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Google Cloud שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  12. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  13. מפעילים את ממשקי ה-API של Cloud Logging,‏ Cloud Monitoring,‏ Cloud Trace וטלמטריה:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, צריך את תפקיד ה-IAM 'אדמין של Service Usage' (roles/serviceusage.serviceUsageAdmin), שכולל את ההרשאה serviceusage.services.enable. איך מקצים תפקידים

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com telemetry.googleapis.com
  14. כדי לקבל את ההרשאות שדרושות לאפליקציית הדוגמה כדי לכתוב נתונים של יומנים, מדדים ומעקב, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

    ההרשאות האלה מספיקות אם מריצים את הדוגמה ב-Cloud Shell, במשאבים או בסביבת פיתוח מקומית. Google Cloud

    כדי לקבל את ההרשאות שדרושות להצגת נתוני היומן, המדדים והמעקב, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

    להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

    יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.

בצעו אינסטרומנטציה באפליקציה כדי לאסוף נתוני מעקב, מדדים ויומנים

כדי להטמיע באפליקציה איסוף של נתוני מעקב ומדדים, וכדי לכתוב JSON מובנה לפלט רגיל, פועלים לפי השלבים הבאים, כפי שמתואר בקטעים הבאים של המסמך הזה:

  1. הגדרה של OpenTelemetry
  2. הגדרת רישום ביומן במבנה

הגדרת OpenTelemetry

אפליקציית הדוגמה הזו מוגדרת לשימוש ב-OpenTelemetry Python SDK כדי לייצא עקבות ומדדים באמצעות פרוטוקול OTLP. כברירת מחדל, OpenTelemetry Python SDK משתמש בפורמט W3C Trace Context כדי להעביר את הקשר של המעקב, וכך מוודא שלטווחים יש קשר הורה-צאצא נכון בתוך מעקב.

בדוגמת הקוד הבאה מוצג מודול Python להגדרת OpenTelemetry. כדי לראות את הדוגמה המלאה, בסרגל הכלים של הדוגמה, לוחצים על הלוגו של GitHub.

def setup_opentelemetry() -> None:
    resource = Resource.create(
        attributes={
            # Use the PID as the service.instance.id to avoid duplicate timeseries
            # from different Gunicorn worker processes.
            SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
        }
    )
    # Set up OpenTelemetry Python SDK
    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(tracer_provider)

    logger_provider = LoggerProvider(resource=resource)
    logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
    logs.set_logger_provider(logger_provider)

    reader = PeriodicExportingMetricReader(OTLPMetricExporter())
    meter_provider = MeterProvider(metric_readers=[reader], resource=resource)
    metrics.set_meter_provider(meter_provider)

אפליקציית Flask מסתמכת על Gunicorn כדי לטפל בבקשות HTTP בהתאם להמלצות במדריך Deploying to Production של Flask. ‫Gunicorn מפעיל כמה עותקים של האפליקציה בתהליכי עבודה עצמאיים כדי להגדיל את קצב העברת הנתונים. כדי לוודא שהמדדים מתהליכי העבודה לא יתנגשו זה בזה, מומלץ שכל תהליך עבודה יגדיר ערך ייחודי למאפיין המשאב service.instance.id. אחת הדרכים לעשות זאת היא להוסיף את מזהה התהליך ל-service.instance.id. מידע נוסף זמין במאמר בנושא התנגשויות בסדרות עיתיות.

מידע נוסף ואפשרויות הגדרה זמינים במאמר OpenTelemetry Python instrumentation.

הגדרת רישום ביומן במבנה

כדי לכתוב יומנים מובְנים שמקושרים למעקב, צריך להגדיר את האפליקציה כך שהיא תוציא יומנים בפורמט JSON לפלט רגיל עם מפתחות שמכילים מידע על מעקב. בדוגמת הקוד הבאה אפשר לראות איך מגדירים את ספריית logging הרגילה כדי להפיק יומנים מובְנים בפורמט JSON באמצעות ספריית python-json-logger, ואיך משתמשים בחבילת opentelemetry-instrumentation-logging כדי לכלול פרטי מעקב.

class JsonFormatter(jsonlogger.JsonFormatter):
    def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None):
        # Format the timestamp as RFC 3339 with microsecond precision
        isoformat = datetime.fromtimestamp(record.created).isoformat()
        return f"{isoformat}Z"


def setup_structured_logging() -> None:
    LoggingInstrumentor().instrument()

    log_handler = logging.StreamHandler()
    formatter = JsonFormatter(
        "%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
        rename_fields={
            "levelname": "severity",
            "asctime": "timestamp",
            "otelTraceID": "logging.googleapis.com/trace",
            "otelSpanID": "logging.googleapis.com/spanId",
            "otelTraceSampled": "logging.googleapis.com/trace_sampled",
        },
    )
    log_handler.setFormatter(formatter)
    logging.basicConfig(
        level=logging.INFO,
        handlers=[log_handler],
    )

ההגדרה הקודמת מחלצת מידע על הטווח הפעיל מהודעת היומן, ואז מוסיפה את המידע הזה כמאפיינים ליומן המובנה ב-JSON. אחר כך אפשר להשתמש במאפיינים האלה כדי ליצור קורלציה בין יומן לבין מעקב:

  • logging.googleapis.com/trace: שם המשאב של ה-trace שמשויך לרשומה ביומן.
  • logging.googleapis.com/spanId: מזהה הטווח עם העקבות שמשויך לרשומה ביומן.
  • logging.googleapis.com/trace_sampled: הערך בשדה הזה חייב להיות true או false.

מידע נוסף על השדות האלה זמין במאמר בנושא LogEntry.

הפעלת אפליקציה לדוגמה שהוגדרה לאיסוף טלמטריה

האינסטרומנטציה באפליקציית הדוגמה משתמשת בפורמטים ניטרליים לספקים, כמו JSON לנתוני יומן ו-OTLP לנתוני מדדים ולנתוני מעקב. אפליקציית הדוגמה משתמשת גם ב-Flask כדי להציג בקשות HTTP, ובספרייה requests כדי ליצור בקשות HTTP. ‫OpenTelemetry Collector שולח נתוני יומן ומדדים לפרויקט באמצעות כלי ייצוא של Google. הוא שולח את נתוני המעקב לפרויקט שלכם באמצעות Telemetry API, שמשתמש ב-OTLP.

כדי ליצור מדדים ועקבות עבור לקוח ושרת HTTP, אפליקציית הדוגמה מתקינה את ספריות המדידה opentelemetry-instrumentation-flask ו-opentelemetry-instrumentation-requests:

logger = logging.getLogger(__name__)

# Initialize OpenTelemetry Python SDK and structured logging
setup_opentelemetry()
setup_structured_logging()

app = Flask(__name__)

# Add instrumentation
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()

לאפליקציה יש שתי נקודות קצה:

  • נקודת הקצה /multi מטופלת על ידי הפונקציה multi. מחולל העומסים באפליקציה שולח בקשות לנקודת הקצה /multi. כשנקודת הקצה הזו מקבלת בקשה, היא שולחת שלוש עד שבע בקשות לנקודת הקצה /single בשרת המקומי.

    @app.route("/multi")
    def multi():
        """Handle an http request by making 3-7 http requests to the /single endpoint."""
        sub_requests = randint(3, 7)
        logger.info("handle /multi request", extra={"subRequests": sub_requests})
        for _ in range(sub_requests):
            requests.get(url_for("single", _external=True))
        return "ok"
    
    
  • נקודת הקצה /single מטופלת על ידי הפונקציה single. כשנקודת הקצה הזו מקבלת בקשה, היא נכנסת למצב שינה למשך השהיה קצרה ואז מגיבה במחרוזת.

    @app.route("/single")
    def single():
        """Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
        duration = uniform(0.1, 0.2)
        logger.info("handle /single request", extra={"duration": duration})
        time.sleep(duration)
        return f"slept {duration} seconds"
    
    

הורדה ופריסה של האפליקציה

כדי להריץ את הדוגמה:

  1. במסוף Google Cloud , מפעילים את Cloud Shell.

    הפעלת Cloud Shell

    בחלק התחתון של Google Cloud המסוף יתחיל סשן של Cloud Shell ותופיע הודעה של שורת הפקודה. Cloud Shell היא סביבת מעטפת שבה ה-CLI של Google Cloud מותקן ומוגדרים ערכים לפרויקט הקיים. הסשן יופעל תוך כמה שניות.

  2. משכפלים את המאגר:

    git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-python
    
  3. עוברים לספריית הדוגמאות:

    cd opentelemetry-operations-python/samples/instrumentation-quickstart
    
  4. מפתחים ומריצים את הדוגמה:

    docker compose up --abort-on-container-exit
    

    אם אתם לא מריצים את האפליקציה ב-Cloud Shell, אתם צריכים להריץ אותה עם משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS שמצביע על קובץ פרטי הכניסה. ‫Application Default Credentials‏ (ADC) מספק קובץ פרטי כניסה בנתיב $HOME/.config/gcloud/application_default_credentials.json.

    # Set environment variables
    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
    export USERID="$(id -u)"
    
    # Run
    docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
    

הצגת המדדים

האינסטרומנטציה של OpenTelemetry באפליקציית הדוגמה יוצרת מדדים של Prometheus שאפשר לראות באמצעות Metrics Explorer:

  • Prometheus/http_server_duration_milliseconds/histogram מתעד את משך הזמן של בקשות לשרת ומאחסן את התוצאות בהיסטוגרמה.

  • Prometheus/http_client_duration_milliseconds/histogram מתעד את משך הזמן של בקשות הלקוח ומאחסן את התוצאות בהיסטוגרמה.

כדי לראות את המדדים שנוצרו על ידי האפליקציה לדוגמה:
  1. נכנסים לדף  Metrics explorer במסוף Google Cloud :

    כניסה אל Metrics Explorer

    אם משתמשים בסרגל החיפוש כדי למצוא את הדף הזה, בוחרים בתוצאה שבה הכותרת המשנית היא Monitoring.

  2. בסרגל הכלים של מסוף Google Cloud , בוחרים את Google Cloud הפרויקט. בהגדרות של מרכז האפליקציות, בוחרים את הפרויקט המארח של מרכז האפליקציות או את פרויקט הניהול של התיקייה לניהול אפליקציות.
  3. ברכיב Metric, מרחיבים את התפריט Select a metric, כותבים http_server בשורת הסינון ומשתמשים בתפריטי המשנה כדי לבחור סוג ספציפי של משאב ומדד:
    1. בתפריט Active resources בוחרים באפשרות Prometheus Target.
    2. בתפריט Active metric categories בוחרים באפשרות Http.
    3. בתפריט Active metrics בוחרים מדד.
    4. לוחצים על אישור.
  4. כדי להוסיף מסננים שמסירים סדרות זמן מתוצאות השאילתה, משתמשים ברכיב Filter.

  5. מגדירים את אופן התצוגה של הנתונים.

    כשמדובר במדדים מצטברים, הכלי 'Metrics Explorer' מבצע נורמליזציה אוטומטית של הנתונים שנמדדו לפי תקופת ההתאמה, וכתוצאה מכך מוצג בתרשים קצב. מידע נוסף זמין במאמר סוגים, סוגים והמרות.

    כשמודדים ערכים מסוג integer או double, כמו שני המדדים counter, הכלי Metrics Explorer מסכם באופן אוטומטי את כל סדרות הזמנים. כדי לראות את הנתונים של נתיבי ה-HTTP‏ /multi ו-/single, מגדירים את התפריט הראשון של הרשומה Aggregation לערך None.

    מידע נוסף על הגדרת תרשים זמין במאמר איך בוחרים מדדים כשמשתמשים ב-Metrics Explorer.

הצגת העקבות

יכול להיות שיעברו כמה דקות עד שנתוני המעקב יהיו זמינים. לדוגמה, כשנתוני מעקב מתקבלים בפרויקט, יכול להיות ש-Google Cloud Observability יצטרך ליצור מסד נתונים כדי לאחסן את הנתונים האלה. יצירת מסד הנתונים יכולה להימשך כמה דקות, ובמהלך התקופה הזו לא ניתן לראות נתוני מעקב.

כדי להציג את נתוני העקבות:

  1. נכנסים לדף Trace explorer במסוף Google Cloud :

    כניסה אל Trace explorer

    אפשר גם להשתמש בסרגל החיפוש כדי למצוא את הדף הזה.

  2. בקטע הטבלה בדף, בוחרים שורה עם שם הטווח /multi.
  3. בתרשים גאנט בחלונית Trace details, בוחרים בטווח שנקרא /multi.

    תיפתח חלונית עם מידע על בקשת ה-HTTP. הפרטים האלה כוללים את השיטה, קוד הסטטוס, מספר הבייטים וסוכן המשתמש של המתקשר.

  4. כדי לראות את היומנים שמשויכים למעקב הזה, בוחרים בכרטיסייה יומנים ואירועים.

    בכרטיסייה מוצגים יומנים בודדים. כדי לראות את הפרטים של הרשומה ביומן, מרחיבים את הרשומה. אפשר גם ללחוץ על הצגת יומנים כדי לראות את היומן באמצעות Logs Explorer.

מידע נוסף על השימוש בכלי Cloud Trace Explorer זמין במאמר חיפוש עקבות ועיון בהם.

הצגת רישומי היומן

בכלי Logs Explorer אפשר לבדוק את היומנים, וגם לראות את העקבות המשויכים, אם הם קיימים.

  1. במסוף Google Cloud , נכנסים לדף Logs Explorer:

    כניסה אל Logs Explorer

    אם משתמשים בסרגל החיפוש כדי למצוא את הדף הזה, בוחרים בתוצאה שכותרת המשנה שלה היא Logging.

  2. מאתרים יומן עם התיאור של handle /multi request.

    כדי לראות את פרטי היומן, מרחיבים את הרשומה ביומן.

  3. לוחצים על Traces (עקבות) ברשומה ביומן עם ההודעה handle /multi request (טיפול בבקשה מרובה), ואז בוחרים באפשרות View trace details (הצגת פרטי העקבות).

    נפתחת חלונית Trace details ומוצג בה ה-Trace שנבחר.

    יכול להיות שנתוני היומן יהיו זמינים כמה דקות לפני שנתוני המעקב יהיו זמינים. אם נתקלתם בשגיאה כשניסיתם להציג נתוני מעקב, בין אם חיפשתם מעקב לפי מזהה או ביצעתם את השלבים במשימה הזו, המתינו דקה או שתיים ונסו שוב לבצע את הפעולה.

מידע נוסף על השימוש ב-Logs Explorer מופיע במאמר הצגת יומנים באמצעות Logs Explorer.

המאמרים הבאים