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

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

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

במסמך הזה לא מתוארת הטמעה ללא קוד. מידע נוסף על הנושא הזה זמין במאמר בנושא הוספת כלי מעקב ב-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 פרויקט.

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

    • 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 באפליקציה
  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.

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

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

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

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

בדוגמת הקוד הבאה אפשר לראות Dockerfile עם העברת הדגל --require:

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

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

כדי לכלול את פרטי העקבות כחלק מהיומנים בפורמט JSON שנכתבים לפלט רגיל, צריך להגדיר את האפליקציה כך שתפיק יומנים מובְנים בפורמט 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: שם המשאב של ה-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,
});

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

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

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

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

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

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

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

  • נקודת הקצה /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';
    });
  • נקודת הקצה /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. במסוף Google Cloud , מפעילים את Cloud Shell.

    הפעלת Cloud Shell

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

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

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

    cd opentelemetry-operations-js/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.

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