Skip to content

Conversation

@shirou
Copy link
Owner

@shirou shirou commented Jun 7, 2025

#1809 accidentally introduced some of bug on AIX. (see this comment)

This PR fixes it and add , to all of other symbols.

Note: I don't have a AIX machine, so I can not check this works or not.

@shirou
Copy link
Owner Author

shirou commented Jun 7, 2025

@Dylan-M sorry to late fix. But could you check this PR is actually you want? Thanks!

var days, hours, mins uint64
var err error

switch ut[3] {
Copy link
Contributor

@mmorel-35 mmorel-35 Jun 7, 2025

Choose a reason for hiding this comment

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

What do you think about using this :

func clearTime(ut string) string {
    return strings.TrimRight(strings.TrimRight(ut, ","),"s")
}

So you just switch on singular words for "day" or "hr" or "min" ?

Copy link

Choose a reason for hiding this comment

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

I would also agree with this, but it can get messy when ut[5] and ut[7] may or may not exist (you cannot trim them ahead of time).

I don't agree with the function name though. "clearTime" makes it seem like you're removing the time, rather than just trimming a string on the time.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's just a suggestion, everything can be changed. The main goal is to decouple the cleaning of comma and s and then look for the type of time

}
}
case "hr,", "hrs,":
case "hr,", "hrs,", "hr", "hrs":
Copy link

Choose a reason for hiding this comment

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

This case also needs a subcase for mins to be in ut[5], with appropriate protections.

// day provided along with a single hour or hours
// ie: up 2 days, 20 hrs,
if ut[5] == "hr," || ut[5] == "hrs," {
if ut[5] == "hr," || ut[5] == "hrs," ||
Copy link

Choose a reason for hiding this comment

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

This needs a subhandling for mins to be in ut[7], for a case where you have 20 days, 17 hrs, 5 mins

it all of these ifs should likely be exists/nil protected as well, since these array elements will only exist if the returned value previously has enough elements to fill it out this far.

Also both of these if ut[5] should probably be another switch/case statement for consistency.

var days, hours, mins uint64
var err error

switch ut[3] {
Copy link

Choose a reason for hiding this comment

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

I would also agree with this, but it can get messy when ut[5] and ut[7] may or may not exist (you cannot trim them ahead of time).

I don't agree with the function name though. "clearTime" makes it seem like you're removing the time, rather than just trimming a string on the time.

@shirou
Copy link
Owner Author

shirou commented Jun 10, 2025

@Dylan-M Could you provide these uptime examples like in the test? I want to add those to the test.

  • additional commas
  • ut[5] and/or ut[7] is missing

@Dylan-M
Copy link

Dylan-M commented Jun 10, 2025

@Dylan-M Could you provide these uptime examples like in the test? I want to add those to the test.

* additional commas

* ut[5] and/or ut[7] is missing

I can't provide them easily, because it requires getting the system that shows those formats - since they only show when they're non-zero.

Also, to further complicate it, one of my systems outputs uptime like this:

# uptime
  10:58AM   up  22:28,  2 users,  load average: 1.87, 1.96, 1.96

Which is for less than a full day, but doesn't split it hrs and mins like I expected. I'll check back once it has been running > 24 hours to see what that looks like. I really hate the way AIX does uptime 😂

@Dylan-M
Copy link

Dylan-M commented Jun 12, 2025

@Dylan-M Could you provide these uptime examples like in the test? I want to add those to the test.

* additional commas

* ut[5] and/or ut[7] is missing

I can't provide them easily, because it requires getting the system that shows those formats - since they only show when they're non-zero.

Also, to further complicate it, one of my systems outputs uptime like this:

# uptime
  10:58AM   up  22:28,  2 users,  load average: 1.87, 1.96, 1.96

Which is for less than a full day, but doesn't split it hrs and mins like I expected. I'll check back once it has been running > 24 hours to see what that looks like. I really hate the way AIX does uptime 😂

Here is what I have recorded (well, partial, I'm recording to a file every 15 minutes using a cronjob)

  11:45AM   up  23:14,  2 users,  load average: 2.79, 2.72, 2.53
  12:00PM   up  23:29,  2 users,  load average: 3.01, 2.87, 2.75
  12:15PM   up  23:44,  2 users,  load average: 2.02, 1.99, 2.26
  12:30PM   up  23:59,  2 users,  load average: 2.73, 2.50, 2.40
  12:45PM   up 1 day, 14 mins,  2 users,  load average: 2.15, 2.31, 2.40
  01:00PM   up 1 day, 29 mins,  2 users,  load average: 2.66, 2.60, 2.44
  01:15PM   up 1 day, 44 mins,  2 users,  load average: 2.01, 2.31, 2.45
  01:30PM   up 1 day, 59 mins,  2 users,  load average: 2.00, 2.09, 2.26
  01:45PM   up 1 day,   1:14,  2 users,  load average: 2.14, 1.97, 2.06
  02:00PM   up 1 day,   1:29,  2 users,  load average: 3.04, 2.56, 2.25
  02:15PM   up 1 day,   1:44,  2 users,  load average: 2.94, 2.89, 2.67
  02:30PM   up 1 day,   1:59,  2 users,  load average: 2.08, 2.07, 2.29

And from later, another day crossing:

  11:45AM   up 1 day,  23:14,  2 users,  load average: 1.84, 2.12, 2.30
  12:00PM   up 1 day,  23:29,  2 users,  load average: 2.63, 2.19, 2.18
  12:15PM   up 1 day,  23:44,  2 users,  load average: 3.13, 2.58, 2.30
  12:30PM   up 1 day,  23:59,  2 users,  load average: 2.94, 2.48, 2.29
  12:45PM   up 2 days, 14 mins,  2 users,  load average: 2.83, 2.75, 2.58
  01:00PM   up 2 days, 29 mins,  2 users,  load average: 2.80, 2.76, 2.64
  01:15PM   up 2 days, 44 mins,  2 users,  load average: 1.75, 2.07, 2.38
  01:30PM   up 2 days, 59 mins,  2 users,  load average: 2.93, 2.36, 2.24
  01:45PM   up 2 days,   1:14,  2 users,  load average: 2.21, 2.27, 2.37
  02:00PM   up 2 days,   1:29,  2 users,  load average: 1.78, 2.38, 2.49
  02:15PM   up 2 days,   1:44,  2 users,  load average: 2.87, 2.44, 2.38
  02:30PM   up 2 days,   1:59,  2 users,  load average: 2.80, 2.46, 2.33

@shirou
Copy link
Owner Author

shirou commented Jun 14, 2025

@Dylan-M Thank you for the additional information. This is more complex than I expected. I’m starting to feel that a proper fix might be better than a quick workaround. It might be better to make use of regular expressions. I'm a busy for these days, so it might take me some time, but I’ll give it a try. Alternatively, feel free to send a good update yourself if you’d like!

@Dylan-M
Copy link

Dylan-M commented Jun 16, 2025

@Dylan-M Thank you for the additional information. This is more complex than I expected. I’m starting to feel that a proper fix might be better than a quick workaround. It might be better to make use of regular expressions. I'm a busy for these days, so it might take me some time, but I’ll give it a try. Alternatively, feel free to send a good update yourself if you’d like!

I'm sure one of us will get to it when we have time. I'm swamped with my day job work right now too.

@Dylan-M
Copy link

Dylan-M commented Jul 17, 2025

I think I've found a much better approach than the uptime command (and it's poorly machine readable format):

Get the start time of the init process (pid 1)
ps -o etime -p 1

Here is the man page info for the etime formatting option

              etime
                   Indicates the elapsed time since the process started. The elapsed time is displayed in the following format:

                   [[ dd-]hh:]mm:ss

This should be significantly easier to parse.

@Dylan-M
Copy link

Dylan-M commented Jul 17, 2025

My above solution using ps, also seems significantly more accurate (uptime doesn't properly roll the minute accurately)

[root@aix72 ~]# uptime
  11:37AM   up  15:02,  2 users,  load average: 2.97, 2.94, 2.76
[root@aix72 ~]# ps -o etimes -p 1
    ELAPSED
   15:03:02
[root@aix72 ~]# ps -o etimes -p 1
    ELAPSED
   15:03:13
[root@aix72 ~]# uptime
  11:37AM   up  15:02,  2 users,  load average: 3.12, 2.97, 2.78
[root@aix72 ~]# ps -o etimes -p 1
    ELAPSED
   15:03:17

@Dylan-M
Copy link

Dylan-M commented Jul 17, 2025

We can also pipe to fgrep to remove the ELPASED header more efficiently than we can probably do in Golang code.

[root@aix72 ~]# ps -o etimes -p 1 | fgrep -v ELAPSED
   15:04:34

@shirou
Copy link
Owner Author

shirou commented Jul 21, 2025

Looking at this: https://www.ibm.com/docs/en/aix/7.3.0?topic=p-ps-command

It does seem that etime (or etimes? which is correct?) uses a fixed format [[ dd-]hh:]mm:ss, looks good! Since using a pipe would involve spawning two processes, handling this level of string processing directly in Go is probably faster and easier.

(On Linux, there's a --no-headers flag, but it seems the AIX ps command doesn't have that.)

@Dylan-M
Copy link

Dylan-M commented Aug 15, 2025

Circling back to this (AIX work in this library in general) next week. I'll handle fixing this as part of that.

As for etime vs etimes - apparently both work and are valid. Yay oddities. I'll double check for support across multiple versions when I implement it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants