-
Notifications
You must be signed in to change notification settings - Fork 50
telemetry API #271
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
telemetry API #271
Conversation
include/aws/s3/s3_client.h
Outdated
| */ | ||
| struct aws_s3_request_telemetry_metrics { | ||
| /* X-AMZ-REQUEST-ID Header value. */ | ||
| struct aws_byte_cursor request_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we're already passing all the response headers, we don't need this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just want to have a simple way to fetch the request id instead of fetching it from the headers.
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #271 +/- ##
==========================================
+ Coverage 87.52% 87.88% +0.36%
==========================================
Files 16 16
Lines 4103 4316 +213
==========================================
+ Hits 3591 3793 +202
- Misses 512 523 +11
|
| /** | ||
| * Information sent in the meta_request telemetry callback. | ||
| */ | ||
| struct aws_s3_request_metrics { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we expose extra things like num_parts, bytes_transferred?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
num_parts is included in the request_path_query, bytes_transferred can be interesting, but most likely will be the part size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe i dont understand what request_path_query is, but how would it include num parts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For put parts, it will have the part number in it, but, for multipart get, it is not.
I'll add the part number to be easier for the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But, for multipart get, we were actually doing ranged-get, which is different from get parts. I guess it can be confused to the user as well.
include/aws/s3/private/s3_request.h
Outdated
| uint64_t send_end_timestamp_ns; | ||
| /* The time duration for the request from start encoding to finish encoding (send_end_timestamp_ns - | ||
| * send_start_timestamp_ns). When send_end_timestamp_ns is 0, means data not available. */ | ||
| uint64_t sending_duration_ns; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we decide on #271 (comment)? I think it would be nice to be consistent with http layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, the reason we used int64_t to have the data unavailable easy to check, but we provide the getters with error, so I guess it will make more sense for those value to be unsigned, as they should never less than zero.
Co-authored-by: Waqar Ahmed Khan <waahm7@gmail.com>
This reverts commit 70c568d.
Co-authored-by: Waqar Ahmed Khan <waahm7@gmail.com>
include/aws/s3/s3_client.h
Outdated
| AWS_S3_API | ||
| void aws_s3_request_metrics_get_request_path_query( | ||
| const struct aws_s3_request_metrics *metrics, | ||
| struct aws_byte_cursor *out_request_path_query); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial: I would use aws_string for these string properties, instead of aws_byte_cursor/aws_byte_buf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? I think we have the metrics as the object holding all the data, so this is the getter to fetch the data from the object, will it be better to use aws_byte_cursor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aws_string is null-terminated, which makes is easier if the user wants to pass it along to things like printf() or other old-fashioned C calls that expect a null-terminated string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, it is easier to reason about the lifetime of aws_string. With a byte_cursor, users must also ensure that the underlying memory is not freed until the lifetime of the byte_cursor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was still proposing the same sketchy lifetime as we'd get with aws_byte_cursor, where we just give them a pointer to the internal data and warn them about lifetimes
source/s3_request.c
Outdated
| if (metrics->time_metrics.receive_end_timestamp_ns == 0 || metrics->time_metrics.receive_start_timestamp_ns == 0) { | ||
| return aws_raise_error(AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE); | ||
| } | ||
| *receiving_duration = metrics->time_metrics.receiving_duration_ns; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't it be less error_prone to continue storing times as int64_t internally, so we could simply use -1 to indicate date not available?
| if (metrics->time_metrics.receive_end_timestamp_ns == 0 || metrics->time_metrics.receive_start_timestamp_ns == 0) { | |
| return aws_raise_error(AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE); | |
| } | |
| *receiving_duration = metrics->time_metrics.receiving_duration_ns; | |
| if (metrics->time_metrics.receiving_duration_ns < 0) { | |
| return aws_raise_error(AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE); | |
| } | |
| *receiving_duration = (uint64_t)metrics->time_metrics.receiving_duration_ns; |
vs doing this thing where 0 maaay be valid from some values, so we better consult two other values
like we were doing in that "Range: 0-0" bug we just had
include/aws/s3/s3_client.h
Outdated
| /* Get the request ID from aws_s3_request_metrics, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised when data | ||
| * unavailable */ | ||
| AWS_S3_API | ||
| int aws_s3_request_metrics_get_request_id( | ||
| struct aws_allocator *allocator, | ||
| const struct aws_s3_request_metrics *metrics, | ||
| struct aws_string **out_request_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /* Get the request ID from aws_s3_request_metrics, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised when data | |
| * unavailable */ | |
| AWS_S3_API | |
| int aws_s3_request_metrics_get_request_id( | |
| struct aws_allocator *allocator, | |
| const struct aws_s3_request_metrics *metrics, | |
| struct aws_string **out_request_id); | |
| /** | |
| * Get the request ID from aws_s3_request_metrics. | |
| * If unavailable, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised. | |
| * If available, out_request_id will be set to a string. Be warned this string's lifetime is tied to the metrics object. | |
| */ | |
| AWS_S3_API | |
| int aws_s3_request_metrics_get_request_id( | |
| const struct aws_s3_request_metrics *metrics, | |
| const struct aws_string **out_request_id); | |
| // OR return NULL and raise error if unavailable | |
| const struct aws_string *aws_s3_request_metrics_get_request_id( | |
| const struct aws_s3_request_metrics *metrics); |
I wasn't suggesting we allocate a new string every time someone queries, I was suggesting storing these internally as aws_string (instead of aws_byte_buf), and just handing out the pointer from the query
If all this rigamarole about using aws_string instead of aws_byte_cursor is more trouble than it's worth, then just roll back to using aws_byte_cursor. this was a debatable suggestion to begin with
graebm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix & ship
| * Notes: | ||
| * - The callback will be invoked multiple times from different threads. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
including concurrently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
|
|
||
| /** | ||
| * Optional. | ||
| * To get telemetry metrics when a single request finishes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this guaranteed to only be invoked before the finish_callback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
include/aws/s3/s3_client.h
Outdated
| /* Get the part number of the request, if the request is not associated with a part, error code will be raised. */ | ||
| AWS_S3_API | ||
| int aws_s3_request_metrics_get_part_number(const struct aws_s3_request_metrics *metrics, uint32_t *out_part_number); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to get the range of the part for auto-ranged gets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, but the response header should have content-range in it, and covers the range of the part for the request.
I think we can just remove it for now, the part number is confusing for auto-ranged get. And for auto-put we can get the information from the aws_s3_request_metrics_get_request_path_query
| void aws_s3_request_metrics_get_request_path_query( | ||
| const struct aws_s3_request_metrics *metrics, | ||
| const struct aws_string **out_request_path_query); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get the type of request this way (GetObject/HeadObject/UploadPart/etc)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add the type of request in a follow up PR to be more clear
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.