דוגמה למכשיר מדידה של Node.js

אתם יכולים להוסיף לאפליקציית JavaScript ב-Node.js כלים לאיסוף נתוני מעקב ומדדים באמצעות ה-SDK של OpenTelemetry ואוסף OpenTelemetry, ולכתוב יומני JSON מובְנים ומתואמים לפלט סטנדרטי (stdout). כדי להתנסות בכלים האלה, אתם יכולים להוריד ולהריץ את האפליקציה לדוגמה Fastify, שיוצרת נתוני יומנים, מדדים ומעקב ומייצאת אותם לפרויקט ב-Google Cloud .

מידע על גישת המדידה

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

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

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

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

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

במסמך הזה לא מתואר שימוש בכלים ללא קוד. למידע נוסף על הנושא הזה, ראו אינסטרומנטציה ללא קוד ב-JavaScript.

למידע כללי, קראו את המאמר OpenTelemetry Instrumentation for Node.

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

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

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

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

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

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

    • בחירת פרויקט: כדי לבחור פרויקט לא נדרש תפקיד IAM ספציפי – אתם יכולים לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד "יצירת פרויקטים" (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 ו-Telemetry, אם הם עדיין לא מופעלים:

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

    כדי להפעיל ממשקי API, צריך את ההרשאה serviceusage.services.enable. אם אתם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד "בעלים" (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד "אדמין בממשק 'שימוש בשירות'" (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    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 .

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

    • בחירת פרויקט: כדי לבחור פרויקט לא נדרש תפקיד IAM ספציפי – אתם יכולים לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד "יצירת פרויקטים" (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 ו-Telemetry, אם הם עדיין לא מופעלים:

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

    כדי להפעיל ממשקי API, צריך את ההרשאה serviceusage.services.enable. אם אתם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד "בעלים" (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד "אדמין בממשק 'שימוש בשירות'" (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

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

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

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

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

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

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

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

  1. הגדרת OpenTelemetry
  2. הגדרת האפליקציה לטעינה מראש של הגדרות OpenTelemetry
  3. הגדרת רישום ביומן של נתונים מובְנים
  4. כתיבת יומנים מובְנים

הגדרת OpenTelemetry

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

דוגמת הקוד הבאה ממחישה מודול JavaScript להגדרת OpenTelemetry.

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


diag.setLogger(
  new DiagConsoleLogger(),
  opentelemetry.core.diagLogLevelFromString(
    opentelemetry.core.getStringFromEnv('OTEL_LOG_LEVEL'),
  ),
);

const sdk = new opentelemetry.NodeSDK({
  instrumentations: getNodeAutoInstrumentations({
    // Disable noisy instrumentations
    '@opentelemetry/instrumentation-fs': {enabled: false},
  }),
  resourceDetectors: getResourceDetectorsFromEnv(),
  metricReader: getMetricReader(),
});

try {
  sdk.start();
  diag.info('OpenTelemetry automatic instrumentation started successfully');
} catch (error) {
  diag.error(
    'Error initializing OpenTelemetry SDK. Your application is not instrumented and will not produce telemetry',
    error,
  );
}

// Gracefully shut down the SDK to flush telemetry when the program exits
process.on('SIGTERM', () => {
  sdk
    .shutdown()
    .then(() => diag.debug('OpenTelemetry SDK terminated'))
    .catch(error => diag.error('Error terminating OpenTelemetry SDK', error));
});

דוגמת הקוד הקודמת מגדירה את OpenTelemetry לייצוא מדדים באמצעות פרוטוקול OTLP, ומשתמשת בחבילה @opentelemetry/auto-instrumentations-node כדי להגדיר את כל כלי המדידה הזמינים של Node.js.

כדי לוודא שכל נתוני הטלמטריה בהמתנה נמחקים ושהחיבורים נסגרים בצורה תקינה לפני שהאפליקציה נסגרת, ה-handler של SIGTERM קורא ל-shutdown.

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

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

כדי להגדיר את האפליקציה לכתוב יומנים מובְנים ולאסוף נתוני מעקב ומדדים באמצעות OpenTelemetry, צריך לעדכן את הקריאה לאפליקציה כדי לטעון מראש את מודול האינסטרומנטציה באמצעות הדגל --require של Node.js. הדגל --require מבטיח ש-OpenTelemetry יופעל לפני שהאפליקציה תתחיל לפעול. מידע נוסף זמין במאמר תחילת העבודה עם OpenTelemetry Node.js.

דוגמת הקוד הבאה ממחישה קובץ Docker שמעביר את הדגל --require:

CMD node --require ./build/src/instrumentation.js build/src/index.js 2>&1 | tee /var/log/app.log

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

כדי לכלול את פרטי המעקב כחלק מהיומנים בפורמט JSON שנכתבים בפלט הסטנדרטי (stdout), צריך להגדיר את האפליקציה כך שתוציא יומנים מובְנים בפורמט JSON.

דוגמת הקוד הבאה ממחישה אובייקט Pino LoggerOptions שמגדיר את האפליקציה להפיק יומנים מובְנים בפורמט JSON:


// Expected attributes that OpenTelemetry adds to correlate logs with spans
interface LogRecord {
  trace_id?: string;
  span_id?: string;
  trace_flags?: string;
  [key: string]: unknown;
}

// https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity
const PinoLevelToSeverityLookup: Record<string, string | undefined> = {
  trace: 'DEBUG',
  debug: 'DEBUG',
  info: 'INFO',
  warn: 'WARNING',
  error: 'ERROR',
  fatal: 'CRITICAL',
};

export const loggerConfig = {
  messageKey: 'message',
  // Same as pino.stdTimeFunctions.isoTime but uses "timestamp" key instead of "time"
  timestamp(): string {
    return `,"timestamp":"${new Date(Date.now()).toISOString()}"`;
  },
  formatters: {
    log(object: LogRecord): Record<string, unknown> {
      // Add trace context attributes following Cloud Logging structured log format described
      // in https://cloud.google.com/logging/docs/structured-logging#special-payload-fields
      const {trace_id, span_id, trace_flags, ...rest} = object;

      return {
        'logging.googleapis.com/trace': trace_id,
        'logging.googleapis.com/spanId': span_id,
        'logging.googleapis.com/trace_sampled': trace_flags
          ? trace_flags === '01'
          : undefined,
        ...rest,
      };
    },
    // See
    // https://getpino.io/#/docs/help?id=mapping-pino-log-levels-to-google-cloud-logging-stackdriver-severity-levels
    level(label: string) {
      return {
        severity:
          PinoLevelToSeverityLookup[label] ?? PinoLevelToSeverityLookup['info'],
      };
    },
  },
} satisfies LoggerOptions;

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

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

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

כדי להשתמש בהגדרות של Pino עם Fastify, מעבירים את אובייקט ההגדרות של ה-logger כשיוצרים את אפליקציית Fastify:

// Create the Fastify app providing the Pino logger config
const fastify = Fastify({
  logger: loggerConfig,
});

כתיבת יומנים מובְנים

כדי לכתוב יומנים מובְנים שמקושרים למעקב, משתמשים בכלי Pino לרישום ביומן שסופק על ידי Fastify. לדוגמה, ההצהרה הבאה מראה איך להפעיל את השיטה Logger.info():

request.log.info({subRequests}, 'handle /multi request');

‫OpenTelemetry מאכלס באופן אוטומטי את רשומות היומן של Pino בהקשר של ה-span של ה-span הפעיל הנוכחי בהקשר של OpenTelemetry. ההקשר של הטווח נכלל ביומני ה-JSON, כמו שמתואר במאמר הגדרת רישום מובנה ביומן.

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

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

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

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

    /**
     * handleMulti handles an http request by making 3-7 http requests to the /single endpoint.
     *
     * OpenTelemetry instrumentation requires no changes here. It will automatically generate a
     * span for the handler body.
     */
    fastify.get('/multi', async request => {
      const subRequests = randInt(3, 8);
      request.log.info({subRequests}, 'handle /multi request');
    
      for (let i = 0; i < subRequests; i++) {
        await axios.get(`http://localhost:${port}/single`);
      }
      return 'ok';
    });
  • נקודת הקצה (endpoint) /single מטופלת על ידי הפונקציה handleSingle. כשהנקודה הזו מקבלת בקשה, היא נכנסת למצב שינה לזמן קצר ואז מגיבה במחרוזת.

    /**
     * handleSingle handles an http request by sleeping for 100-200 ms. It writes the number of
     * milliseconds slept as its response.
     */
    fastify.get('/single', async request => {
      // Sleep between 100-200 milliseconds
      const sleepMillis = randInt(100, 200);
      request.log.info({sleepMillis}, 'Going to sleep');
      await sleep(sleepMillis);
      return `slept ${sleepMillis}\n`;
    });

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

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

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

    הפעלת Cloud Shell

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

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

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

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

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

    אם אתם לא מריצים את האפליקציה ב-Cloud Shell, אתם צריכים להריץ אותה כשמשתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS מצביע על קובץ פרטי הכניסה. Application Default Credentials מספק קובץ של פרטי כניסה ב-$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. במסוף Google Cloud , נכנסים לדף  Metrics explorer:

    כניסה לדף Metrics Explorer

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

  2. בסרגל הכלים של מסוף Google Cloud , בוחרים את הפרויקט ב- Google Cloud . בהגדרות של App Hub, בוחרים את הפרויקט המארח של App Hub או את הפרויקט לניהול של התיקייה לניהול אפליקציות.
  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 מנרמל באופן אוטומטי את הנתונים שנמדדו לפי תקופת ההתאמה, וכתוצאה מכך בתרשים מוצג שיעור. למידע נוסף, ראו סוגים, טיפוסים והמרות.

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

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

הצגת המעקבים

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

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

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

    כניסה לדף Trace Explorer

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

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

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

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

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

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

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

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

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

    נכנסים לדף Logs Explorer.

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

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

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

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

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

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

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

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