Skip to content
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

Add representative count to apm-data plugin #119995

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Conversation

rubvs
Copy link

@rubvs rubvs commented Jan 10, 2025

Closes elastic/apm-data#388

The pipeline changes copies the representative count calculated in APM Data (see Code), into the event.success_count metric. The default representative count is 1.

If an event, which can only be a transaction or span in this context, failed for some reason, the event.success_count metric is set to zero. To my understanding, we are not capturing any data related to failed events. Nor do I see any usage of something like an event.failure_count metric. Please correct me if I'm wrong.

Kibana

Along with the unit test provided, the pipeline changes was also test manually in Kibana Console:

POST _ingest/pipeline/_simulate
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "description": "Test APM pipeline",
    "processors": [
      {
        "set": {
          "if": "ctx.transaction?.type != null",
          "field": "processor.event",
          "value": "transaction"
        }
      },
      {
        "set": {
          "field": "processor.event",
          "value": "span",
          "override": false
        }
      },
      {
        "script": {
          "if": "ctx[ctx.processor.event]?.duration == null",
          "source": """
            def eventDuration = ctx.event?.duration ?: 0;
            def rootObjectName = ctx.processor?.event;
            def rootObject = ctx[rootObjectName];
            if (rootObject == null) {
              rootObject = [:];
              ctx[rootObjectName] = rootObject;
            }
            rootObject.duration = ["us": (long)(eventDuration/1000)];
          """
        }
      },
      {
        "remove": {
          "field": ["event.duration"],
          "ignore_failure": true,
          "ignore_missing": true
        }
      },
      {
        "script": {
          "if": "ctx.event?.outcome == 'success'",
          "source": """
            ctx.event.success_count = ctx[ctx.processor?.event].representative_count;
          """
        }
      },
      {
        "set": {
          "if": "ctx.event?.outcome == 'failure'",
          "field": "event.success_count",
          "value": 0
        }
      }
    ]
  },
  "docs": [
    {
      "_source": {
        "processor": {
          "event": "transaction"
        },
        "transaction": {
          "representative_count": 0.2,
          "type": "request",
          "duration": {
            "us": 1234567
          }
        },
        "event": {
          "duration": 1234567000,
          "outcome": "success"
        }
      }
    },
    {
      "_source": {
        "processor": {
          "event": "span"
        },
        "span": {
          "representative_count": 0.3,
          "type": "request",
          "duration": {
            "us": 1234567
          }
        },
        "event": {
          "duration": 1234567000,
          "outcome": "success"
        }
      }
    },
    {
      "_source": {
        "processor": {"event": "transaction"},
        "transaction": {
          "representative_count": 0.2,
          "type": "request",
          "duration": {
            "us": 1234567
          }
        },
        "event": {
          "duration": 1234567000,
          "outcome": "failure"
        }
      }
    },
    {
      "_source": {
        "processor": {
          "event": "span"
        },
        "span": {
          "representative_count": 0.3,
          "type": "request",
          "duration": {
            "us": 1234567
          }
        },
        "event": {
          "duration": 1234567000,
          "outcome": "failure"
        }
      }
    }
  ]
}

@joegallo joegallo added >enhancement Team:Data Management Meta label for data/management team external-contributor Pull request authored by a developer outside the Elasticsearch team labels Jan 10, 2025
@rubvs rubvs requested review from lahsivjar and carsonip January 10, 2025 22:33
field: event.success_count
value: 1
source: |
ctx.event.success_count = ctx[ctx.processor?.event]?.representative_count;
Copy link
Member

Choose a reason for hiding this comment

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

I can't think of a reason why representative count would be missing, but I still think a null check feels safer.

Copy link
Contributor

Choose a reason for hiding this comment

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

(Not a response to @carsonip, just a comment on the same section of the code.) What eventually happens with the value of the event.success_count? Does it make sense to pop a null in there or will that blow up later processing?

Copy link
Member

Choose a reason for hiding this comment

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

Looking at apm-server source code, event.success_count can be nil: https://github.com/elastic/apm-server/blob/79c4599ab9bd65e1cc688eed1169505933f6f405/systemtest/ingest_test.go#L177

It is only non-nil when outcome is success or failure, in which case, non-0 and 0 respectively.

I assume it will be used by APM UI for getting a transaction success rate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>enhancement external-contributor Pull request authored by a developer outside the Elasticsearch team Team:Data Management Meta label for data/management team v9.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

event.success_count metric should use representative count
4 participants