יצירת כללי מדיניות להתראות באמצעות API

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

במסמך מתוארים הנושאים הבאים:

  • איך מדיניות ההתראות מיוצגת ב-Monitoring API.
  • סוגי התנאים ש-Monitoring API מספק עבור מדיניות התראות.
  • איך יוצרים מדיניות התראות באמצעות Google Cloud CLI או ספריות לקוח.

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

המבנה של מדיניות התראות

המבנה AlertPolicy מגדיר את הרכיבים של מדיניות התראות. כשיוצרים מדיניות, מציינים ערכים בשדות הבאים של AlertPolicy:

  • displayName: תווית תיאורית של המדיניות.
  • documentation: מומלץ להשתמש בשדה הזה כדי לספק מידע שיעזור לצוותים שמגיבים לאירועים. מידע נוסף זמין במאמר הוספת הערות להתראות עם תיעוד שהוגדר על ידי המשתמש.
  • userLabels: תוויות שהוגדרו על ידי המשתמש ומצורפות למדיניות. התוויות האלה מוצגות בכללי מדיניות התראות, באירועים ובהתראות. מידע על שימוש בתוויות עם התראות זמין במאמר הוספת הערות לאירועים באמצעות תוויות.

  • conditions[]: מערך של מבני Condition.

  • combiner: אופרטור לוגי שקובע איך לטפל בכמה תנאים.

  • notificationChannels[]: מערך של שמות משאבים, שכל אחד מהם מזהה NotificationChannel.

  • alertStrategy: מציין את הפרטים הבאים:

    • כמה זמן עובר עד שהכלי 'מעקב' סוגר אירועים כשנתונים מפסיקים להגיע.
    • במדיניות התראות שמבוססת על מדדים, האם מערכת Monitoring שולחת התראה כשאירוע נסגר.
    • במדיניות התראות שמבוססת על מדדים, האם מופעלות התראות חוזרות והמרווח בין ההתראות האלה. מידע נוסף זמין במאמר בנושא הגדרה של התראות חוזרות למדיניות התראות שמבוססת על מדדים.

אפשר גם לציין את השדה severity כשמשתמשים ב-Cloud Monitoring API ובמסוף Google Cloud . בשדה הזה אפשר להגדיר את רמת החומרה של האירועים. אם לא מציינים חומרה, Cloud Monitoring מגדיר את החומרה של מדיניות ההתראות ל-No Severity.

יש שדות נוספים שאפשר להשתמש בהם, בהתאם לתנאים שיוצרים.

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

כשיוצרים או משנים את מדיניות ההתראות, מערכת Monitoring מגדירה גם שדות אחרים, כולל השדה name. הערך בשדה name הוא שם המשאב של מדיניות ההתראות, שמזהה את המדיניות. שם המשאב הוא בפורמט הבא:

projects/PROJECT_ID/alertPolicies/POLICY_ID

בביטוי הקודם:

  • PROJECT_ID: מזהה הפרויקט. בהגדרות של מרכז האפליקציות, בוחרים את פרויקט המארח או את פרויקט הניהול של מרכז האפליקציות.
  • POLICY_ID: המזהה של מדיניות ההתראות

סוגי התנאים ב-API

‫Cloud Monitoring API תומך במגוון סוגי תנאים במבנה Condition. יש כמה סוגים של תנאים לכללי מדיניות של התראות שמבוססים על מדדים, וסוג אחד של תנאים לכללי מדיניות של התראות שמבוססים על יומנים. בקטעים הבאים מתוארים סוגי התנאים הזמינים.

תנאים להגדרת מדיניות התראות שמבוססת על מדדים

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

תנאים להערכת מדדים שמבוססים על סינון

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

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

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

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

תנאים להערכת מדדים שמבוססים על PromQL

התנאי PrometheusQueryLanguageCondition משתמש בשאילתות של שפת השאילתות של Prometheus‏ (PromQL) כדי לבחור נתונים של סדרות זמן ולבצע בהם מניפולציות לצורך מעקב. התנאי יכול לחשב יחס בין מדדים, להעריך השוואות בין מדדים ועוד.

