Open JBAhire opened 3 years ago
I have started looking into this.
Following is the information I could gather around the changes we might need for the implementation to go through.
Currently the following attributes are sent as Trace
related attributes
.
[
{
"name": "startTime",
"displayName": "Start Time",
"type": "LONG",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "duration",
"displayName": "Duration",
"type": "LONG",
"scope": "API_TRACE",
"units": "ms",
"onlySupportsAggregation": true,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG",
"AVGRATE",
"PERCENTILE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "apiTraceErrorSpanCount",
"displayName": "Api Trace Error Span Count",
"type": "LONG",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "protocol",
"displayName": "Protocol",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "statusCode",
"displayName": "Status Code",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "requestMethod",
"displayName": "HTTP Method",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "tags",
"displayName": "Tags",
"type": "STRING_MAP",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "apiDiscoveryState",
"displayName": "Endpoint Discovery State",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "apiExitCalls",
"displayName": "Api Exit Calls",
"type": "LONG",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "statusMessage",
"displayName": "Status Message",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "userAgent",
"displayName": "User Agent",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "spaceIds",
"displayName": "Space IDs",
"type": "STRING_ARRAY",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "calls",
"displayName": "Calls",
"type": "LONG",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": true,
"supportedAggregations": [
"COUNT",
"AVGRATE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "apiBoundaryType",
"displayName": "Endpoint Boundary Type",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "errorCount",
"displayName": "Error Count",
"type": "LONG",
"scope": "API_TRACE",
"units": "Errors",
"onlySupportsAggregation": true,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG",
"AVGRATE",
"PERCENTILE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "status",
"displayName": "Status",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "apiName",
"displayName": "Endpoint Name",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "apiCalleeNameCount",
"displayName": "Api Callee Name Count",
"type": "STRING_MAP",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "requestUrl",
"displayName": "URL",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "traceId",
"displayName": "Trace ID",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "endTime",
"displayName": "End Time",
"type": "LONG",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "apiTraceId",
"displayName": "Endpoint Trace ID",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "serviceName",
"displayName": "Service Name",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "apiId",
"displayName": "Endpoint ID",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "serviceId",
"displayName": "Service ID",
"type": "STRING",
"scope": "API_TRACE",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
}
]
And the following are Span
related attributes.
[
{
"name": "id",
"displayName": "Span ID",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "type",
"displayName": "Span Type",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "statusCode",
"displayName": "Status Code",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "spaceIds",
"displayName": "Space IDs",
"type": "STRING_ARRAY",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "traceId",
"displayName": "Trace ID",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "serviceName",
"displayName": "Service Name",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "duration",
"displayName": "Duration",
"type": "LONG",
"scope": "SPAN",
"units": "ms",
"onlySupportsAggregation": true,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG",
"AVGRATE",
"PERCENTILE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "parentSpanId",
"displayName": "Parent Span ID",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "displaySpanName",
"displayName": "Span Name",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "startTime",
"displayName": "Start Time",
"type": "LONG",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "endTime",
"displayName": "End Time",
"type": "LONG",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "spanTags",
"displayName": "Tags",
"type": "STRING_MAP",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "apiName",
"displayName": "Endpoint Name",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "apiId",
"displayName": "Endpoint ID",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "exceptionCount",
"displayName": "Exception Count",
"type": "LONG",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": true,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG",
"AVGRATE",
"PERCENTILE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "displayEntityName",
"displayName": "Entity Name",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "spanRequestMethod",
"displayName": "HTTP Method",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "spanRequestUrl",
"displayName": "URL",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "apiTraceId",
"displayName": "Endpoint Trace ID",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "errorCount",
"displayName": "Error Count",
"type": "LONG",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": true,
"onlySupportsGrouping": false,
"supportedAggregations": [
"SUM",
"MIN",
"MAX",
"AVG",
"AVGRATE",
"PERCENTILE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "protocolName",
"displayName": "Protocol",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "serviceId",
"displayName": "Service ID",
"type": "STRING",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [
"DISTINCTCOUNT"
],
"groupable": true,
"__typename": "AttributeMetadata"
},
{
"name": "spans",
"displayName": "Spans",
"type": "LONG",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": true,
"supportedAggregations": [
"COUNT",
"AVGRATE"
],
"groupable": false,
"__typename": "AttributeMetadata"
},
{
"name": "spanRequestParams",
"displayName": "Request Params",
"type": "STRING_MAP",
"scope": "SPAN",
"units": "",
"onlySupportsAggregation": false,
"onlySupportsGrouping": false,
"supportedAggregations": [],
"groupable": false,
"__typename": "AttributeMetadata"
}
]
The logic for explorer dashboard as well as navigation on click of the filter is based upon the same attributes.
Now, because the names of the attribute
are difference for span
and trace
tab in the explorer, the filter with a different name doesn't retain it's value which is causing https://github.com/hypertrace/hypertrace-ui/issues/1249. If the service responsible for sending the attributes can ensure that the same names are used for the filters used in both span
view and trace
view in explorer view and everywhere else, both of these issues will be solved.
One example for the difference in name.
For Trace
tab, we call HTTP Method
as requestMethod
, but for Span
tab, we call it spanRequestMethod
in the filter.
@aaron-steinfeld @anandtiwary @itssharmasandeep @jyothishjose6190
Wanted to know your thoughts on the same.
The logic for explorer dashboard as well as navigation on click of the filter is based upon the same attributes.
I think this is the fundamental misunderstanding. The attributes aren't the same. There is some overlap, and there may be a few attributes which overlap exactly in meaning but have different names (these are defined via config in https://github.com/hypertrace/config-bootstrapper/tree/main/config-bootstrapper/src/main/resources/configs/config-bootstrapper/attribute-service), but changing these names directly isn't really feasible since it would break existing queries (we could do some extra effort to make it compatible, but not sure it's worth it). Other attributes in both scopes are just exclusive to one scope or the other, so we should never operate under the assumption that a mapping can always be made.
So as far as #1250 is concerned, we should be drilling into the scope we started from. If we're viewing a span attribute, we should be going to the span explorer; if viewing a trace attribute, trace explorer. No attempt at mapping should be done here (nor is necessary). For #1249 , we should be doing a best effort and mapping where there's an exact match (I thought this was the existing behavior, but would have to check). If there are particular attributes of concern that have a counterpart with a different name, let's enumerate those and see what our options are to align them (the two that come to mind are either adding an alias on the backend, or maintaining a dictionary on the UI - neither is great).
Hey @aaron-steinfeld , I did a comparison for all the attributes and came up with the below table.
Field | Trace Filter Name | Span Filter Name |
---|---|---|
Span ID | - | id |
Span Name | - | displaySpanName |
Span Type | - | type |
Parent Span ID | - | parentSpanId |
Exception Count | - | exceptionCount |
Entity Name | - | displayEntityName |
Request Params | - | spanRequestParams |
HTTP Method | requestMethod | spanRequestMethod |
Protocol | protocol | protocolName |
URL | requestURL | spanRequestUrl |
Tags | tags | spanTags |
Status Code | statusCode | statusCode |
Space IDs | spaceIds | spaceIds |
Service ID | serviceId | serviceId |
Trace ID | traceId | traceId |
Service Name | serviceName | serviceName |
Duration | duration | duration |
Start Time | startTime | startTime |
End Time | endTime | endTime |
Error Count | errorCount | errorCount |
Endpoint Name | apiName | apiName |
Endpoint ID | apiId | apiId |
Endpoint Trace ID | apiTraceId | apiTraceId |
Api Trace Error Span Count | apiTraceErrorSpanCount | - |
Endpoint Discovery State | apiDiscoveryState | - |
Endpoint Boundary Type | apiBoundaryType | - |
Api Callee Name Count | apiCalleeNameCount | - |
Api Exit Calls | apiExitCalls | - |
Status Message | statusMessage | - |
User Agent | userAgent | - |
Calls | calls | - |
Status | status | - |
As of now I could find 4 fields which have different names - HTTP Method
, Protocol
, URL
, Tags
.
The table above gives information about both mutually exclusive fields, as well as fields with different name which is present for both views.
I think the next question is about how to approach the same? Given the number of fields with different name (4), we can choose to update the id
of such fields from service side, or send along some extra metadata along with each field which helps the UI to do the conversion on the fly. Like an additional field like alternateId
or something of the kind. The UI might need to do some rework on the response to compute the object.
Thanks for putting together the list @jaywalker21 . So the options I see and their pros/cons:
Given the options, I think I'd suggest the first approach. It's the quickest to implement - a single PR likely under 50 lines, and how the smallest surface area since nothing is downstream of the change. If we need to unwind it for whatever reason, trivial to do so. What do you think?
Hi @aaron-steinfeld, Below are my thoughts around each of the options
Option 1
Will be quite easy to do from implementation perspective. Just feels a little wrong from design perspective given how everything is designed (config driven). But, we can take this approach for now and think around moving any meta info/config to backend in the future if a need arises. The only downside, as you mentioned is the hardcoded values that the code will maintain.
Option 2
Is there any way to check for the internal references of the query/URL? From the user base perspective, if there is a lot of reuse/bookmarking of the URLs, then this approach isn't feasible now.
Option 3
I think it's a lot of overhead to maintain and carry out on the browser. For every filter being applied, it might require an iteration, which again isn't ideal from performance perspective too. It will also considerably reduce the readability of the code.
Option 4
This option is very close to Option 2
and will not want to move ahead with this for the same reasons.
I think it would be better to go with Option 1
for now. We can revisit if need be in the future, but this looks the most suitable approach for the time being.
Use Case
Current implementation of attribute based drill down always redirects to Trace tab of explorer with tag filter applied. But as some of the attributes don't exist in trace scope it shows no data. We should check the scope of attribute and then redirect accordingly.
Proposal
As there will always be data in span context, it make more sense to always go to Spans tab in that case.
Questions to address (if any)