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

cmd/top: First draft, have some issues #801

Closed
wants to merge 0 commits into from

Conversation

CharanSriramUni
Copy link
Contributor

@CharanSriramUni CharanSriramUni commented Apr 28, 2024

Working on adding support from incus top, but having some issues:

  1. When attempting to get the metrics data from 1.0/metrics using the internal RawQuery mechanism, err is always not nil due to an invalid character being recognized
	    if err != nil {
		    return err
	    }
	    // Perform the query
	    resp, _, err := d.RawQuery("GET", path, nil, "") // <-- err is: invalid character '#' looking for beginning of value
  1. Following how cmd/query is structured, I try to fallback to raw text if RawQuery doesn't work. Is there a way to Unmarshal OpenMetrics structured strings into the metrics struct?
  2. CPU info (at least in the raw text form) doesn't contain CPU usage per instance

Would appreciate any guidance!

@@ -11,7 +11,7 @@ import (

"github.com/spf13/cobra"

"github.com/lxc/incus/v6/client"
incus "github.com/lxc/incus/v6/client"
Copy link
Member

Choose a reason for hiding this comment

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

Tiny detail but this change should not be included, vscode tends to do that through running goimports. incus is already the package name for that URL so putting in directly as the import name is needless duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it!

cmd/incus/top.go Outdated
func (c *cmdTop) Run(cmd *cobra.Command, args []string) error {
conf := c.global.conf

remote, path, err := conf.ParseRemote("/1.0/metrics")
Copy link
Member

Choose a reason for hiding this comment

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

So I'm not too sure what's going on here.
conf.ParseRemote should be passed args[0] as is usual as that just points it to the correct server (e.g. incus top my-cluster:)

Copy link
Member

Choose a reason for hiding this comment

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

The path part is actually irrelevant in this case, you only really need remote.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If no argument is passed, should we assume that the remote is local then?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, you can look at monitor.go for an example command with similar argument handling.

cmd/incus/top.go Outdated
Comment on lines 48 to 52
// Validate path
if !strings.HasPrefix(path, "/") {
return fmt.Errorf(i18n.G("Query path must start with /"))
}

Copy link
Member

Choose a reason for hiding this comment

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

That's not relevant and can be dropped.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it!

cmd/incus/top.go Outdated
return err
}

// Perform the query
Copy link
Member

Choose a reason for hiding this comment

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

So this part is odd as you're trying to directly hit /1.0/metrics to fetch the information when you could just run d.GetMetrics() to get the same data.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah silly miss of mine- didn't realize d.GetMetrics existed. Will change this accordingly.

@stgraber
Copy link
Member

Left a bunch of comments in-line.

@CharanSriramUni
Copy link
Contributor Author

CharanSriramUni commented May 2, 2024

Just modified it to address these issues. Also, can this PR be linked to #701? Left a few comments there about some assumptions I made.

@CharanSriramUni
Copy link
Contributor Author

UI should update in realtime now like top.

Small aside, I'm currently reading user shortcuts from stdin via bufio which requires shortcuts like 'd' (changing delay) to need an "enter" keypress to be registered. There are libraries like term-box or tcell I could pull in, but wanted to ask before modifying dependencies.

Also, I'm doing parsing for metrics into the MetricSet struct (locally defined) in this code - it could be useful to move this to an external file for future use involving metrics.

@stgraber
Copy link
Member

stgraber commented May 2, 2024

Small aside, I'm currently reading user shortcuts from stdin via bufio which requires shortcuts like 'd' (changing delay) to need an "enter" keypress to be registered. There are libraries like term-box or tcell I could pull in, but wanted to ask before modifying dependencies.

Plain bufio is probably fine for now, keeping external dependencies down.

@stgraber
Copy link
Member

stgraber commented May 2, 2024

Looks like make static-analysis caught a few small things to fix :)

Copy link
Member

@stgraber stgraber left a comment

Choose a reason for hiding this comment

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

Just a few small fixes needed.

Also as this introduces new translated strings, you'll need to commit the result of make i18n as i18n: Update translation templates

cmd/incus/top.go Outdated
}

func (ms *MetricSet) getMetricValue(metricType metrics.MetricType, instanceName string) float64 {
value := 0.0
Copy link
Member

Choose a reason for hiding this comment

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

Line break here

cmd/incus/top.go Outdated
global *cmdGlobal
}

type MetricSet struct {
Copy link
Member

Choose a reason for hiding this comment

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

Since it's used internally only it doesn't need to be exported, so should just be metricSet

cmd/incus/top.go Outdated

"github.com/spf13/cobra"

incus "github.com/lxc/incus/v6/client"
Copy link
Member

Choose a reason for hiding this comment

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

This should be import as just:

"github.com/lxc/incus/v6/client"

cmd/incus/top.go Outdated
incus "github.com/lxc/incus/v6/client"
cli "github.com/lxc/incus/v6/internal/cmd"
"github.com/lxc/incus/v6/internal/i18n"
"github.com/lxc/incus/v6/internal/server/metrics"
Copy link
Member

Choose a reason for hiding this comment

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

What are you getting from this one?

The client should normally never import anything from internal/server/XYZ

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This brings in the MetricType struct and MetricNames enum that I'm using to work with the logs. I can also copy the file over here if we want - let me know if this is preferred!

cmd/incus/top.go Outdated
Comment on lines 45 to 47
cmd.Short = i18n.G("Manage command aliases")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
`Manage command aliases`))
Copy link
Member

Choose a reason for hiding this comment

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

That description is incorrect :)

cmd/incus/top.go Outdated
return err
}

// // Start the ticker for periodic updates
Copy link
Member

Choose a reason for hiding this comment

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

Weird command identifier, probably just need one // :)

cmd/incus/top.go Outdated
kv := strings.Split(pair, "=")
if len(kv) != 2 {
continue
}
Copy link
Member

Choose a reason for hiding this comment

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

Line break here

cmd/incus/top.go Outdated
key := strings.TrimSpace(kv[0])
value := strings.Trim(kv[1], "\"")
labels[key] = value
}
Copy link
Member

Choose a reason for hiding this comment

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

Line break here

cmd/incus/top.go Outdated
if typName == name {
return typ, true
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Line break here

@CharanSriramUni
Copy link
Contributor Author

Accidentally closed this branch, replaced with #817

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

Successfully merging this pull request may close these issues.

None yet

2 participants