Aligning span names
This is the initial step towards aligning span names across agents.
Naturally, it only deals with frameworks that are not language-specific. We have specs for those, but in some cases, these specs were added in retrospect, reflecting the naming-chaos at the time, so we may want to revisit.
@elastic/apm-agent-devs Please take the time to fill some examples in the tables and vote wherever there is a
sign - either add 👍 to an existing option, or add a new one with your 👍 on it.
After I gather your feedback, I will make the spec PRs accordingly wherever required.
OpenTelemetry general Span guidelines for reference.
HTTP
The naming scheme for transactions is not rigid in the existing spec. It is more so for spans, where names should have the format <method> <host>.
OpenTelemetry HTTP spec for reference.
Existing state:
| Agent |
Transaction |
Span |
| Java |
GET unknown route ServletClassName#doGet GET /testWithPathMethod/{id} |
GET 127.0.0.1 GET [::1] GET localhost |
| .NET |
|
|
| Go |
GET unknown route GET /hello/:name GET /hello/{name} |
GET host:port |
| Node.js |
GET unknown route (vanilla HTTP server) GET /hello/:name (typical with frameworks) static file (if using express.static()) CORS preflight (CORS preflight req with hapi framework) |
POST localhost:9200/myIndex*/_search (full URL usage is elastic/apm-agent-nodejs#2067) GET http://localhost:52394/sub (http2, same issue) |
| PHP |
GET /users/{id} |
POST example.com |
| Python |
GET /users/{id} (only for frameworks that expose the necessary routing info ) |
POST example.com |
| Ruby |
PostsController#index (most likely) GET /users/:id POST /publish Rack (last resort) |
POST example.com GET elastic.co |
Choose one of the followings:
- Spec is good enough as is 👍 👍 👍 👍 👍
- Spec should change (replace with your suggestion and add a +1)
DB
The spec defines a convention for each DB type.
OpenTelemetry DB spec for reference.
Existing state:
| Agent |
SQL DB |
Redis |
MongoDB |
GraphQL |
Elasticsearch |
DynamoDB |
S3 |
| Java |
SELECT FROM table |
SET |
db.collection.drop |
NA |
Elasticsearch: GET /index/_search |
NA |
NA |
| .NET |
|
|
|
|
|
|
|
| Go |
SELECT FROM table |
SET (flush pipeline) |
${collection}.${command} aggregate |
NA |
Elasticsearch: GET /index/_search |
DynamoDB GetItem Movies |
S3 PutObject bucket |
| Node.js |
SELECT FROM table_name UPDATE table_name |
SET |
db.collection.command e.g. elasticapm.test.insert, system.$cmd.ismaster |
Transaction name: [opName] queryNames, ... (/path) Span name: GraphQL: [opName] queryNames, ... (see note below) |
Elasticsearch: ${method} ${path} e.g. Elasticsearch: POST /myIndex*/_search |
Not yet implemented |
Not yet implemented |
| PHP |
SELECT FROM table |
Not supported yet |
Not supported yet |
Not supported yet |
Not supported yet |
Not supported yet |
Not supported yet |
| Python |
SELECT FROM table |
SET |
db.collection.drop |
NA |
ES GET /myindex/_search |
DynamoDB Query tableName |
S3 PutObject bucket |
| Ruby |
SELECT FROM table |
SET |
db.collection.drop |
NA (outgoing) |
GET _search |
DynamoDB Query tableName |
S3 CreateBucket bucket-name |
The spec includes prefixed names like:
DynamoDB UpdateItem my_table
S3 GetObject my-bucket
Elasticsearch: GET /index/_search
Choose one of the followings:
Messaging
The spec defines naming convention that contains lots of prefixing.
Kafka is not represented in the spec and in Java it is really bad (100% my fault 🤦♂️ ) - a combination of API-based for send spans and prefix-based for receive spans. This is because we don't really have an API in the Kafka client for a retrieval of one record, there is only API for reading a batch, which is not a good fit for transaction name that is based on a single record.
OpenTelemetry messaging spec for reference.
Existing state:
| Agent |
Kafka |
RabbitMQ |
SQS |
SNS |
Other |
| Java |
Send spans:
KafkaProducer#send to MyTopic Transactions: Kafka record from MyTopic |
RabbitMQ RECEIVE from MyQueue |
NA |
NA |
JMS SEND to MyQueue |
| .NET |
|
|
|
|
|
| Go |
NA |
NA |
SQS SEND to queue |
SNS PUBLISH myTopic |
NA |
| Node.js |
Not supported |
Not supported |
SQS SEND to queue_name
SQS RECEIVE from queue_name
SQS DELETE from queue_name |
Not supported |
NA |
| PHP |
Not supported yet |
Not supported yet |
Not supported yet |
Not supported yet |
Not supported yet |
| Python |
|
|
|
|
|
| Ruby |
NA |
NA |
SQS SEND to my-queue |
SNS PUBLISH to MyTopic |
NA |
Choose one of the followings:
- With prefix, e.g.
Kafka send to MyTopic
- General form, human-readable, e.g.
Record send to MyTopic or Message received from MyQueue
- General form, OTel scheme:
<destination_name> <operation_name>, e.g. MyTopic send or MyQueue receive 👍 👍
- API-based names, e.g.
MeassgeProducer#send *
- Other (replace with your suggestion and add a +1)
* Note: it is common in messaging clients that the receive API is designed for batches, in which case the API cannot be used as is for the transaction name. So if you choose this option, propose a name for such transactions.
gRPC
The spec defines to used the method as the name, eg: /helloworld.Greeter/SayHello.
Since this is a fairly new spec that was approved lately, I am assuming that everybody is happy with it.
Aligning span names
This is the initial step towards aligning span names across agents.
Naturally, it only deals with frameworks that are not language-specific. We have specs for those, but in some cases, these specs were added in retrospect, reflecting the naming-chaos at the time, so we may want to revisit.
@elastic/apm-agent-devs Please take the time to fill some examples in the tables and vote wherever there is a
sign - either add 👍 to an existing option, or add a new one with your 👍 on it.
After I gather your feedback, I will make the spec PRs accordingly wherever required.
OpenTelemetry general Span guidelines for reference.
HTTP
The naming scheme for transactions is not rigid in the existing spec. It is more so for spans, where names should have the format
<method> <host>.OpenTelemetry HTTP spec for reference.
Existing state:
GET unknown routeServletClassName#doGetGET /testWithPathMethod/{id}GET 127.0.0.1GET [::1]GET localhostGET unknown routeGET /hello/:nameGET /hello/{name}GET host:portGET unknown route(vanilla HTTP server)GET /hello/:name(typical with frameworks)static file(if using express.static())CORS preflight(CORS preflight req with hapi framework)POST localhost:9200/myIndex*/_search(full URL usage is elastic/apm-agent-nodejs#2067)GET http://localhost:52394/sub(http2, same issue)GET /users/{id}POST example.comGET /users/{id}(only for frameworks that expose the necessary routing info )
POST example.comPostsController#index(most likely)GET /users/:idPOST /publishRack(last resort)POST example.comGET elastic.coDB
The spec defines a convention for each DB type.
OpenTelemetry DB spec for reference.
Existing state:
SELECT FROM tableSETdb.collection.dropElasticsearch: GET /index/_searchSELECT FROM tableSET(flush pipeline)${collection}.${command}aggregateElasticsearch: GET /index/_searchDynamoDB GetItem MoviesS3 PutObject bucketSELECT FROM table_nameUPDATE table_nameSETdb.collection.commande.g.elasticapm.test.insert,system.$cmd.ismaster[opName] queryNames, ... (/path)Span name:
GraphQL: [opName] queryNames, ...(see note below)
Elasticsearch: ${method} ${path}e.g.Elasticsearch: POST /myIndex*/_searchSELECT FROM tableSELECT FROM tableSETdb.collection.dropES GET /myindex/_searchDynamoDB Query tableNameS3 PutObject bucketSELECT FROM tableSETdb.collection.dropGET _searchDynamoDB Query tableNameS3 CreateBucket bucket-nameThe spec includes prefixed names like:
DynamoDB UpdateItem my_tableS3 GetObject my-bucketElasticsearch: GET /index/_searchsubtypein waterfall)Messaging
The spec defines naming convention that contains lots of prefixing.
Kafka is not represented in the spec and in Java it is really bad (100% my fault 🤦♂️ ) - a combination of API-based for send spans and prefix-based for receive spans. This is because we don't really have an API in the Kafka client for a retrieval of one record, there is only API for reading a batch, which is not a good fit for transaction name that is based on a single record.
OpenTelemetry messaging spec for reference.
Existing state:
KafkaProducer#send to MyTopicTransactions:
Kafka record from MyTopicRabbitMQ RECEIVE from MyQueueJMS SEND to MyQueueSQS SEND to queueSNS PUBLISH myTopicSQS SEND to queue_nameSQS RECEIVE from queue_nameSQS DELETE from queue_nameSQS SEND to my-queueSNS PUBLISH to MyTopicKafka send to MyTopicRecord send to MyTopicorMessage received from MyQueue<destination_name> <operation_name>, e.g.MyTopic sendorMyQueue receive👍 👍MeassgeProducer#send** Note: it is common in messaging clients that the receive API is designed for batches, in which case the API cannot be used as is for the transaction name. So if you choose this option, propose a name for such transactions.
gRPC
The spec defines to used the method as the name, eg:
/helloworld.Greeter/SayHello.Since this is a fairly new spec that was approved lately, I am assuming that everybody is happy with it.