אם משתמשים בתנאי PrometheusQueryLanguageCondition, הוא חייב להיות התנאי היחיד במדיניות ההתראות. מידע נוסף זמין במאמר בנושא מדיניות התראות עם PromQL.

תנאים להצגת התראות על יחסים

אפשר ליצור מדיניות התראות על סף מדד כדי לעקוב אחרי היחס בין שני מדדים. אפשר ליצור את כללי המדיניות האלה באמצעות סוג התנאי MetricThreshold או PrometheusQueryLanguageCondition. אפשר גם להשתמש ב-PromQL ישירות במסוף Google Cloud . אי אפשר ליצור או לנהל תנאים שמבוססים על יחסים באמצעות הממשק הגרפי ליצירת תנאי סף.

מומלץ להשתמש ב-PromQL כדי ליצור מדיניות התראות מבוססת-יחס. עם PromQL אפשר ליצור שאילתות חזקות וגמישות יותר מאלה שאפשר ליצור באמצעות סוג התנאי MetricTheshold ומסנני Monitoring. לדוגמה, באמצעות תנאי PrometheusQueryLanguageCondition, אפשר לחשב את היחס בין מדד מסוג gauge לבין מדד מסוג delta.

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

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

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

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

ההבדל במספר הערכים במרווחי ההתאמה המקבילים יכול להוביל לערכי יחס לא הגיוניים של error/total, כמו 1/0 או 2/1.

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

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

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

תנאי למדיניות התראות מבוססת-יומן

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

אל תנסו להשתמש בסוג התנאי LogMatch בשילוב עם מדדים מבוססי-יומן. מדיניות התראות שעוקבת אחרי מדדים מבוססי-יומנים היא מדיניות מבוססת-מדדים. מידע נוסף על בחירה בין מדיניות התראות שמנטרת מדדים מבוססי-יומן או רשומות ביומן זמין במאמר מעקב אחרי היומנים.

מדיניות ההתראות שמשמשת בדוגמאות במסמך ניהול מדיניות התראות באמצעות API היא מדיניות התראות מבוססת-מדדים, אבל העקרונות זהים גם למדיניות התראות מבוססת-יומנים. מידע ספציפי על מדיניות התראות מבוססת-יומן זמין במאמר יצירת מדיניות התראות מבוססת-יומן באמצעות Monitoring API במסמכי התיעוד של Cloud Logging.

איך משייכים מדיניות התראות לאפליקציה ב-App Hub

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

כדי לשייך מדיניות התראות לאפליקציה ב-App Hub, צריך לצרף למדיניות תוויות עם המפתחות הבאים:

  • apphub_application_location
  • apphub_application_id
  • apphub_service_id או apphub_workload_id
לדוגמה, הקטע userLabels בייצוג ה-JSON של מדיניות התראות יכול להיראות כך:

  "userLabels": {
    "apphub_service_id": "my-service-id",
    "apphub_application_location": "my-app-location",
    "apphub_application_id": "my-app"
  },

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

לפני שכותבים קוד שמשתמש ב-API, צריך:

  • חשוב להכיר את המושגים הכלליים ואת המינוח שמשמשים במדיניות בנושא התראות. מידע נוסף זמין במאמר סקירה כללית על התראות.
  • מוודאים ש-Cloud Monitoring API מופעל. מידע נוסף זמין במאמר בנושא הפעלת ה-API.
  • אם אתם מתכננים להשתמש בספריות לקוח, אתם צריכים להתקין את הספריות בשפות שבהן אתם רוצים להשתמש. פרטים נוספים זמינים במאמר ספריות לקוח. תמיכה ב-API להגדרת התראות זמינה רק בשפות C#,‏ Go,‏ Java,‏ Node.js ו-Python.
  • אם אתם מתכננים להשתמש ב-Google Cloud CLI, אתם צריכים להתקין אותו. עם זאת, אם אתם משתמשים ב-Cloud Shell, ‏ Google Cloud CLI כבר מותקן.

    בנוסף, מופיעות כאן דוגמאות לשימוש בממשק gcloud. שימו לב: בכל הדוגמאות של gcloud מניחים שהפרויקט הנוכחי כבר הוגדר כיעד (gcloud config set project [PROJECT_ID]), ולכן ההפעלות לא כוללות את הדגל --project המפורש. המזהה של הפרויקט הנוכחי בדוגמאות הוא a-gcp-project. בהגדרות של מרכז האפליקציות, בוחרים את פרויקט המארח או את פרויקט הניהול של מרכז האפליקציות.

