מבוא למדדי Dropwizard

1. הקדמה

מדדים היא ספריית Java המספקת מכשירי מדידה ליישומי Java.

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

2. מודול מדדי הליבה

2.1. תלות Maven

כדי להשתמש ב- מדדי הליבה למודול, יש רק תלות אחת שנדרשת להוסיף ל- pom.xml קוֹבֶץ:

 מדדי הליבה io.dropwizard.metrics 3.1.2 

ותוכלו למצוא את הגרסה האחרונה שלה כאן.

2.2. מטרי רישום

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

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

בואו ניצור מטרי רישום עַכשָׁיו:

MetricRegistry metricRegistry = חדש MetricRegistry ();

ואז נוכל לרשום כמה מדדים בעזרת זה מטרי רישום:

מטר מטר 1 = מטר חדש (); metricRegistry.register ("מטר 1", מטר 1); מד מטר 2 = metricRegistry.meter ("מטר 2"); 

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

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

מחרוזת name1 = MetricRegistry.name (Filter.class, "בקשה", "ספירה"); מחרוזת name2 = MetricRegistry.name ("CustomFilter", "תגובה", "ספירה"); 

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

SharedMetricRegistries.add ("ברירת מחדל", metricRegistry); MetricRegistry retrievedMetricRegistry = SharedMetricRegistries.getOrCreate ("ברירת מחדל"); SharedMetricRegistries.remove ("ברירת מחדל"); 

3. מושגי מדדים

מודול מדדי הליבה מספק מספר סוגי מדדים נפוצים: מטר, מַד, דֶלְפֵּק, היסטוגרמה ו שָׁעוֹן עֶצֶר, ו כַתָב להפקת ערכי מדדים.

3.1. מטר

א מטר מודד ספירת ושיעורי אירועים:

מד מטר = מטר חדש (); initCount ארוך = meter.getCount (); assertThat (initCount, equalTo (0L)); meter.mark (); assertThat (meter.getCount (), equalTo (1L)); מטר.סימן (20); assertThat (meter.getCount (), equalTo (21L)); ממוצע כפול = meter.getMeanRate (); כפול oneMinRate = meter.getOneMinuteRate (); כפול fiveMinRate = meter.getFiveMinuteRate (); כפול fiveteenMinRate = meter.getFifteenMinuteRate (); 

ה getCount () השיטה מחזירה ספירת אירועים, ו סימן() השיטה מוסיפה 1 או n לספירת האירועים. ה מטר האובייקט מספק ארבעה שיעורים המייצגים שיעורים ממוצעים לכלל מטר לכל החיים, לדקה האחרונה, לחמש הדקות האחרונות ולרבע האחרון בהתאמה.

3.2. מַד

מַד הוא ממשק שמשמש פשוט להחזרת ערך מסוים. מודול מדדי הליבה מספק כמה מימושים שלו: RatioGauge, CachedGauge, DerivativeGauge ו JmxAttributeGauge.

RatioGauge הוא מעמד מופשט והוא מודד את היחס בין ערך אחד למשנהו.

בואו נראה איך להשתמש בזה. ראשית, אנו מיישמים כיתה נוכחות RatioGauge:

