001package nl.nlighten.prometheus.wildfly; 002 003import io.prometheus.client.Collector; 004import io.prometheus.client.GaugeMetricFamily; 005 006import javax.management.AttributeNotFoundException; 007import javax.management.MBeanServer; 008import javax.management.ObjectInstance; 009import javax.management.ObjectName; 010import java.lang.management.ManagementFactory; 011import java.util.*; 012 013/** 014 * Exports undertow session and http-listener related metrics. 015 * <p> 016 * Example usage: 017 * <pre> 018 * {@code 019 * new UndertowExports().register(); 020 * } 021 * </pre> 022 * Example metrics being exported: 023 * <pre> 024 * undertow_listener_request_total{server="default-server",listener="default",} 11000.0 025 * undertow_listener_error_total{server="default-server",listener="default",} 3.0 026 * undertow_listener_processingtime_nanos{server="default-server",listener="default",} 0.0 027 * undertow_listener_sent_bytes{server="default-server",listener="default",} 5056098.0 028 * undertow_listener_received_bytes{server="default-server",listener="default",} 406234.0 029 * undertow_session_active_total{deployment="foo",context="/bar",} 53.0 030 * undertow_session_rejected_total{deployment="foo",context="/bar",} 0.0 031 * undertow_session_created_total{deployment="foo",context="/bar",} 343.0 032 * undertow_session_expired_total{deployment="foo",context="/bar",} 290.0 033 * undertow_session_alivetime_avg_seconds{deployment="foo",context="/bar",} 2304482.0 034 * undertow_session_alivetime_max_seconds{deployment="foo",context="/bar",} 8983372.0 035 * 036 * 037 * </pre> 038 * Note that you need to enable undertow statistics to see anything 039 */ 040public class UndertowExports extends Collector { 041 042 public List<MetricFamilySamples> collect() { 043 List<MetricFamilySamples> mfs = new ArrayList<>(); 044 try { 045 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 046 ObjectName filterName = new ObjectName("jboss.as:subsystem=undertow,server=*,http-listener=*"); 047 Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); 048 049 if (mBeans.size() > 0) { 050 051 GaugeMetricFamily errorCountGauge = new GaugeMetricFamily( 052 "undertow_listener_error_total", 053 "Number of errors for this http-listener", 054 Arrays.asList("server", "listener")); 055 056 GaugeMetricFamily processingTimeGauge = new GaugeMetricFamily( 057 "undertow_listener_processingtime_nanos", 058 "Total processing time for this http-listener", 059 Arrays.asList("server", "listener")); 060 061 GaugeMetricFamily requestCountGauge = new GaugeMetricFamily( 062 "undertow_listener_request_total", 063 "Total request count for this http-listener", 064 Arrays.asList("server", "listener")); 065 066 GaugeMetricFamily bytesSentGauge = new GaugeMetricFamily( 067 "undertow_listener_sent_bytes", 068 "Number of bytes sent by this http-listener", 069 Arrays.asList("server", "listener")); 070 071 GaugeMetricFamily bytesReceivedGauge = new GaugeMetricFamily( 072 "undertow_listener_received_bytes", 073 "Number of bytes received by this http-listener", 074 Arrays.asList("server", "listener")); 075 076 for (final ObjectInstance mBean : mBeans) { 077 078 errorCountGauge.addMetric( 079 Arrays.asList(mBean.getObjectName().getKeyProperty("server"), mBean.getObjectName().getKeyProperty("http-listener")), 080 ((Long) server.getAttribute(mBean.getObjectName(), "errorCount")).doubleValue()); 081 082 processingTimeGauge.addMetric( 083 Arrays.asList(mBean.getObjectName().getKeyProperty("server"), mBean.getObjectName().getKeyProperty("http-listener")), 084 ((Long) server.getAttribute(mBean.getObjectName(), "processingTime")).doubleValue()); 085 086 requestCountGauge.addMetric( 087 Arrays.asList(mBean.getObjectName().getKeyProperty("server"), mBean.getObjectName().getKeyProperty("http-listener")), 088 ((Long) server.getAttribute(mBean.getObjectName(), "requestCount")).doubleValue()); 089 090 bytesSentGauge.addMetric( 091 Arrays.asList(mBean.getObjectName().getKeyProperty("server"), mBean.getObjectName().getKeyProperty("http-listener")), 092 ((Long) server.getAttribute(mBean.getObjectName(), "bytesSent")).doubleValue()); 093 094 bytesReceivedGauge.addMetric( 095 Arrays.asList(mBean.getObjectName().getKeyProperty("server"), mBean.getObjectName().getKeyProperty("http-listener")), 096 ((Long) server.getAttribute(mBean.getObjectName(), "bytesReceived")).doubleValue()); 097 } 098 mfs.add(errorCountGauge); 099 mfs.add(processingTimeGauge); 100 mfs.add(requestCountGauge); 101 102 filterName = new ObjectName("jboss.as.expr:deployment=*,subsystem=undertow"); 103 mBeans = server.queryMBeans(filterName, null); 104 105 if (mBeans.size() > 0) { 106 GaugeMetricFamily activeSessionCountGauge = new GaugeMetricFamily( 107 "undertow_session_active_total", 108 "Number of active sessions", 109 Arrays.asList("deployment", "context")); 110 111 GaugeMetricFamily rejectedSessionCountGauge = new GaugeMetricFamily( 112 "undertow_session_rejected_total", 113 "Number of rejected sessions", 114 Arrays.asList("deployment", "context")); 115 116 GaugeMetricFamily createdSessionCountGauge = new GaugeMetricFamily( 117 "undertow_session_created_total", 118 "Number of sessions created", 119 Arrays.asList("deployment", "context")); 120 121 GaugeMetricFamily expiredSessionCountGauge = new GaugeMetricFamily( 122 "undertow_session_expired_total", 123 "Number of sessions expired", 124 Arrays.asList("deployment", "context")); 125 126 GaugeMetricFamily sessionAvgAliveTimeGauge = new GaugeMetricFamily( 127 "undertow_session_alivetime_avg_seconds", 128 "Average session alive time", 129 Arrays.asList("deployment", "context")); 130 131 GaugeMetricFamily sessionMaxAliveTimeGauge = new GaugeMetricFamily( 132 "undertow_session_alivetime_max_seconds", 133 "Average session alive time", 134 Arrays.asList("deployment", "context")); 135 136 for (final ObjectInstance mBean : mBeans) { 137 String deployment = mBean.getObjectName().getKeyProperty("deployment"); 138 String context = (String) server.getAttribute(mBean.getObjectName(), "contextRoot"); 139 140 activeSessionCountGauge.addMetric( 141 Arrays.asList(deployment, context), 142 Double.parseDouble((String) server.getAttribute(mBean.getObjectName(), "activeSessions"))); 143 144 rejectedSessionCountGauge.addMetric( 145 Arrays.asList(deployment, context), 146 Double.parseDouble((String) server.getAttribute(mBean.getObjectName(), "rejectedSessions"))); 147 148 createdSessionCountGauge.addMetric( 149 Arrays.asList(deployment, context), 150 Double.parseDouble((String) server.getAttribute(mBean.getObjectName(), "sessionsCreated"))); 151 152 expiredSessionCountGauge.addMetric( 153 Arrays.asList(deployment, context), 154 Double.parseDouble((String) server.getAttribute(mBean.getObjectName(), "expiredSessions"))); 155 156 sessionAvgAliveTimeGauge.addMetric( 157 Arrays.asList(deployment, context), 158 Double.parseDouble((String) server.getAttribute(mBean.getObjectName(), "sessionAvgAliveTime"))); 159 160 sessionMaxAliveTimeGauge.addMetric( 161 Arrays.asList(deployment, context), 162 Double.parseDouble((String) server.getAttribute(mBean.getObjectName(), "sessionMaxAliveTime"))); 163 } 164 mfs.add(activeSessionCountGauge); 165 mfs.add(rejectedSessionCountGauge); 166 mfs.add(createdSessionCountGauge); 167 mfs.add(expiredSessionCountGauge); 168 mfs.add(sessionAvgAliveTimeGauge); 169 mfs.add(sessionMaxAliveTimeGauge); 170 171 } 172 173 } 174 } catch (AttributeNotFoundException e) { 175 // ignore, can happen during server startup. 176 } catch (Exception e) { 177 e.printStackTrace(); 178 } 179 return mfs; 180 } 181} 182