יצירת מדיניות התראות

כדי ליצור מדיניות התראות בפרויקט, משתמשים ב-method ‏alertPolicies.create. מידע על הפעלת השיטה הזו, על הפרמטרים שלה ועל נתוני התגובה מופיע בדף העזר alertPolicies.create.

אפשר ליצור מדיניות מקובצי JSON או YAML. ‫Google Cloud CLI מקבל את הקבצים האלה כארגומנטים, ואפשר לקרוא קובצי JSON באופן פרוגרמטי, להמיר אותם לאובייקטים של AlertPolicy וליצור מהם כללי מדיניות באמצעות השיטה alertPolicies.create. אם יש לכם קובץ תצורה של Prometheus בפורמט JSON או YAML עם כלל התראות, ה-CLI של gcloud יכול להעביר אותו למדיניות התראות של Cloud Monitoring עם תנאי PromQL. מידע נוסף זמין במאמר בנושא העברה של כללי התראות ושל נמענים מ-Prometheus.

כל מדיניות התראה שייכת לפרויקט היקף של היקף מדדים. כל פרויקט יכול להכיל עד 2,000 כללי מדיניות. כשמבצעים קריאות ל-API, צריך לספק 'מזהה פרויקט'. הערך שצריך להזין הוא המזהה של פרויקט ההיקף של היקף המדדים. בדוגמאות האלה, המזהה של פרויקט ההיקף של היקף המדדים הוא a-gcp-project.

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

gcloud

כדי ליצור מדיניות התראות בפרויקט, משתמשים בפקודה gcloud monitoring policies create. בדוגמה הבאה נוצרת מדיניות התראות ב-a-gcp-project מהקובץ rising-cpu-usage.json:

gcloud monitoring policies create --policy-from-file="rising-cpu-usage.json"

אם הפקודה מסתיימת ללא שגיאות, היא מחזירה את השם של המדיניות החדשה, לדוגמה:

Created alert policy [projects/a-gcp-project/alertPolicies/12669073143329903307].

הקובץ rising-cpu-usage.json מכיל את ה-JSON של מדיניות עם שם התצוגה 'שיעור שינוי גבוה של CPU'. פרטים על המדיניות הזו מופיעים במאמר מדיניות שיעור השינוי.

מידע נוסף מופיע במפרט של השיטה ב-gcloud monitoring policies create.

C#

כדי לבצע אימות ב-Monitoring, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

static void RestorePolicies(string projectId, string filePath)
{
    var policyClient = AlertPolicyServiceClient.Create();
    var channelClient = NotificationChannelServiceClient.Create();
    List<Exception> exceptions = new List<Exception>();
    var backup = JsonConvert.DeserializeObject<BackupRecord>(
        File.ReadAllText(filePath), new ProtoMessageConverter());
    var projectName = new ProjectName(projectId);
    bool isSameProject = projectId == backup.ProjectId;
    // When a channel is recreated, rather than updated, it will get
    // a new name.  We have to update the AlertPolicy with the new
    // name.  Track the names in this map.
    var channelNameMap = new Dictionary<string, string>();
    foreach (NotificationChannel channel in backup.Channels)
    {
    }
    foreach (AlertPolicy policy in backup.Policies)
    {
        string policyName = policy.Name;
        // These two fields cannot be set directly, so clear them.
        policy.CreationRecord = null;
        policy.MutationRecord = null;
        // Update channel names if the channel was recreated with
        // another name.
        for (int i = 0; i < policy.NotificationChannels.Count; ++i)
        {
            if (channelNameMap.ContainsKey(policy.NotificationChannels[i]))
            {
                policy.NotificationChannels[i] =
                    channelNameMap[policy.NotificationChannels[i]];
            }
        }
        try
        {
            Console.WriteLine("Updating policy.\n{0}",
                policy.DisplayName);
            bool updated = false;
            if (isSameProject)
                try
                {
                    policyClient.UpdateAlertPolicy(null, policy);
                    updated = true;
                }
                catch (Grpc.Core.RpcException e)
                when (e.Status.StatusCode == StatusCode.NotFound)
                { }
            if (!updated)
            {
                // The policy no longer exists.  Recreate it.
                policy.Name = null;
                foreach (var condition in policy.Conditions)
                {
                    condition.Name = null;
                }
                policyClient.CreateAlertPolicy(projectName, policy);
            }
            Console.WriteLine("Restored {0}.", policyName);
        }
        catch (Exception e)
        {
            // If one failed, continue trying to update the others.
            exceptions.Add(e);
        }
    }
    if (exceptions.Count > 0)
    {
        throw new AggregateException(exceptions);
    }
}