כיתה ציבורית AttendanceRatioGauge מרחיב את RatioGauge {private int attendanceCount; קורס פרטי intCount; יחס מוגן ב- @Override getRatio () {Return Ratio.of (attendanceCount, courseCount); } // קונסטרוקציות סטנדרטיות} 

ואז אנחנו בודקים את זה:

RatioGauge ratioGauge = חדש נוכחות RatioGauge (15, 20); assertThat (ratioGauge.getValue (), equalTo (0.75)); 

CachedGauge הוא מחלקה מופשטת אחרת שיכולה לשמור את המטמון, ולכן זה די שימושי כאשר הערכים יקרים לחישוב. כדי להשתמש בו, עלינו ליישם כיתה ActiveUsersGauge:

מחלקה ציבורית ActiveUsersGauge מרחיב את CachedGauge {@Override מוגן רשימה loadValue () {להחזיר getActiveUserCount (); } רשימה פרטית getActiveUserCount () {תוצאת רשימה = ArrayList חדש (); result.add (12L); תוצאת החזרה; } // קונסטרוקציות סטנדרטיות}

ואז אנחנו בודקים את זה כדי לראות אם זה עובד כצפוי:

מַד activeUsersGauge = ActiveUsersGauge חדש (15, TimeUnit.MINUTES); רשימה צפויה = ArrayList חדש (); צפוי. להוסיף (12 ליטר); assertThat (activeUsersGauge.getValue (), equalTo (צפוי)); 

קבענו את זמן התפוגה של המטמון ל 15 דקות בעת הפעלת התיקייה ActiveUsersGauge.

DerivativeGauge הוא גם מעמד מופשט והוא מאפשר לך להפיק ערך מאחרים מַד כערכו.

בואו נסתכל על דוגמה:

מחלקה ציבורית ActiveUserCountGauge מרחיב את DerivativeGauge {@Override מוגן טרנספורמציה שלמה (ערך רשימה) {return value.size (); } // קונסטרוקציות סטנדרטיות}

זֶה מַד שואב את ערכו מ- ActiveUsersGauge, לכן אנו מצפים שזה יהיה הערך מגודל רשימת הבסיס:

מַד activeUsersGauge = ActiveUsersGauge חדש (15, TimeUnit.MINUTES); מד activeUserCountGauge = ActiveUserCountGauge חדש (activeUsersGauge); assertThat (activeUserCountGauge.getValue (), equalTo (1)); 

JmxAttributeGauge משמש כשאנחנו צריכים לגשת למדדי ספריות אחרות שנחשפו באמצעות JMX.

3.3. דֶלְפֵּק

ה דֶלְפֵּק משמש להקלטת תוספות וירידות:

מונה נגד = מונה חדש (); initCount ארוך = counter.getCount (); assertThat (initCount, equalTo (0L)); counter.inc (); assertThat (counter.getCount (), equalTo (1L)); counter.inc (11); assertThat (counter.getCount (), equalTo (12L)); counter.dec (); assertThat (counter.getCount (), equalTo (11L)); counter.dec (6); assertThat (counter.getCount (), equalTo (5L));

3.4. היסטוגרמה

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

היסטוגרמה היסטוגרמה = היסטוגרמה חדשה (UniformReservoir חדש ()); היסטוגרמה.עדכון (5); ספירה ארוכה 1 = היסטוגרמה. getCount (); assertThat (count1, equalTo (1L)); תמונת מצב snapshot1 = היסטוגרמה. GetSnapshot (); assertThat (snapshot1.getValues ​​(). אורך, שווה ל- (1)); assertThat (snapshot1.getValues ​​() [0], equalTo (5L)); היסטוגרמה.עדכון (20); ספירה ארוכה = היסטוגרמה. getCount (); assertThat (count2, equalTo (2L)); Snapshot snapshot2 = histogram.getSnapshot (); assertThat (snapshot2.getValues ​​(). אורך, שווה ל (2)); assertThat (snapshot2.getValues ​​() [1], equalTo (20L)); assertThat (snapshot2.getMax (), equalTo (20L)); assertThat (snapshot2.getMean (), equalTo (12.5)); assertEquals (10.6, snapshot2.getStdDev (), 0.1); assertThat (snapshot2.get75thPercentile (), equalTo (20.0)); assertThat (snapshot2.get999thPercentile (), equalTo (20.0)); 

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

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

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

3.5. שָׁעוֹן עֶצֶר

שָׁעוֹן עֶצֶר משמש למעקב אחר משכי העיתוי המרובים המיוצגים על ידי הֶקשֵׁר אובייקטים, והוא גם מספק את הנתונים הסטטיסטיים שלהם:

טיימר טיימר = טיימר חדש (); Timer.Context context1 = timer.time (); TimeUnit.SECONDS.sleep (5); long elapsed1 = context1.stop (); assertEquals (5000000000L, עבר 1, 1000000); assertThat (timer.getCount (), equalTo (1L)); assertEquals (0.2, timer.getMeanRate (), 0.1); Timer.Context context2 = timer.time (); TimeUnit.SECONDS.sleep (2); context2.close (); assertThat (timer.getCount (), equalTo (2L)); assertEquals (0.3, timer.getMeanRate (), 0.1); 

3.6. כַתָב

כאשר אנו צריכים להעביר את המדידות שלנו, נוכל להשתמש בהן כַתָב. זהו ממשק, ומודול ליבת המדדים מספק כמה מימושים שלו, כגון ConsoleReporter, CsvReporter, Slf4jReporter, JmxReporter וכולי.

כאן אנו משתמשים ConsoleReporter לדוגמא:

MetricRegistry metricRegistry = חדש MetricRegistry (); מד מטר = metricRegistry.meter ("מטר"); מטר.סימן (); מטר.סימן (200); היסטוגרמה היסטוגרמה = metricRegistry.histogram ("היסטוגרמה"); היסטוגרמה.עדכון (12); היסטוגרמה.עדכון (17); מונה נגד = metricRegistry.counter ("מונה"); counter.inc (); counter.dec (); כתב ConsoleReporter = ConsoleReporter.forRegistry (metricRegistry) .build (); reporter.start (5, TimeUnit.MICROSECONDS); reporter.report (); 

להלן פלט הדוגמה של ה- ConsoleReporter:

- היסטוגרמות ------------------------------------------------------- ------------------- ספירת היסטוגרמה = 2 דקות = 12 מקסימום = 17 ממוצע = 14.50 stddev = 2.50 חציון = 17.00 75% <= 17.00 95% <= 17.00 98% <= 17.00 99% <= 17.00 99.9% <= 17.00 - מטר ---------------------------------- ------------------------------------ ספירת מטר = 201 קצב ממוצע = 1756.87 אירועים / שנייה דקה אחת קצב = 0.00 אירועים / שנייה 5 דקות = 0.00 אירועים / שנייה 15 דקות = 0.00 אירועים / שנייה 

4. מודול מדדים-בדיקות בריאות

למדדים יש מודול הרחבה מדדי-בריאות לבדיקות בריאות.

4.1. תלות Maven

כדי להשתמש במודול מדדים-בריאות, עלינו להוסיף תלות זו ל- pom.xml קוֹבֶץ:

 io.dropwizard.metrics מדדים-בדיקות בריאות 3.1.2 

ותוכלו למצוא את הגרסה האחרונה שלה כאן.

4.2. נוֹהָג

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

לדוגמא, אנו משתמשים DatabaseHealthCheck ו UserCenterHealthCheck:

Class class DatabaseHealthCheck מרחיב את HealthCheck {@Override מוגן תוצאת בדיקה () זורק חריג {החזר Result.healthy (); }} 
מחלקה ציבורית UserCenterHealthCheck מרחיב HealthCheck {@Override מוגן בדיקת תוצאות () זורקת חריגה {להחזיר Result.healthy (); }} 

ואז, אנחנו צריכים HealthCheckRegistry (שזה בדיוק כמו מטרי רישום), ורשום את DatabaseHealthCheck ו UserCenterHealthCheck עם זה:

HealthCheckRegistry healthCheckRegistry = HealthCheckRegistry חדש (); healthCheckRegistry.register ("db", DatabaseHealthCheck חדש ()); healthCheckRegistry.register ("uc", UserCenterHealthCheck חדש); assertThat (healthCheckRegistry.getNames (). size (), equalTo (2)); 

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

healthCheckRegistry.unregister ("uc"); assertThat (healthCheckRegistry.getNames (). size (), equalTo (1)); 

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

תוצאות מפה = healthCheckRegistry.runHealthChecks (); עבור (Map.Entry entry: results.entrySet ()) {assertThat (entry.getValue (). isHealthy (), equalTo (true)); } 

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

healthCheckRegistry.runHealthCheck ("db"); 

5. מודול מדדים- servlets

מדדים מספקים לנו קומץ servlets שימושיים המאפשרים לנו לגשת לנתונים הקשורים למדדים באמצעות בקשות HTTP.

5.1. תלות Maven

כדי להשתמש במודול metrics-servlets, עלינו להוסיף תלות זו ל- pom.xml קוֹבֶץ:

 io.dropwizard.metrics metrics-servlets 3.1.2 

ותוכלו למצוא את הגרסה האחרונה שלה כאן.

5.2. HealthCheckServlet נוֹהָג

HealthCheckServlet מספק תוצאות בדיקת בריאות. ראשית, עלינו ליצור ServletContextListener שחושף את שלנו HealthCheckRegistry:

מחלקה ציבורית MyHealthCheckServletContextListener מרחיב את HealthCheckServlet.ContextListener {public static HealthCheckRegistry HEALTH_CHECK_REGISTRY = new HealthCheckRegistry (); סטטי {HEALTH_CHECK_REGISTRY.register ("db", DatabaseHealthCheck חדש ()); } @Override מוגן HealthCheckRegistry getHealthCheckRegistry () {return HEALTH_CHECK_REGISTRY; }} 

לאחר מכן, אנו מוסיפים גם המאזין הזה וגם HealthCheckServlet לתוך ה web.xml קוֹבֶץ:

 com.baeldung.metrics.servlets.MyHealthCheckServletContextListener healthCheck com.codahale.metrics.servlets.HealthCheckServlet healthCheck / healthcheck 

כעת אנו יכולים להפעיל את יישום האינטרנט ולשלוח בקשת GET אל "// localhost: 8080 / healthcheck" כדי לקבל תוצאות בדיקת בריאות. התגובה שלה צריכה להיות כזו:

{"db": {"בריא": נכון}}

5.3. ThreadDumpServlet נוֹהָג

ThreadDumpServlet מספק מידע על כל האשכולות החיים ב- JVM, על מדינותיהם, עקבות הערימה שלהם ומצב המנעולים שהם עשויים לחכות להם.

אם אנו רוצים להשתמש בו, עלינו פשוט להוסיף אותם אל ה- web.xml קוֹבֶץ:

 threadDump com.codahale.metrics.servlets.ThreadDumpServlet threadDump / threaddump 

נתוני השלכת חוטים יהיו זמינים בכתובת “// localhost: 8080 / threaddump”.

5.4. PingServlet נוֹהָג

PingServlet ניתן להשתמש בו כדי לבדוק אם היישום פועל. אנו מוסיפים את אלה ל web.xml קוֹבֶץ:

 פינג com.codahale.metrics.servlets.PingServlet פינג / פינג 

ואז שלח בקשת GET אל "// localhost: 8080 / ping". קוד הסטטוס של התגובה הוא 200 ותוכנו "פונג".

5.5. MetricsServlet נוֹהָג

MetricsServlet מספק נתוני מדדים. ראשית, עלינו ליצור ServletContextListener שחושף את שלנו מטרי רישום:

מחלקה ציבורית MyMetricsServletContextListener מרחיב את MetricsServlet.ContextListener {פרטי סטטי MetricRegistry METRIC_REGISTRY = MetricRegistry חדש (); סטטי {Counter counter = METRIC_REGISTRY.counter ("m01-counter"); counter.inc (); היסטוגרמה היסטוגרמה = METRIC_REGISTRY.histogram ("m02-histogram"); היסטוגרמה.עדכון (5); היסטוגרמה.עדכון (20); היסטוגרמה.עדכון (100); } @MetricRegistry מוגן @Override getMetricRegistry () {להחזיר METRIC_REGISTRY; }} 

גם המאזין הזה וגם MetricsServlet צריך להוסיף לתוך web.xml:

 com.codahale.metrics.servlets.MyMetricsServletContextListener metric com.codahale.metrics.servlets.MetricsServlet metrics / metrics 

הדבר ייחשף ביישום האינטרנט שלנו בכתובת “// localhost: 8080 / metrics”. התגובה שלה צריכה להכיל נתוני מדדים שונים:

{"version": "3.0.0", "gauges": {}, "counters": {"m01-counter": {"count": 1}}, "histograms": {"m02-histogram": { "count": 3, "max": 100, "mean": 41.66666666666666, "min": 5, "p50": 20, "p75": 100, "p95": 100, "p98": 100, "p99 ": 100," p999 ": 100," stddev ": 41.69998667732268}}," meters ": {}," timers ": {}} 

5.6. AdminServlet נוֹהָג

AdminServlet אגרגטים HealthCheckServlet, ThreadDumpServlet, MetricsServlet, ו PingServlet.

בואו נוסיף את אלה ל web.xml:

 מנהל com.codahale.metrics.servlets.AdminServlet admin / admin / * 

כעת ניתן לגשת אליו בכתובת “// localhost: 8080 / admin”. נקבל דף המכיל ארבעה קישורים, אחד לכל אחד מארבעת הסרווטים האלה.

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

6. מודול מדדים-סרוולט

ה מדדים-סרוולט המודול מספק לְסַנֵן בעל מספר מדדים: מטרים לקודי סטטוס, מונה למספר הבקשות הפעילות וטיימר למשך הבקשה.

6.1. תלות Maven

כדי להשתמש במודול זה, ראשית נוסיף את התלות ב- pom.xml:

 io.dropwizard.metrics metrics-servlet 3.1.2 

ותוכלו למצוא את הגרסה האחרונה שלה כאן.

6.2. נוֹהָג

כדי להשתמש בו, עלינו ליצור ServletContextListener שחושף את שלנו מטרי רישום אל ה InstrumentedFilter:

מחלקה ציבורית MyInstrumentedFilterContextListener מרחיב InstrumentedFilterContextListener {public static MetricRegistry REGISTRY = MetricRegistry חדש (); @Override מוגן MetricRegistry getMetricRegistry () {להחזיר REGISTRY; }} 

לאחר מכן, אנו מוסיפים אותם לתוך ה- web.xml:

  com.baeldung.metrics.servlet.MyInstrumentedFilterContextListener instrumentFilter com.codahale.metrics.servlet.InstrumentedFilter instrumentFilter / * 

עכשיו ה InstrumentedFilter יכול לעבוד. אם אנו רוצים לגשת לנתוני המדדים שלו, נוכל לעשות זאת באמצעותם מטרי רישוםהרשמה.

7. מודולים אחרים

למעט המודולים שהצגנו לעיל, למדדים יש כמה מודולים אחרים למטרות שונות:

  • מדדים- jvm: מספק מספר מדדים שימושיים למכשירי פנים של JVM
  • מדדים- ehcache: מספק InstrumentedEhcache, מעצב למטמון Ehcache
  • מדדים- httpclient: מספק שיעורים למכשור Apache HttpClient (גרסת 4.x)
  • מדדים-log4j: מספק InstrumentedAppender, Log4j חוטב יישום עבור log4j 1.x המתעד את קצב האירועים המחוברים לפי רמת הכניסה שלהם
  • מדדים-log4j2: דומה למדדים-log4j, רק עבור log4j 2.x
  • מדדים-לוגבק: מספק InstrumentedAppender, לוגבק חוטב יישום המתעד את קצב האירועים המחוברים לפי רמת הרישום שלהם
  • מדדים-ג'סון: מספק HealthCheckModule ו MetricsModule לג'קסון

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

8. מסקנה

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

כמו תמיד, קוד המקור המלא של הדוגמה זמין ב- GitHub.