Project: SkyWalking (Observability and Analysis / Observability)
File: service-hierarchy.md

SkyWalking v10 introduces a new concept `Service Hierarchy` which defines the relationships of existing logically same services in various layers. OAP will detect the services from different layers, and try to build the connections. There 2 ways to detect the connections: Automatically matching through OAP internal mechanism, no extra work is required. Build the connections through specific agents. Note: All the relationships and auto-matching rules should be defined in the `config/hierarchy-definition.yml` file. If you want to customize it according to your own needs, please refer to . | Upper layer | Lower layer | Matching rule | ||-|-| | GENERAL | K8S_SERVICE | | | GENERAL | APISIX | | | VIRTUAL_DATABASE | MYSQL | | | VIRTUAL_DATABASE | POSTGRESQL | | | VIRTUAL_DATABASE | CLICKHOUSE | | | VIRTUAL_MQ | RABBITMQ | | | VIRTUAL_MQ | ROCKETMQ | | | VIRTUAL_MQ | KAFKA | | | VIRTUAL_MQ | RABBITMQ | | | VIRTUAL_MQ | PULSAR | | | MESH | MESH_DP | | | MESH | K8S_SERVICE | | | MESHDP | K8SSERVICE | | | MYSQL | K8S_SERVICE | | | POSTGRESQL | K8S_SERVICE | | | CLICKHOUSE | K8S_SERVICE | | | NGINX | K8S_SERVICE | | | APISIX | K8S_SERVICE | | | ROCKETMQ | K8S_SERVICE | | | RABBITMQ | K8S_SERVICE | | | KAFKA | K8S_SERVICE | | | PULSAR | K8S_SERVICE | | | SO11YOAP | K8SSERVICE | | The following sections will describe the default matching rules in detail and use the `upper-layer On lower-layer` format. The example service name are based on SkyWalking default deployment. In SkyWalking the service name could be composed of `group` and `short name` with `::` separator. Rule name: `lower-short-name-remove-ns` Groovy script: `{ (u, l) -> u.shortName == l.shortName.substring(0, l.shortName.lastIndexOf('.')) }` Description: GENERAL.service.shortName == K8S_SERVICE.service.shortName without namespace Matched Example: GENERAL.service.name: `agent::songs` K8S_SERVICE.service.name: `skywalking-showcase::songs.sample-services` Rule name: `lower-short-name-remove-ns` Groovy script: `{ (u, l) -> u.shortName == l.shortName.substring(0, l.shortName.lastIndexOf('.')) }` Description: GENERAL.service.shortName == APISIX.service.shortName without namespace Matched Example: GENERAL.service.name: `agent::frontend` APISIX.service.name: `APISIX::frontend.sample-services` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description: VIRTUAL_DATABASE.service.shortName remove port == MYSQL.service.shortName with fqdn suffix Matched Example: VIRTUAL_DATABASE.service.name: `mysql.skywalking-showcase.svc.cluster.local:3306` MYSQL.service.name: `mysql::mysql.skywalking-showcase` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description: VIRTUAL_DATABASE.service.shortName remove port == POSTGRESQL.service.shortName with fqdn suffix Matched Example: VIRTUAL_DATABASE.service.name: `psql.skywalking-showcase.svc.cluster.local:5432` POSTGRESQL.service.name: `postgresql::psql.skywalking-showcase` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description: VIRTUAL_DATABASE.service.shortName remove port == CLICKHOUSE.service.shortName with fqdn suffix Matched Example: VIRTUAL_DATABASE.service.name: `clickhouse.skywalking-showcase.svc.cluster.local:8123` CLICKHOUSE.service.name: `clickhouse::clickhouse.skywalking-showcase` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description: VIRTUAL_MQ.service.shortName remove port == ROCKETMQ.service.shortName with fqdn suffix Matched Example: VIRTUAL_MQ.service.name: `rocketmq.skywalking-showcase.svc.cluster.local:9876` ROCKETMQ.service.name: `rocketmq::rocketmq.skywalking-showcase` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description:

remove port == RABBITMQ.service.shortName with fqdn suffix Matched Example: VIRTUAL_MQ.service.name: `rabbitmq.skywalking-showcase.svc.cluster.local:5672` RABBITMQ.service.name: `rabbitmq::rabbitmq.skywalking-showcase` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description: VIRTUAL_MQ.service.shortName remove port == KAFKA.service.shortName with fqdn suffix Matched Example: VIRTUAL_MQ.service.name: `kafka.skywalking-showcase.svc.cluster.local:9092` KAFKA.service.name: `kafka::rocketmq.skywalking-showcase` Rule name: `lower-short-name-with-fqdn` Groovy script: `{ (u, l) -> u.shortName.substring(0, u.shortName.lastIndexOf(':')) == l.shortName.concat('.svc.cluster.local') }` Description: VIRTUAL_MQ.service.shortName remove port == PULSAR.service.shortName with fqdn suffix Matched Example: VIRTUAL_MQ.service.name: `pulsar.skywalking-showcase.svc.cluster.local:6650` PULSAR.service.name: `pulsar::pulsar.skywalking-showcase` Rule name: `name` Groovy script: `{ (u, l) -> u.name == l.name }` Description: MESH.service.name == MESH_DP.service.name Matched Example: MESH.service.name: `mesh-svr::songs.sample-services` MESH_DP.service.name: `mesh-svr::songs.sample-services` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: MESH.service.shortName == K8S_SERVICE.service.shortName Matched Example: MESH.service.name: `mesh-svr::songs.sample-services` K8S_SERVICE.service.name: `skywalking-showcase::songs.sample-services` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: MESHDP.service.shortName == K8SSERVICE.service.shortName Matched Example: MESH_DP.service.name: `mesh-svr::songs.sample-services` K8S_SERVICE.service.name: `skywalking-showcase::songs.sample-services` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: MYSQL.service.shortName == K8S_SERVICE.service.shortName Matched Example: MYSQL.service.name: `mysql::mysql.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::mysql.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: POSTGRESQL.service.shortName == K8S_SERVICE.service.shortName Matched Example: POSTGRESQL.service.name: `postgresql::psql.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::psql.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: CLICKHOUSE.service.shortName == K8S_SERVICE.service.shortName Matched Example: CLICKHOUSE.service.name: `clickhouse::clickhouse.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::clickhouse.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: NGINX.service.shortName == K8S_SERVICE.service.shortName Matched Example: NGINX.service.name: `nginx::nginx.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::nginx.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: APISIX.service.shortName == K8S_SERVICE.service.shortName Matched Example: APISIX.service.name: `APISIX::frontend.sample-services` K8S_SERVICE.service.name: `skywalking-showcase::frontend.sample-services` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: ROCKETMQ.service.shortName == K8S_SERVICE.service.shortName Matched Example: ROCKETMQ.service.name: `rocketmq::rocketmq.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::rocketmq.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: RABBITMQ.service.shortName == K8S_SERVICE.service.shortName Matched Example: RABBITMQ.service.name: `rabbitmq::rabbitmq.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::rabbitmq.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: KAFKA.service.shortName == K8S_SERVICE.service.shortName Matched Example: KAFKA.service.name: `kafka::kafka.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::kafka.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: PULSAR.service.shortName == K8S_SERVICE.service.shortName Matched Example: PULSAR.service.name: `pulsar::pulsar.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::pulsar.skywalking-showcase` Rule name: `short-name` Groovy script: `{ (u, l) -> u.shortName == l.shortName }` Description: SO11YOAP.service.shortName == K8SSERVICE.service.shortName Matched Example: SO11Y_OAP.service.name: `demo-oap.skywalking-showcase` K8S_SERVICE.service.name: `skywalking-showcase::demo-oap.skywalking-showcase` Use agent tech involved(such as eBPF) and deployment tools(such as operator and agent injector) to detect the service hierarchy relations. | Upper layer | Lower layer | Agent | |-|--|-| Instance Hierarchy relationship follows the same definition as Service Hierarchy. If the service hierarchy is built, the instance hierarchy relationship could be detected automatically through the following rules: The upper instance name equals the lower instance name. The upper instance attribute `pod/hostname` equals the lower instance attribute `pod/hostname`. The upper instance attribute `pod/hostname` equals the lower instance name. The upper instance name equals the lower instance attribute `pod/hostname`.