Go

כדי לבצע אימות ב-Monitoring, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.


// restorePolicies updates the project with the alert policies and
// notification channels in r.
func restorePolicies(w io.Writer, projectID string, r io.Reader) error {
	b := backup{}
	if err := json.NewDecoder(r).Decode(&b); err != nil {
		return err
	}
	sameProject := projectID == b.ProjectID

	ctx := context.Background()

	alertClient, err := monitoring.NewAlertPolicyClient(ctx)
	if err != nil {
		return err
	}
	defer alertClient.Close()
	channelClient, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}
	defer channelClient.Close()

	// When a channel is recreated, rather than updated, it will get
	// a new name.  We have to update the AlertPolicy with the new
	// name.  channelNames keeps track of the new names.
	channelNames := make(map[string]string)
	for _, c := range b.Channels {
		fmt.Fprintf(w, "Updating channel %q\n", c.GetDisplayName())
		c.VerificationStatus = monitoringpb.NotificationChannel_VERIFICATION_STATUS_UNSPECIFIED
		updated := false
		if sameProject {
			req := &monitoringpb.UpdateNotificationChannelRequest{
				NotificationChannel: c.NotificationChannel,
			}
			_, err := channelClient.UpdateNotificationChannel(ctx, req)
			if err == nil {
				updated = true
			}
		}
		if !updated {
			req := &monitoringpb.CreateNotificationChannelRequest{
				Name:                "projects/" + projectID,
				NotificationChannel: c.NotificationChannel,
			}
			oldName := c.GetName()
			c.Name = ""
			newC, err := channelClient.CreateNotificationChannel(ctx, req)
			if err != nil {
				return err
			}
			channelNames[oldName] = newC.GetName()
		}
	}

	for _, policy := range b.AlertPolicies {
		fmt.Fprintf(w, "Updating alert %q\n", policy.GetDisplayName())
		policy.CreationRecord = nil
		policy.MutationRecord = nil
		for i, aChannel := range policy.GetNotificationChannels() {
			if c, ok := channelNames[aChannel]; ok {
				policy.NotificationChannels[i] = c
			}
		}
		updated := false
		if sameProject {
			req := &monitoringpb.UpdateAlertPolicyRequest{
				AlertPolicy: policy.AlertPolicy,
			}
			_, err := alertClient.UpdateAlertPolicy(ctx, req)
			if err == nil {
				updated = true
			}
		}
		if !updated {
			req := &monitoringpb.CreateAlertPolicyRequest{
				Name:        "projects/" + projectID,
				AlertPolicy: policy.AlertPolicy,
			}
			if _, err = alertClient.CreateAlertPolicy(ctx, req); err != nil {
				log.Fatal(err)
			}
		}
	}
	fmt.Fprintf(w, "Successfully restored alerts.")
	return nil
}

Java

כדי לבצע אימות ב-Monitoring, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

private static void restoreRevisedPolicies(
    String projectId, boolean isSameProject, List<AlertPolicy> policies) throws IOException {
  try (AlertPolicyServiceClient client = AlertPolicyServiceClient.create()) {
    for (AlertPolicy policy : policies) {
      if (!isSameProject) {
        policy = client.createAlertPolicy(ProjectName.of(projectId), policy);
      } else {
        try {
          client.updateAlertPolicy(null, policy);
        } catch (Exception e) {
          policy =
              client.createAlertPolicy(
                  ProjectName.of(projectId), policy.toBuilder().clearName().build());
        }
      }
      System.out.println(String.format("Restored %s", policy.getName()));
    }
  }
}

