diff --git a/entity-types/infra-haproxyinstance/definition.yml b/entity-types/infra-haproxyinstance/definition.yml index dd3bf5bc5..4494e3a8f 100644 --- a/entity-types/infra-haproxyinstance/definition.yml +++ b/entity-types/infra-haproxyinstance/definition.yml @@ -34,6 +34,8 @@ synthesis: haproxy.addr: # HAProxy-specific attributes (natively emitted by haproxyreceiver) haproxy.proxy_name: + # Relationship join key (label-based); indexed by the HAPROXYINSTANCE candidate. + haproxy.deployment.name: haproxy.service_name: # Environment attributes (from resourcedetection processor) os.type: @@ -86,6 +88,8 @@ synthesis: haproxy.addr: # HAProxy-specific attributes (natively emitted by haproxyreceiver) haproxy.proxy_name: + # Relationship join key (label-based); indexed by the HAPROXYINSTANCE candidate. + haproxy.deployment.name: haproxy.service_name: # Environment attributes (from resourcedetection processor) os.type: @@ -138,6 +142,8 @@ synthesis: ttl: P1D haproxy.addr: haproxy.proxy_name: + # Relationship join key (label-based); indexed by the HAPROXYINSTANCE candidate. + haproxy.deployment.name: haproxy.service_name: os.type: host.id: @@ -184,6 +190,8 @@ synthesis: ttl: P1D haproxy.addr: haproxy.proxy_name: + # Relationship join key (label-based); indexed by the HAPROXYINSTANCE candidate. + haproxy.deployment.name: haproxy.service_name: os.type: host.id: @@ -260,6 +268,8 @@ synthesis: haproxy.instance.id: haproxy.addr: haproxy.proxy_name: + # Relationship join key (label-based); indexed by the HAPROXYINSTANCE candidate. + haproxy.deployment.name: host.name: ttl: P1D host.id: @@ -300,6 +310,8 @@ synthesis: haproxy.instance.id: haproxy.addr: haproxy.proxy_name: + # Relationship join key (label-based); indexed by the HAPROXYINSTANCE candidate. + haproxy.deployment.name: host.name: ttl: P1D host.id: @@ -327,6 +339,7 @@ goldenTags: - host.id - host.name - haproxy.addr +- haproxy.deployment.name - os.type - cloud.provider - cloud.region diff --git a/entity-types/infra-haproxyinstance/tests/Metric.json b/entity-types/infra-haproxyinstance/tests/Metric.json index ec5b96cdf..731656de3 100644 --- a/entity-types/infra-haproxyinstance/tests/Metric.json +++ b/entity-types/infra-haproxyinstance/tests/Metric.json @@ -7,6 +7,7 @@ "haproxy.addr": "http://127.0.0.1:8404/stats", "haproxy.proxy_name": "http_front", "haproxy.service_name": "FRONTEND", + "haproxy.deployment.name": "haproxy-demo-lb", "description": "Number of connections over the last elapsed second (frontend). Corresponds to HAProxy's conn_rate metric.", "instrumentation.provider": "opentelemetry", "metricName": "haproxy.connections.rate", diff --git a/relationships/candidates/HAPROXYINSTANCE.stg.yml b/relationships/candidates/HAPROXYINSTANCE.stg.yml new file mode 100644 index 000000000..1f697941b --- /dev/null +++ b/relationships/candidates/HAPROXYINSTANCE.stg.yml @@ -0,0 +1,19 @@ +category: HAPROXYINSTANCE +lookups: + # Deployment-name lookup — indexes the HAPROXYINSTANCE entity by its + # haproxy.deployment.name join tag (label-based / Option 5). Both relationship + # directions resolve against this single field; the join value is identical on + # the client side (tags.haproxy.deployment.name) and the backend side + # (tags.haproxy.upstream.deployment.name). + - entityTypes: + - domain: INFRA + type: HAPROXYINSTANCE + tags: + matchingMode: ALL + predicates: + - tagKeys: ["haproxy.deployment.name"] + field: deploymentName + onMatch: + onMultipleMatches: RELATE_ALL + onMiss: + action: NO_OP diff --git a/relationships/synthesis/EXT-SERVICE-to-INFRA-HAPROXYINSTANCE.stg.yml b/relationships/synthesis/EXT-SERVICE-to-INFRA-HAPROXYINSTANCE.stg.yml new file mode 100644 index 000000000..6dff7b3b9 --- /dev/null +++ b/relationships/synthesis/EXT-SERVICE-to-INFRA-HAPROXYINSTANCE.stg.yml @@ -0,0 +1,30 @@ +relationships: + # OTel client service → HAPROXYINSTANCE (CALLS), label-based. + # The client (e.g. haproxy-frontend) declares which HAProxy it calls via + # OTEL_RESOURCE_ATTRIBUTES=tags.haproxy.deployment.name= + # Note the key: on HAProxy the *client* carries haproxy.deployment.name + - name: otelExtServiceCallsHaproxyInstanceByDeploymentLabelStg + version: "1" + origins: + - OpenTelemetry + conditions: + - attribute: eventType + anyOf: [ "Metric" ] + - attribute: newrelic.source + anyOf: [ "api.metrics.otlp" ] + - attribute: entity.type + anyOf: [ "SERVICE" ] + - attribute: tags.haproxy.deployment.name + present: true + relationship: + expires: PT75M + relationshipType: CALLS + source: + extractGuid: + attribute: entity.guid + target: + lookupGuid: + candidateCategory: HAPROXYINSTANCE + fields: + - field: deploymentName + attribute: tags.haproxy.deployment.name diff --git a/relationships/synthesis/INFRA-HAPROXYINSTANCE-to-EXT-SERVICE.stg.yml b/relationships/synthesis/INFRA-HAPROXYINSTANCE-to-EXT-SERVICE.stg.yml new file mode 100644 index 000000000..090d257cc --- /dev/null +++ b/relationships/synthesis/INFRA-HAPROXYINSTANCE-to-EXT-SERVICE.stg.yml @@ -0,0 +1,32 @@ +relationships: + # HAPROXYINSTANCE → OTel backend service (CALLS), label-based. + # The backend (e.g. haproxy-backend-8001/8002) declares the HAProxy that fronts + # it via + # OTEL_RESOURCE_ATTRIBUTES=tags.haproxy.upstream.deployment.name= + # ("upstream" = the load balancer in front of the backend). Note the key: on + # HAProxy the *backend* carries haproxy.upstream.deployment.name + - name: haproxyInstanceCallsOtelExtServiceByUpstreamLabelStg + version: "1" + origins: + - OpenTelemetry + conditions: + - attribute: eventType + anyOf: [ "Metric" ] + - attribute: newrelic.source + anyOf: [ "api.metrics.otlp" ] + - attribute: entity.type + anyOf: [ "SERVICE" ] + - attribute: tags.haproxy.upstream.deployment.name + present: true + relationship: + expires: PT75M + relationshipType: CALLS + source: + lookupGuid: + candidateCategory: HAPROXYINSTANCE + fields: + - field: deploymentName + attribute: tags.haproxy.upstream.deployment.name + target: + extractGuid: + attribute: entity.guid