33
44package com .microsoft .applicationinsights .agent .internal .init ;
55
6- import static com .microsoft .applicationinsights .agent .internal .diagnostics .MsgId .CUSTOM_JMX_METRIC_ERROR ;
7-
86import com .azure .monitor .opentelemetry .autoconfigure .implementation .utils .PropertyHelper ;
9- import com .azure .monitor .opentelemetry .autoconfigure .implementation .utils .Strings ;
107import com .microsoft .applicationinsights .agent .internal .configuration .Configuration ;
118import com .microsoft .applicationinsights .agent .internal .perfcounter .DeadLockDetectorPerformanceCounter ;
129import com .microsoft .applicationinsights .agent .internal .perfcounter .FreeMemoryPerformanceCounter ;
1310import com .microsoft .applicationinsights .agent .internal .perfcounter .GcPerformanceCounter ;
1411import com .microsoft .applicationinsights .agent .internal .perfcounter .JmxAttributeData ;
15- import com .microsoft .applicationinsights .agent .internal .perfcounter .JmxDataFetcher ;
1612import com .microsoft .applicationinsights .agent .internal .perfcounter .JmxMetricPerformanceCounter ;
1713import com .microsoft .applicationinsights .agent .internal .perfcounter .JvmHeapMemoryUsedPerformanceCounter ;
1814import com .microsoft .applicationinsights .agent .internal .perfcounter .OshiPerformanceCounter ;
1915import com .microsoft .applicationinsights .agent .internal .perfcounter .PerformanceCounterContainer ;
2016import com .microsoft .applicationinsights .agent .internal .perfcounter .ProcessCpuPerformanceCounter ;
2117import com .microsoft .applicationinsights .agent .internal .perfcounter .ProcessMemoryPerformanceCounter ;
22- import io .opentelemetry .api .GlobalOpenTelemetry ;
23- import io .opentelemetry .api .common .AttributeKey ;
24- import io .opentelemetry .api .common .Attributes ;
25- import io .opentelemetry .api .metrics .ObservableDoubleMeasurement ;
2618import java .lang .management .ManagementFactory ;
2719import java .lang .management .ThreadMXBean ;
28- import java .util .ArrayList ;
2920import java .util .Arrays ;
30- import java .util .Collection ;
31- import java .util .HashMap ;
3221import java .util .List ;
33- import java .util .Map ;
3422import org .slf4j .Logger ;
3523import org .slf4j .LoggerFactory ;
36- import org .slf4j .MDC ;
3724
3825public class PerformanceCounterInitializer {
3926
4027 private static final Logger logger = LoggerFactory .getLogger (PerformanceCounterInitializer .class );
41- private static final String METRIC_NAME_REGEXP = "[a-zA-Z0-9_.-/]+" ;
42- private static final String INVALID_CHARACTER_REGEXP = "[^a-zA-Z0-9_.-/]" ;
4328
4429 public static void initialize (Configuration configuration ) {
4530
4631 PerformanceCounterContainer .INSTANCE .setCollectionFrequencyInSec (
4732 configuration .metricIntervalSeconds );
4833
4934 if (logger .isDebugEnabled ()) {
50- PerformanceCounterContainer .INSTANCE .setLogAvailableJmxMetrics ();
35+ PerformanceCounterContainer .INSTANCE .setLogAvailableJmxMetrics (configuration . jmxMetrics );
5136 }
5237
5338 // We don't want these two to be flowing to the OTLP endpoint
@@ -65,7 +50,7 @@ public static void initialize(Configuration configuration) {
6550 "LoadedClassCount" ,
6651 configuration .jmxMetrics );
6752
68- loadCustomJmxPerfCounters (configuration .jmxMetrics );
53+ JmxPerformanceCounterLoader . loadCustomJmxPerfCounters (configuration .jmxMetrics );
6954
7055 PerformanceCounterContainer .INSTANCE .register (
7156 new ProcessCpuPerformanceCounter (
@@ -114,127 +99,5 @@ private static boolean isMetricInConfig(
11499 return false ;
115100 }
116101
117- /**
118- * The method will load the Jmx performance counters requested by the user to the system: 1. Build
119- * a map where the key is the Jmx object name and the value is a list of requested attributes. 2.
120- * Go through all the requested Jmx counters: a. If the object name is not in the map, add it with
121- * an empty list Else get the list b. Add the attribute to the list. 3. Go through the map For
122- * every entry (object name and attributes) to build a meter per attribute & for each meter
123- * register a callback to report the metric value.
124- */
125- private static void loadCustomJmxPerfCounters (List <Configuration .JmxMetric > jmxXmlElements ) {
126- HashMap <String , Collection <JmxAttributeData >> data = new HashMap <>();
127-
128- // Build a map of object name to its requested attributes
129- for (Configuration .JmxMetric jmxElement : jmxXmlElements ) {
130- Collection <JmxAttributeData > collection =
131- data .computeIfAbsent (jmxElement .objectName , k -> new ArrayList <>());
132-
133- if (Strings .isNullOrEmpty (jmxElement .objectName )) {
134- try (MDC .MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR .makeActive ()) {
135- logger .error ("JMX object name is empty, will be ignored" );
136- }
137- continue ;
138- }
139-
140- if (Strings .isNullOrEmpty (jmxElement .attribute )) {
141- try (MDC .MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR .makeActive ()) {
142- logger .error ("JMX attribute is empty for '{}'" , jmxElement .objectName );
143- }
144- continue ;
145- }
146-
147- if (Strings .isNullOrEmpty (jmxElement .name )) {
148- try (MDC .MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR .makeActive ()) {
149- logger .error ("JMX name is empty for '{}', will be ignored" , jmxElement .objectName );
150- }
151- continue ;
152- }
153-
154- collection .add (new JmxAttributeData (jmxElement .name , jmxElement .attribute ));
155- }
156-
157- createMeterPerAttribute (data );
158- }
159-
160- // Create a meter for each attribute & declare the callback that reports the metric in the meter.
161- private static void createMeterPerAttribute (
162- Map <String , Collection <JmxAttributeData >> objectAndAttributesMap ) {
163- for (Map .Entry <String , Collection <JmxAttributeData >> entry :
164- objectAndAttributesMap .entrySet ()) {
165- String objectName = entry .getKey ();
166-
167- for (JmxAttributeData jmxAttributeData : entry .getValue ()) {
168-
169- String otelMetricName ;
170- if (jmxAttributeData .metricName .matches (METRIC_NAME_REGEXP )) {
171- otelMetricName = jmxAttributeData .metricName ;
172- } else {
173- otelMetricName = jmxAttributeData .metricName .replaceAll (INVALID_CHARACTER_REGEXP , "_" );
174- }
175-
176- GlobalOpenTelemetry .getMeter ("com.microsoft.applicationinsights.jmx" )
177- .gaugeBuilder (otelMetricName )
178- .buildWithCallback (
179- observableDoubleMeasurement -> {
180- calculateAndRecordValueForAttribute (
181- observableDoubleMeasurement , objectName , jmxAttributeData );
182- });
183- }
184- }
185- }
186-
187- private static void calculateAndRecordValueForAttribute (
188- ObservableDoubleMeasurement observableDoubleMeasurement ,
189- String objectName ,
190- JmxAttributeData jmxAttributeData ) {
191- try {
192- List <Object > result =
193- JmxDataFetcher .fetch (
194- objectName , jmxAttributeData .attribute ); // should return the [val, ...] here
195-
196- logger .trace (
197- "Size of the JmxDataFetcher.fetch result: {}, for objectName:{} and metricName:{}" ,
198- result .size (),
199- objectName ,
200- jmxAttributeData .metricName );
201-
202- boolean ok = true ;
203- double value = 0.0 ;
204- for (Object obj : result ) {
205- try {
206- if (obj instanceof Boolean ) {
207- value = ((Boolean ) obj ).booleanValue () ? 1 : 0 ;
208- } else {
209- value += Double .parseDouble (String .valueOf (obj ));
210- }
211- } catch (RuntimeException e ) {
212- ok = false ;
213- break ;
214- }
215- }
216- if (ok ) {
217- logger .trace (
218- "value {} for objectName:{} and metricName{}" ,
219- value ,
220- objectName ,
221- jmxAttributeData .metricName );
222- observableDoubleMeasurement .record (
223- value ,
224- Attributes .of (
225- AttributeKey .stringKey ("applicationinsights.internal.metric_name" ),
226- jmxAttributeData .metricName ));
227- }
228- } catch (Exception e ) {
229- try (MDC .MDCCloseable ignored = CUSTOM_JMX_METRIC_ERROR .makeActive ()) {
230- logger .error (
231- "Failed to calculate the metric value for objectName {} and metric name {}" ,
232- objectName ,
233- jmxAttributeData .metricName );
234- logger .error ("Exception: {}" , e .toString ());
235- }
236- }
237- }
238-
239102 private PerformanceCounterInitializer () {}
240103}
0 commit comments