Node.js

כדי לבצע אימות ב-Monitoring, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

const fs = require('fs');

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.AlertPolicyServiceClient();

async function restorePolicies() {
  // Note: The policies are restored one at a time due to limitations in
  // the API. Otherwise, you may receive a 'service unavailable'  error
  // while trying to create multiple alerts simultaneously.

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const projectId = 'YOUR_PROJECT_ID';

  console.log('Loading policies from ./policies_backup.json');
  const fileContent = fs.readFileSync('./policies_backup.json', 'utf-8');
  const policies = JSON.parse(fileContent);

  for (const index in policies) {
    // Restore each policy one at a time
    let policy = policies[index];
    if (await doesAlertPolicyExist(policy.name)) {
      policy = await client.updateAlertPolicy({
        alertPolicy: policy,
      });
    } else {
      // Clear away output-only fields
      delete policy.name;
      delete policy.creationRecord;
      delete policy.mutationRecord;
      policy.conditions.forEach(condition => delete condition.name);

      policy = await client.createAlertPolicy({
        name: client.projectPath(projectId),
        alertPolicy: policy,
      });
    }

    console.log(`Restored ${policy[0].name}.`);
  }
  async function doesAlertPolicyExist(name) {
    try {
      const [policy] = await client.getAlertPolicy({
        name,
      });
      return policy ? true : false;
    } catch (err) {
      if (err && err.code === 5) {
        // Error code 5 comes from the google.rpc.code.NOT_FOUND protobuf
        return false;
      }
      throw err;
    }
  }
}
restorePolicies();

PHP

כדי לבצע אימות ב-Monitoring, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

use Google\Cloud\Monitoring\V3\AlertPolicy;
use Google\Cloud\Monitoring\V3\AlertPolicy\Condition;
use Google\Cloud\Monitoring\V3\AlertPolicy\Condition\MetricThreshold;
use Google\Cloud\Monitoring\V3\AlertPolicy\ConditionCombinerType;
use Google\Cloud\Monitoring\V3\Client\AlertPolicyServiceClient;
use Google\Cloud\Monitoring\V3\ComparisonType;
use Google\Cloud\Monitoring\V3\CreateAlertPolicyRequest;
use Google\Protobuf\Duration;

/**
 * @param string $projectId Your project ID
 */
function alert_create_policy($projectId)
{
    $alertClient = new AlertPolicyServiceClient([
        'projectId' => $projectId,
    ]);
    $projectName = 'projects/' . $projectId;

    $policy = new AlertPolicy();
    $policy->setDisplayName('Test Alert Policy');
    $policy->setCombiner(ConditionCombinerType::PBOR);
    /** @see https://cloud.google.com/monitoring/api/resources for a list of resource.type */
    /** @see https://cloud.google.com/monitoring/api/metrics_gcp for a list of metric.type */
    $policy->setConditions([new Condition([
        'display_name' => 'condition-1',
        'condition_threshold' => new MetricThreshold([
            'filter' => 'resource.type = "gce_instance" AND metric.type = "compute.googleapis.com/instance/cpu/utilization"',
            'duration' => new Duration(['seconds' => '60']),
            'comparison' => ComparisonType::COMPARISON_LT,
        ])
    ])]);
    $createAlertPolicyRequest = (new CreateAlertPolicyRequest())
        ->setName($projectName)
        ->setAlertPolicy($policy);

    $policy = $alertClient->createAlertPolicy($createAlertPolicyRequest);
    printf('Created alert policy %s' . PHP_EOL, $policy->getName());
}

Python

כדי לבצע אימות ב-Monitoring, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

