Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganizes content to reflect decisions made since last workshop #72

Merged
merged 2 commits into from
Mar 12, 2018

Conversation

codefromthecrypt
Copy link

The following is an "all-in-one" change to capture the essence of changes
described since the February workshop. Notably, this includes:

  • lowercase concatenation naming convention (ex traceparent)
  • applied description of the multiple trace states

As the two headers are tightly coupled, this places them in the same document.

This is done as one change as there is pressure for folks to do implementations
and so far very few changes have actually taken place. By spiking a review to
integrate feedback, we are more likely to have interoperable implementations
without accidentally implementing old versions of the standard. Please take this
practical concern into consideration when reviewing.

Fixes #57

The following is an "all-in-one" change to capture the essence of changes
described since the February workshop. Notably, this includes:

* lowercase concatenation naming convention (ex `traceparent`)
* applied description of the multiple trace states

As the two headers are tightly coupled, this places them in the same document.

This is done as one change as there is pressure for folks to do implementations
and so far very few changes have actually taken place. By spiking a review to
integrate feedback, we are more likely to have interoperable implementations
without accidentally implementing old versions of the standard. Please take this
practical concern into consideration when reviewing.

Fixes #57
Single header:

```
tracestate: parent_application_id = 123
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self-note: this example is crap

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yanked

This document provides rationale for the decisions made, mapping the
`Trace-Parent` and `Trace-State` fields to HTTP headers.

## Lowercase Concatenated header names
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new content

- It is expected that the typical name will be a single word in latin and the value will be a
short string in latin or a derivative of an url.

### Field name without value
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new content

@codefromthecrypt
Copy link
Author


## Header value

`name1[=value1[;properties1]],name2[=value2[;properties2]]`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to represent vendor-specific "golden copy"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. will adjust the example though I think we should remove any notion of nested encoding for now. I don't think we will want to mix atoms and molecules (ex atom being some random property and molecule being opaque trace state for amazon)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think =value1[;properties1] looks like an encode format to me, which I am not sure whether others agree. In another words, should value end with , and start with = be good enough?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that this feels a bit too open to misinterpretation. Not sure what the best way to represent it here is, but ultimately readers should get the hint that this is vendorName1=opaqueValue1,vendorName2=opaqueValue2.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ripped out the copy/pasted stuff from correlation context

Copy link

@tylerbenson tylerbenson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great. I appreciate the move to lower case+concat to improve interop with MQ's.

It might be nice to see some additional examples with variations, for example multiple different vendors in tracestate. If we get a rich enough set of examples with edge cases, that would feed well into a compatibility test suite later.

is only one trace graph and that is from the Congo service:

```
trace-parent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
Copy link

@tylerbenson tylerbenson Mar 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove - character in name to reflect new name (below too).

@codefromthecrypt
Copy link
Author

Had an offline discussion with @tylerbenson which was good as he wasn't at the workshop (except remote), which helped flesh out some things to address.

There's certainly one of those things here, with this PR, which is priority. I think there's very high priority completely breaking the old spec based on the discussion with 30people over 2 days in feb. We need to do that so people stop implementing the old thing. OTOH, fleshing out everything including protocol in a single pull request will put it at risk. Here's some things I think from the chat with Tyler, I can work into this one.

  • Gold Copy is confusing
    Right now, we mention gold copy is in tracestate. This is jargony and should try a different way. A description that a vendor places their state in the tracestate field is also not enough, as even if we have a rationale field, it is too mysterious. We need an example of multi-vendor to describe this.

  • Suggest base64 or otherwise not KV pairs for trace-state values
    Especially because text formatting stuff is in rationale, we anchor towards a global dict of state. Ex that dd's entry is a list of key value pairs, maybe someone should append trace-parent into. However, It was very clear in the workshop that vendors do not want other vendors affecting their state willy nilly, or a chance of overlap etc. It was suggested some vendors will publish their format (amazon for example), but that at a base level the trace states are opaque. I'd suggest we firmly say the value field is base64 or something that isn't a nested list of fields. I think we can do so in an example, or maybe a rationale entry which shows the clash risk

  • Include a A->B->C example directly in the text
    Showing moving from one provider to another is unfortunately something that can really belabor this pull request. However a basic example of multi-hop can help even if we add a TODO or REVISIT section if there's something tension about it. Again, the goal is to move closer to what we discussed without stalling endlessly on work that few are helping with.


## Header value

`name1[=value1[;properties1]],name2[=value2[;properties2]]`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think =value1[;properties1] looks like an encode format to me, which I am not sure whether others agree. In another words, should value end with , and start with = be good enough?


## Relationship between the headers

The `tracestate` header is not an extension of the data in `traceparent`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is not an extension is totally clear to me, but, I have to say, for new guys join this community, they will have no clue about where does this come from. The specification document should stay in the recent status. We may provide a CHANGELOG to describe the changes.


## Value format

Value starts after equal sign and ends with the special character `;`, separator `,` or end of string. Value represents a url encoded string and case sensitive. Spaces are allowed in the beginning and the end of the value. Value with spaces before and after MUST be considered identical to the trimmed value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does most people agree about this format of state.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose or benefit of including semicolon ; as a value-ending character? Can we (or should we) just ignore it and say that commas , and end-of-string are the only things that end a value?

I guess I'm assuming that "value" in this context means the entire opaque vendor-specific trace state, and since it's opaque they could use ; if they want to but by itself it has no special meaning and should therefore not be called out - is that the case or am I misunderstanding?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also implicit in here that the value-ending characters (e.g. ,) are therefore reserved and should not be used in a vendor's opaque trace state value, but might be worth explicitly calling it out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done (the old formatting was unnecessary in opaque, but restricted characters are)

For example, the following:
```
trace-parent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
trace-state: yelp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should demo about trace-state without value, but with other vendor/product value.

Such as:

trace-state: yelp,alpha=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed special case

* `Trace-State` maps all graphs the incoming parent is a part of in potentially vendor-specific formats. For example, if an ancestor of this request was in a different trace, there will be a separate entry for the last position it was in that trace graph.

Notably, the `Trace-State` field is unreliant on data in the `Trace-Parent`,
except if the direct upstream is fully described by `Trace-Parent`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something here, but how could a user tell whether the "direct upstream is fully described by Trace-Parent"? Specially in the case of having more than one trace graph involved.

Also, in the case of multiple trace graphs is there any rule regarding which of the identifiers should stay in the traceparent header? Are implementors allowed to "move" a different set of identifiers between the parent and state headers? e.g. traceparent has yelp-generated identifiers but as soon as it crosses to another vendor, they might want to propagate yelp's identifiers in tracestate and have their own in traceparent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the ability to split across headers (as this was copy/paste from correlation context) and opened an issue in case folks want to revisit later #80

@codefromthecrypt
Copy link
Author

codefromthecrypt commented Mar 6, 2018 via email

`name1[=value1[;properties1]],name2[=value2[;properties2]]`

**Limits:**
Maximum length of a combined header MUST be less than 512 bytes.
Copy link

@nicmunroe nicmunroe Mar 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a deferred/todo thing, but at some point we might want to define recommended behavior for when you can't add your vendor's state to the header because it would put it over 512 bytes. Find the biggest offender and drop it on the floor? Find the oldest one and drop it (probably not possible to determine oldest one)? Throw everything on the floor and start fresh with just your vendor state?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be part of the processing model and needs to be defined explicitly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theres already a TODO, which preceded this. lifecycle isn't well defined yet and too much to do in one PR, but good note


Value starts after equal sign and ends with the special character `;`, separator `,` or end of string. Value represents a url encoded string and case sensitive. Spaces are allowed in the beginning and the end of the value. Value with spaces before and after MUST be considered identical to the trimmed value.

## Properties

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on other comments and my own personal opinion, I'd favor chopping this entire Properties section and just call out that the vendor value is opaque and vendors can do whatever they want as long as they don't use value-ending characters (e.g. ,) or otherwise violate the RFC 7230 spec.

I'd also be perfectly happy with @adriancole's suggestion that maybe the vendor value should be explicitly base64 rather than free-for-all. I might even prefer that - it means some extra work when parsing/extracting your trace graph, but it could seriously reduce confusion and misinterpretation when humans visually look at a tracestate header and try to understand it without reading this specification.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And that confusion/misinterpretation is inevitable when key=val pairs are embedded everywhere in a large header value.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@AloisReitbauer
Copy link
Contributor

Honestly, I find it weird to describe the header format in plain English. We should use EBNF syntax to describe it. As an example look at the grammar for the HTTP Cookie header

...
cookie-date = *delimiter date-token-list delimiter
date-token-list = date-token ( 1delimiter date-token )
date-token = 1
non-delimiter

delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E
non-delimiter = %x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF
non-digit = %x00-2F / %x3A-FF

day-of-month = 1*2DIGIT ( non-digit *OCTET )
month = ( "jan" / "feb" / "mar" / "apr" /
"may" / "jun" / "jul" / "aug" /
"sep" / "oct" / "nov" / "dec" ) OCTET
year = 2
4DIGIT ( non-digit *OCTET )
time = hms-time ( non-digit OCTET )
hms-time = time-field ":" time-field ":" time-field
time-field = 1
2DIGIT
...

ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
```

There is one exception to the "gold copy" rule, which is when the incoming
Copy link

@nicmunroe nicmunroe Mar 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @adriancole on moving this generic case section elsewhere. I think there is some good potential value in the option, but I'm not sure the benefit outweighs the cost at the moment. The costs as I see it:

  • It adds to the cognitive load required to understand the spec, and is not required for successful execution of an impl (i.e. if nobody does this then the spec still works).
  • In order for this to work an impl needs to recognize when the incoming generic case is not compatible with their tracing system, and when they see an incompatibility they must do something special or else the trace graph of the vendor using the generic case is busted. The "something special" is copying the traceparent value into the generic vendor's state. e.g. in this case my tracing system would have to set tracestate: mystuff=someOpaqueValue,yelp=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01 (possibly base64-ing it if we decide that's required for the opaque vendor payload values). If I fail to do that copy, then the next time a yelp system sees this trace context they will not be able to resume correctly - their trace graph will be broken and probably unfixable.
  • The above issue is tricky to explain and potentially easy to goof up. It increases the complexity of an impl and goes against the general ethos we seemed to agree on in the workshop that you shouldn't mess with another vendor's gold copy. And when someone does goof up it means breaking other vendors' trace graphs.

For these reasons I'd recommend tabling this feature/option for now, and focus on the bare minimum to allow the spec to reach its goals. The less moving parts and the simpler it is, the higher likelihood of success IMO. Like I said I do think there's value here and it's worth revisiting, I just don't think it needs to be here right now. Unless we think it needs to be now or never, in which case it's probably worth discussing further.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


* `Trace-Parent` describes the position of the incoming request in its trace graph in a portable, fixed-length format. Its design focuses on fast parsing.

* `Trace-State` maps all graphs the incoming parent is a part of in potentially vendor-specific formats. For example, if an ancestor of this request was in a different trace, there will be a separate entry for the last position it was in that trace graph.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble parsing the first sentence here. I think it could benefit from a rewording. I'd suggest something but I'm not sure exactly what it's trying to say.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reworded

@codefromthecrypt
Copy link
Author

working in feedback now. Thanks folks

@codefromthecrypt
Copy link
Author

by the way I am not going to endlessly work things in. I am going to work in as much as I can. we can decide whether to merge things or not, then raise a PR. blocking on perfection such as nailing EBNF is not something I'll be doing in this PR

@codefromthecrypt
Copy link
Author

ok I updated based on the feedback, with two followups for a future work. I'm kindly asking to find way to merge this and only put blocking comments as again.. we are in a position of holding up everyone.

Here are the followups

Copy link
Contributor

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AloisReitbauer AloisReitbauer merged commit 41f9405 into master Mar 12, 2018
@SergeyKanzhelev SergeyKanzhelev deleted the reorg branch August 23, 2018 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants