Skip to content

Conversation

@hiralpatelHM
Copy link
Contributor

What this PR does / why we need it:

  • Implement JSON parsing in ParseJSONFields to extract anomaly-related fields
  • Parse top-level anomaly_score, prediction, and prediction_reason
  • Parse diagnostics array to extract contribution values and normalize percentages

Which issue(s) this PR fixes:

Fixes #Anomaly Detection

Special notes for your reviewer:

@hiralpatelHM hiralpatelHM requested a review from a team as a code owner November 28, 2025 12:47
@hiralpatelHM hiralpatelHM requested review from iwysiu and njvrzm and removed request for a team November 28, 2025 12:47
@github-project-automation github-project-automation bot moved this to Incoming in AWS Datasources Dec 3, 2025
@kevinwcyu kevinwcyu moved this from Incoming to Next in AWS Datasources Dec 3, 2025
Copy link
Contributor

@iwysiu iwysiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! I did an initial pass of this, but do you have links to any aws docs or anything for more context on this? I feel like I don't have the full story on what this is implementing.

Also the code in ParseJsonFields specifically could be more commented since its doing a lot of logic and not all of it's immediately clear, for example where the diag_anomaly field get added.

return propertyNameMap
}

func isRequireJSONParsing(query models.BaseQuery) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this could be requiresJsonParsing instead

propertyNameMap := map[string]string{}
if assetID == "" {
backend.Logger.Warn("BuildPropertyNameMap: empty assetId")
return propertyNameMap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of returning an empty map, we could return an error instead, and either log the error in ParseJsonFields or exit early if that's appropriate


var obj map[string]interface{}
if err := json.Unmarshal([]byte(rawStr), &obj); err != nil {
backend.Logger.Warn("ParseJSONFields: corrupted JSON, skipping row", "err", err, "frame", frame.Name, "row", r)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This log should include the field. Also I know you have a test for it but I would think users would expect an error in this situation instead of partially returned data. Do we expect to get corrupted JSON returned for this type of query relatively often?

// Required fields check
for _, req := range []string{"timestamp", "prediction", "prediction_reason"} {
if _, ok := obj[req]; !ok {
backend.Logger.Warn("ParseJSONFields: missing required field", "field", req, "frame", frame.Name, "row", r)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this log should include the field. The same thing where if these are required fields, I feel like users would expect an error

}
jsonParsed = true
// Required fields check
for _, req := range []string{"timestamp", "prediction", "prediction_reason"} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The required fields should be consts since we use them multiple times

}

for key, val := range obj {
if key == "diagnostics" || key == "timestamp" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we also skip anomaly score if we handle it in the next block? Also are we intentionally skipping timestamp?

if !ok {
continue
}
rawName, _ := diagObj["name"].(string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably have a check for if name exists in diagObj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Next

Development

Successfully merging this pull request may close these issues.

2 participants