This servlet filter, for each incoming request:
- decodes incoming
x-request-id
header into traceId and parentId - generates UUID4 for transactionId
- generates UUID4 for spanId
- encodes traceId and spanId into outgoing
x-request-id
header
Why? To support Elastic Common Schema's tracing fields in tomcat9.
The following sequence diagram (install this browser extension to render the diagram because github does not support mermaid natively) explains how these tracing fields are used.
Essentially, the guidelines for using the tracing fields are:
- incoming external requests are assigned a traceId and a transactionId
- outgoing internal requests are assigned a spanId which is encoded into the outgoing
x-request-id
along with traceId - incoming internal requests are assigned a transactionId and the incoming
x-request-id
header is parsed for traceId and parentId (parent's spanId) - traceId is propagated throughout the stack to group logging events
- logging events must include traceId, parentId, and transactionId
where the above uses a single request header, x-request-id
to transport values through the tech
stack.
Finally, in the diagram below, strings such as "T2S1" might lead one to conclude that they include the value of T2. Not so. Each of these is just another UUID4 and "T2S1" is used as a short string for use in the diagram. (Perhaps using random short strings is more appropriate. - TODO)
%%{
init: {
"theme": "base",
"themeVariables": {
"primaryColor": "#59616d",
"secondaryColor": "#59616d",
"primaryTextColor": "#7c702f",
"actorTextColor": "#ffffff",
"noteBkgColor": "#59616d",
"noteTextColor": "#ffffff"
}
}
}%%
sequenceDiagram
# external request is assigned a trace.id
# incoming requests are assigned a transaction.id
# outgoing requests are assigned a span.id
autonumber
participant A as client<br/>(browser)
participant B as web server<br/>(apache)
participant C as asset cache<br/>(varnish)
participant D as app server<br/>(tomcat)
participant E as application
participant F as api
participant G as database
activate A
A->>+B: external request<br/>x-request-id: X|null
note over B: trace.id = UUID<br/>parent.id = X|null<br/>transaction.id = T1
note over B: span.id = T1S1
B->>+C: internal request<br/>x-request-id: UUID.T1S1
note over C: trace.id = UUID<br/>parent.id = T1S1<br/>transaction.id = T2
C->>-B: internal response<br/>x-request-id: UUID.T1S1
note over B: span.id = T1S2
B->>+D: internal request<br/>x-request-id: UUID.T1S2
note over D: trace.id = UUID<br/>parent.id = T1S2<br/>transaction.id = T3
note over D: span.id = T3S1
D->>+E: internal request<br/>x-request-id: UUID.T3S1
note over E: trace.id = UUID<br/>parent.id = T3S1<br/>transaction.id = T4
note over E: span.id = T4S1
E->>+F: internal request<br/>x-request-id: UUID.T4S1
note over F: trace.id = UUID<br/>parent.id = T4S1<br/>transaction.id = T5
note over F: span.id = T5S1
F->>+G: internal request<br/>x-request-id: UUID.T5S1
note over G: trace.id = UUID<br/>parent.id = T5S1<br/>transaction.id = T6
G->>-F: internal response<br/>x-request-id: UUID.T5S1
note over F: span.id = T5S2
F->>+G: internal request<br/>x-request-id: UUID.T5S2
note over G: trace.id = UUID<br/>parent.id = T5S2<br/>transaction.id = T7
G->>-F: internal response<br/>x-request-id: UUID.T5S2
F->>-E: internal response<br/>x-request-id: UUID.T4S1
note over E: span.id = T4S2
E->>+F: internal request<br/>x-request-id: UUID.T4S2
note over F: trace.id = UUID<br/>parent.id = T4S2<br/>transaction.id = T8
note over F: span.id = T8S1
F->>+G: internal request<br/>x-request-id: UUID.T8S1
note over G: trace.id = UUID<br/>parent.id = T8S1<br/>transaction.id = T9
G->>-F: internal response<br/>x-request-id: UUID.T8S1
note over F: span.id = T8S2
F->>+G: internal request<br/>x-request-id: UUID.T8S2
note over G: trace.id = UUID<br/>parent.id = T8S2<br/>transaction.id = T10
G->>-F: internal response<br/>x-request-id: UUID.T8S2
F->>-E: internal response<br/>x-request-id: UUID.T4S2
E->>-D: internal response<br/>x-request-id: UUID.T3S1
D->>-B: internal response<br/>x-request-id: UUID.T1S2
B->>-A: external response<br/>x-request-id: X|null
deactivate A