def restore(project_name, backup_filename):
    """Restore alert policies in a project.

    Arguments:
        project_name (str): The Google Cloud Project to use. The project name
            must be in the format - 'projects/<PROJECT_NAME>'.
        backup_filename (str): Name of the file (along with its path) from
            which the alert policies will be restored.
    """
    print(
        "Loading alert policies and notification channels from {}.".format(
            backup_filename
        )
    )
    record = json.load(open(backup_filename, "rt"))
    is_same_project = project_name == record["project_name"]
    # Convert dicts to AlertPolicies.
    policies_json = [json.dumps(policy) for policy in record["policies"]]
    policies = [
        monitoring_v3.AlertPolicy.from_json(policy_json)
        for policy_json in policies_json
    ]
    # Convert dicts to NotificationChannels
    channels_json = [json.dumps(channel) for channel in record["channels"]]
    channels = [
        monitoring_v3.NotificationChannel.from_json(channel_json)
        for channel_json in channels_json
    ]

    # Restore the channels.
    channel_client = monitoring_v3.NotificationChannelServiceClient()
    channel_name_map = {}

    for channel in channels:
        updated = False
        print("Updating channel", channel.display_name)
        # This field is immutable and it is illegal to specify a
        # non-default value (UNVERIFIED or VERIFIED) in the
        # Create() or Update() operations.
        channel.verification_status = (
            monitoring_v3.NotificationChannel.VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED
        )

        if is_same_project:
            try:
                channel_client.update_notification_channel(notification_channel=channel)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The channel was deleted.  Create it below.

        if not updated:
            # The channel no longer exists.  Recreate it.
            old_name = channel.name
            del channel.name
            new_channel = channel_client.create_notification_channel(
                name=project_name, notification_channel=channel
            )
            channel_name_map[old_name] = new_channel.name

    # Restore the alerts
    alert_client = monitoring_v3.AlertPolicyServiceClient()

    for policy in policies:
        print("Updating policy", policy.display_name)
        # These two fields cannot be set directly, so clear them.
        del policy.creation_record
        del policy.mutation_record

        # Update old channel names with new channel names.
        for i, channel in enumerate(policy.notification_channels):
            new_channel = channel_name_map.get(channel)
            if new_channel:
                policy.notification_channels[i] = new_channel

        updated = False

        if is_same_project:
            try:
                alert_client.update_alert_policy(alert_policy=policy)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The policy was deleted.  Create it below.
            except google.api_core.exceptions.InvalidArgument:
                # Annoying that API throws InvalidArgument when the policy
                # does not exist.  Seems like it should throw NotFound.
                pass  # The policy was deleted.  Create it below.

        if not updated:
            # The policy no longer exists.  Recreate it.
            old_name = policy.name
            del policy.name
            for condition in policy.conditions:
                del condition.name
            policy = alert_client.create_alert_policy(
                name=project_name, alert_policy=policy
            )
        print("Updated", policy.name)

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

הגדרה של התראות חוזרות למדיניות התראות שמבוססת על מדדים

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

כדי להגדיר התראות חוזרות, מוסיפים להגדרות של מדיניות ההתראות אובייקט AlertStrategy שמכיל לפחות אובייקט NotificationChannelStrategy אחד. לאובייקט NotificationChannelStrategy יש שני שדות:

  • renotifyInterval: המרווח בשניות בין התראות חוזרות.

    אם משנים את הערך של השדה renotifyInterval כשאירוע של מדיניות ההתראות נפתח, קורה הדבר הבא:

    • מדיניות ההתראות שולחת הודעה נוספת על האירוע.
    • מדיניות ההתראות מפעילה מחדש את תקופת ההמתנה.
  • notificationChannelNames: מערך של שמות משאבים של ערוצי התראות, שהם מחרוזות בפורמט projects/PROJECT_ID/notificationChannels/CHANNEL_ID, כאשר CHANNEL_ID הוא ערך מספרי. במאמר רשימת ערוצי התראות בפרויקט מוסבר איך מאחזרים את מזהה הערוץ.

לדוגמה, בדוגמת ה-JSON הבאה מוצגת אסטרטגיית התראה שהוגדרה לשלוח התראות חוזרות כל 1,800 שניות (30 דקות) לערוץ התראות אחד:

  "alertStrategy": {
    "notificationChannelStrategy": [
      {
        "notificationChannelNames": [
          "projects/PROJECT_ID/notificationChannels/CHANNEL_ID"
        ],
        "renotifyInterval": "1800s"
      }
    ]
  }

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

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