-
Notifications
You must be signed in to change notification settings - Fork 2.1k
OpenTelemetry Metrics Support For Live Metrics #41220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
b5748bc
sending metrics to openTel exporter
t-nsukumar e072720
working base version
t-nsukumar 8cc3cff
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 59db9df
testing metric interval
t-nsukumar 14bbaca
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar d7d9a6c
Merge branch 't-nsukumar/experimentation' of https://github.com/navsu…
t-nsukumar 7280ddf
added etag variable
t-nsukumar d0a4401
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 26ddfba
code for sending opentel metrics
t-nsukumar 2b1e66c
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 26f2934
fixed custom metrics to display on Live
t-nsukumar cb1ee6e
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar f069e2d
Resolved intermittent display issue in Live Metrics
t-nsukumar f9c2a03
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 59e7318
Merge branch 't-nsukumar/experimentation' into main
navsukumar 13a2561
Merge pull request #1 from navsukumar/main
navsukumar b9058f2
resolved reliance on breeze interval
t-nsukumar ec3a3e0
Merge remote-tracking branch 'origin/t-nsukumar/experimentation' into…
t-nsukumar 6de7c2f
Merge branch 'Azure:main' into main
navsukumar 5aef823
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 87609a5
Merge branch 't-nsukumar/experimentation' of https://github.com/navsu…
t-nsukumar b1209e6
Merge branch 'Azure:main' into main
navsukumar 109d18e
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 39168fe
Merge branch 't-nsukumar/experimentation' of https://github.com/navsu…
t-nsukumar a1cf9ca
working version
t-nsukumar 8aee2f1
Merge branch 'Azure:main' into main
navsukumar 824b200
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 925b457
refactoring QuickPulseConfiguration
t-nsukumar 97026e2
Merge branch 'Azure:main' into main
navsukumar 7314a75
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 56c58d4
Merge branch 'Azure:main' into main
navsukumar 1c863e0
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 6b302bf
Merge branch 'Azure:main' into main
navsukumar 2231e28
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar 258b89c
fixed same metric on multiple dashboards bug
t-nsukumar 46af557
Merge branch 'Azure:main' into main
navsukumar 4c86a30
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar e2113f7
temporarily removing timestamp
t-nsukumar 472287f
updated functionality
t-nsukumar 52fc348
updated invariant version in tests
t-nsukumar cea6b53
Merge branch 'Azure:main' into main
navsukumar 267658c
Merge branch 'Azure:main' into t-nsukumar/experimentation
navsukumar ac7631a
deleted reset function in config
t-nsukumar 9ec6d16
refactored storage of derived metric info
t-nsukumar 52b0d3f
Merge branch 'main' into t-nsukumar/experimentation
t-nsukumar 7cbc371
added filtering support
t-nsukumar eb9e78c
big merge from sdk main
t-nsukumar dcc0e67
working on fixing implementation
t-nsukumar 640a32e
adapted to use azure-json
t-nsukumar 00a2332
merged main into branch
t-nsukumar f78b58c
removed unused import statements
t-nsukumar aed5a9c
removed unused imports
t-nsukumar 62a8fd0
Merge branch 'main' into t-nsukumar/experimentation
t-nsukumar 6903595
Merge remote-tracking branch 'upstream/main'
t-nsukumar 632bcca
Merge branch 'main' into t-nsukumar/experimentation
t-nsukumar e48e6ff
fixed metric receiver
t-nsukumar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
250 changes: 250 additions & 0 deletions
250
...ure/monitor/opentelemetry/exporter/implementation/quickpulse/QuickPulseConfiguration.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
package com.azure.monitor.opentelemetry.exporter.implementation.quickpulse; | ||
|
||
import com.azure.core.http.HttpResponse; | ||
import com.azure.core.util.logging.ClientLogger; | ||
import com.azure.json.*; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Objects; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
public class QuickPulseConfiguration { | ||
private static final ClientLogger logger = new ClientLogger(QuickPulseDataFetcher.class); | ||
private AtomicReference<String> etag = new AtomicReference<>(); | ||
private ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>> derivedMetrics = new ConcurrentHashMap<>(); | ||
|
||
public synchronized String getEtag() { | ||
return this.etag.get(); | ||
} | ||
|
||
public synchronized void setEtag(String etag) { | ||
this.etag.set(etag); | ||
} | ||
|
||
public synchronized ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>> getDerivedMetrics() { | ||
return this.derivedMetrics; | ||
} | ||
|
||
public synchronized void setDerivedMetrics(ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>> metrics) { | ||
this.derivedMetrics = metrics; | ||
} | ||
|
||
public synchronized void updateConfig(String etagValue, | ||
ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>> otelMetrics) { | ||
if (!Objects.equals(this.getEtag(), etagValue)) { | ||
this.setEtag(etagValue); | ||
this.setDerivedMetrics(otelMetrics); | ||
} | ||
|
||
} | ||
|
||
public ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>> parseDerivedMetrics(HttpResponse response) | ||
throws IOException { | ||
|
||
ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>> requestedMetrics = new ConcurrentHashMap<>(); | ||
try { | ||
|
||
String responseBody = response.getBodyAsString().block(); | ||
if (responseBody == null || responseBody.isEmpty()) { | ||
return new ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>>(); | ||
} | ||
|
||
try (JsonReader jsonReader = JsonProviders.createReader(responseBody)) { | ||
jsonReader.nextToken(); | ||
while (jsonReader.nextToken() != JsonToken.END_OBJECT) { | ||
if ("Metrics".equals(jsonReader.getFieldName())) { | ||
jsonReader.nextToken(); | ||
|
||
while (jsonReader.nextToken() != JsonToken.END_ARRAY) { | ||
DerivedMetricInfo metric = new DerivedMetricInfo(); | ||
|
||
while (jsonReader.nextToken() != JsonToken.END_OBJECT) { | ||
|
||
String fieldName = jsonReader.getFieldName(); | ||
jsonReader.nextToken(); | ||
|
||
switch (fieldName) { | ||
case "Id": | ||
metric.setId(jsonReader.getString()); | ||
break; | ||
|
||
case "Aggregation": | ||
metric.setAggregation(jsonReader.getString()); | ||
break; | ||
|
||
case "TelemetryType": | ||
metric.setTelemetryType(jsonReader.getString()); | ||
break; | ||
|
||
case "Projection": | ||
metric.setProjection(jsonReader.getString()); | ||
break; | ||
|
||
case "FilterGroups": | ||
// Handle "FilterGroups" field | ||
if (jsonReader.currentToken() == JsonToken.START_ARRAY) { | ||
while (jsonReader.nextToken() != JsonToken.END_ARRAY) { | ||
if (jsonReader.currentToken() == JsonToken.START_OBJECT) { | ||
while (jsonReader.nextToken() != JsonToken.END_OBJECT) { | ||
if (jsonReader.currentToken() == JsonToken.FIELD_NAME | ||
&& jsonReader.getFieldName().equals("Filters")) { | ||
jsonReader.nextToken(); | ||
if (jsonReader.currentToken() == JsonToken.START_ARRAY) { | ||
while (jsonReader.nextToken() != JsonToken.END_ARRAY) { | ||
if (jsonReader.currentToken() | ||
== JsonToken.START_OBJECT) { | ||
String innerFieldName = ""; | ||
String predicate = ""; | ||
String comparand = ""; | ||
|
||
while (jsonReader.nextToken() | ||
!= JsonToken.END_OBJECT) { | ||
String filterFieldName | ||
= jsonReader.getFieldName(); | ||
jsonReader.nextToken(); | ||
|
||
switch (filterFieldName) { | ||
case "FieldName": | ||
innerFieldName | ||
= jsonReader.getString(); | ||
if (innerFieldName.contains(".")) { | ||
innerFieldName = innerFieldName | ||
.split("\\.")[1]; | ||
} | ||
break; | ||
|
||
case "Predicate": | ||
predicate = jsonReader.getString(); | ||
break; | ||
|
||
case "Comparand": | ||
comparand = jsonReader.getString(); | ||
break; | ||
} | ||
} | ||
|
||
if (!innerFieldName.isEmpty() | ||
&& !innerFieldName.equals("undefined") | ||
&& !predicate.isEmpty() | ||
&& !comparand.isEmpty()) { | ||
metric.addFilterGroup(innerFieldName, | ||
predicate, comparand); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
break; | ||
|
||
default: | ||
jsonReader.skipChildren(); | ||
break; | ||
} | ||
} | ||
requestedMetrics.computeIfAbsent(metric.getTelemetryType(), k -> new ArrayList<>()) | ||
.add(metric); | ||
} | ||
} else { | ||
jsonReader.skipChildren(); | ||
|
||
} | ||
} | ||
} | ||
return requestedMetrics; | ||
} catch (Exception e) { | ||
logger.verbose("Failed to parse metrics from response: %s", e.getMessage()); | ||
} | ||
return new ConcurrentHashMap<String, ArrayList<DerivedMetricInfo>>(); | ||
} | ||
|
||
public class DerivedMetricInfo { | ||
private String id; | ||
private String projection; | ||
private String telemetryType; | ||
private String aggregation; | ||
private ArrayList<FilterGroup> filterGroups = new ArrayList<FilterGroup>(); | ||
|
||
public String getId() { | ||
return this.id; | ||
} | ||
|
||
public void setId(String id) { | ||
this.id = id; | ||
} | ||
|
||
public String getProjection() { | ||
return projection; | ||
} | ||
|
||
public void setTelemetryType(String telemetryType) { | ||
this.telemetryType = telemetryType; | ||
} | ||
|
||
public String getTelemetryType() { | ||
return this.telemetryType; | ||
} | ||
|
||
public void setProjection(String projection) { | ||
this.projection = projection; | ||
} | ||
|
||
public String getAggregation() { | ||
return this.aggregation; | ||
} | ||
|
||
public void setAggregation(String aggregation) { | ||
this.aggregation = aggregation; | ||
} | ||
|
||
public ArrayList<FilterGroup> getFilterGroups() { | ||
return this.filterGroups; | ||
} | ||
|
||
public void addFilterGroup(String fieldName, String predicate, String comparand) { | ||
this.filterGroups.add(new FilterGroup(fieldName, predicate, comparand)); | ||
} | ||
} | ||
|
||
class FilterGroup { | ||
private String fieldName; | ||
private String operator; | ||
private String comparand; | ||
|
||
public FilterGroup(String fieldName, String predicate, String comparand) { | ||
this.setFieldName(fieldName); | ||
this.setOperator(predicate); | ||
this.setComparand(comparand); | ||
} | ||
|
||
public String getFieldName() { | ||
return this.fieldName; | ||
} | ||
|
||
private void setFieldName(String fieldName) { | ||
this.fieldName = fieldName; | ||
} | ||
|
||
public String getOperator() { | ||
return this.operator; | ||
} | ||
|
||
private void setOperator(String operator) { | ||
this.operator = operator; | ||
} | ||
|
||
public String getComparand() { | ||
return this.comparand; | ||
} | ||
|
||
public void setComparand(String comparand) { | ||
this.comparand = comparand; | ||
} | ||
} | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.