-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
analyze: Add "timespan" command to dump time span in usec #10411
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
Conversation
4b0f2eb to
5fcb2cb
Compare
|
Shouldn't the output show both the time in raw µs (as your patch does it) and normalized in pretty printed way? (i.e. with format_timestamp())? I am a bit puzzled why this takes two arguments? I mean "systemd-analyze timespan 5 s" is the same as "systemd-analyze timestamp 5s" in this way, no? hence why have it at all? sounds like the second argument shouldn't really be there if we parse it from user passed data anyway, because then it's really redundant, as the user might just add the unit to the first argument instead and things are much simpler then |
src/analyze/analyze.c
Outdated
|
|
||
| if (argc == 3) { | ||
| char **multiplier = argv + 2; | ||
| extract_multiplier(*multiplier, &default_unit); |
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.
this would be a bit sloppy, because specifiyng "sec foobarxxxxyzzzz" would be parsed cleanly, even though it really shouldn't...
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 this one, do you have a suggestion on how the multiplier specification should be handled if it is to be kept? That is, as you mention, I notice that extract_multiplier currently has no way to return match/no match status because currently in the way it interacts with parse_time it doesn't have to, but in this case to avoid this I think we have to know whether we actually matched something by returning int and changing the return to happen as a mutable argument, perhaps?
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.
(Also, I was somewhat surprised that extract_multiplier checks "starts with" instead of doing direct equality matching.)
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.
well, extract_multipler() is an internal call so far, that is used exclusively while we iteratively parse a time specification. i.e. when we parse a string such as "5s 153ms 5us" we use it to parse the "s", the "ms" and the "us", and each time we need to continue parsing right after, hence it works the way it works, that it uses startswith() and returns where we left of.
That said, I am still not convinced that specifying the default unit is really useful. Where's the benefit of being able to write "5" "s" in two arguments rather than requiring "5s" in one?
src/analyze/analyze.c
Outdated
| r = parse_time(*input_timespan, &output_usecs, default_unit); | ||
| if (r < 0) { | ||
| ret = log_error_errno(r, "Failed to parse time span '%s': %m", *input_timespan); | ||
| return ret; |
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 use "ret" here instead of returning log_error_errno() directly?
src/analyze/analyze.c
Outdated
|
|
||
| printf("%" PRIu64 "\n", output_usecs); | ||
|
|
||
| return ret; |
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 drop "ret" entirely, and instead do "return EXIT_SUCCESS" here?
|
Agreed with all the points, thanks. Only a couple of things to clarify:
What if one wants to debug (as an example) a directive with an implied default unit magnitude? Then one no longer can copy and paste and think about the default unit separately, but they have to find the default unit and manually edit it in. This isn't a massive deal, but seems non-ideal. I think the current approach avoids the pitfalls of each approach individually since you can also do this now just by doing what you said and not having to pass any unit magnitude, but you can also do it the other way if you prefer to not have to find/edit in the magnitude directly.
Sure, I'll add that. |
hmm, example? i mean, if i want to check what "565" means on an configuration item that uses "us" as default unit. So with your current proposal i could write that as or we could even take it one notch further: if multiple arguments are specified, let's just strv_join() them, i.e. so that |
|
Ah, wait, you're right. Since only the last number can be the one without a unit, it makes no difference at all. In which case maybe we should even ban numbers without any unit specified from this. I'll make the changes. |
a3957b2 to
b0860e0
Compare
|
I believe all comments are now resolved. :-) |
39bd9f2 to
ec7bf58
Compare
poettering
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.
looks pretty good already, but some points
man/systemd-analyze.xml
Outdated
|
|
||
| <para><command>systemd-analyze timespan</command> parses a time span and outputs the equivalent value in microseconds. | ||
| The time span should adhere to the same syntax documented in <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. | ||
| Values without associated magnitudes are parsed as microseconds.</para> |
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.
almost all our time settings default to second magnitude. I think this should too, to be least surprising.
src/analyze/analyze.c
Outdated
| char ft_buf[FORMAT_TIMESPAN_MAX]; | ||
|
|
||
| STRV_FOREACH(input_timespan, strv_skip(argv, 1)) { | ||
| r = parse_time(*input_timespan, &output_usecs, usec_magnitude); |
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.
Please follow CODING_STYLE, indentation by multiples of 8ch only
src/analyze/analyze.c
Outdated
| r = parse_time(*input_timespan, &output_usecs, usec_magnitude); | ||
| if (r < 0) { | ||
| return log_error_errno(r, "Failed to parse time span '%s': %m", *input_timespan); | ||
| } |
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.
please follow CODING_STYLE, no {} around single-line if blocks, please
src/analyze/analyze.c
Outdated
| int r; | ||
| char **input_timespan; | ||
| usec_t usec_magnitude = 1, output_usecs; | ||
| char ft_buf[FORMAT_TIMESPAN_MAX]; |
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.
please move all variables only used in the loop into the loop. We usually define all variables at the innermost scope they are used (though r is usually defined on the outermost, given that we pretty much always have that, as it is our usual variable for storing return codes that might be errors)
src/analyze/analyze.c
Outdated
| } | ||
|
|
||
| printf("Original: %s\n", *input_timespan); | ||
| printf(" μs: %" PRIu64 "\n", output_usecs); |
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 like the use of unicode, but I figure this needs to be added to the special_glyph() logic, see locale-util.[ch] for details, so that it has an ASCII fallback (µ → u)...
src/analyze/analyze.c
Outdated
| printf(" μs: %" PRIu64 "\n", output_usecs); | ||
| printf(" Human: %s\n", format_timespan(ft_buf, sizeof(ft_buf), output_usecs, usec_magnitude)); | ||
|
|
||
| if (*(input_timespan + 1)) |
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 think if (input_timespan[1]) is a tiny bit more readable, but doesn't matter
This is useful for a couple of cases, I'm mostly interested in case systemd#1: 1. Verifying "reasonable" values in a trivially scriptable way 2. Debugging unexpected time span parsing directly Test Plan: ``` % build/systemd-analyze timespan 20 Original: 20 μs: 20 Human: 20us % build/systemd-analyze timespan 20ms Original: 20ms μs: 20000 Human: 20ms % build/systemd-analyze timespan 20z Failed to parse time span '20z': Invalid argument ```
ec7bf58 to
1d7145f
Compare
|
Thanks, all resolved now I think. |
|
excellent! thanks! lgtm! |
|
i386 test failure looks unrelated: |
|
I'm not sure how to interpret the following output: ./build/systemd-analyze timespan '1111111111111111111y'
Original: 1111111111111111111y
μs: 10816682103480387584
Human: 342759y 11month 2w 6d 8h 8min 387.584msSomething has overflowed somewhere apparently :-) |
|
The command itself is very handy. Thank you! |
That's interesting, because on mine ERANGE is successfully returned from Maybe something in the checks is resulting in UB? |
Summary: Rebase two fixes onto the version merged upstream: systemd/systemd#10507 systemd/systemd#10567 and backport a few more: systemd/systemd#10411 systemd/systemd#10493 systemd/systemd#10757 systemd/systemd#10876 These are almost all cgroup2 related. Reviewed By: cdown Differential Revision: D13351498 fbshipit-source-id: 87c8428d48dbb0eb2ae7d34f7381fff88f83872f
This is useful for a couple of cases, I'm mostly interested in case #1:
Test Plan: