Skip to content

Commit

Permalink
Merge pull request #703 from NAICNO/larstha-667-bring-help-now
Browse files Browse the repository at this point in the history
Fix # 667 - More online help
  • Loading branch information
lars-t-hansen authored Nov 22, 2024
2 parents 964eef2 + 1d7c2a7 commit 6f77ec6
Show file tree
Hide file tree
Showing 32 changed files with 434 additions and 138 deletions.
33 changes: 7 additions & 26 deletions code/sonalyze/cmd/add/add.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
// The "add" command adds information to the database. It reads its input from a provided stream.
// This command is remotable.
//
// Major operations:
//
// add -sample
// Add sonar sample data. The default format is "free csv", ie csv with name=value field syntax
// and no fixed colums. There are no alternate formats at this time.
//
// add -sysinfo
// Add sonar sysinfo data. The default format is JSON. There are no alternate formats at this
// time.
//
// add -slurm-sacct
// Add sacct data. The default formt is "free csv", ie csv with name=value field syntax
// and no fixed colums. There are no alternate formats at this time.

package add

import (
"bufio"
"bytes"
_ "embed"
"encoding/csv"
"encoding/json"
"errors"
Expand All @@ -34,13 +18,6 @@ import (
"sonalyze/sonarlog"
)

// MT: Constant after initialization; immutable
var addHelp = []string{
"Add new data to the database. Data are read from stdin, the type and",
"format are implied by operations -sample, -sysinfo, or -slurm-sacct, one",
"of which must be specified.",
}

type AddCommand struct /* implements RemotableCommand */ {
DevArgs
VerboseArgs
Expand All @@ -52,8 +29,11 @@ type AddCommand struct /* implements RemotableCommand */ {
SlurmSacct bool
}

func (ac *AddCommand) Summary() []string {
return addHelp
//go:embed summary.txt
var summary string

func (ac *AddCommand) Summary() string {
return summary
}

func (ac *AddCommand) Add(fs *CLI) {
Expand All @@ -62,6 +42,7 @@ func (ac *AddCommand) Add(fs *CLI) {
ac.DataDirArgs.Add(fs)
ac.RemotingArgs.Add(fs)
ac.ConfigFileArgs.Add(fs)

fs.Group("data-target")
fs.BoolVar(&ac.Sample, "sample", false,
"Insert sonar sample data from stdin (zero or more records)")
Expand Down
14 changes: 14 additions & 0 deletions code/sonalyze/cmd/add/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Add new data to the database.

Data are read from stdin, the type and format are implied by operations
-sample, -sysinfo, or -slurm-sacct, one of which must be specified:

`add -sample` adds `sonar ps` data. The format must be "free CSV", ie CSV
with name=value field syntax and no fixed colums.

`add -sysinfo` adds `sonar sysinfo` data. The format must be JSON.

`add -slurm-sacct` adds `sonar slurm` data. The format must be free CSV.

Mostly this command is only run by the daemon; manual use is for
experiments and bugfixes.
15 changes: 7 additions & 8 deletions code/sonalyze/cmd/cli.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// An elaborated flag.FlagSet object in which options can be grouped sensibly in the help text.

package cmd

import (
Expand Down Expand Up @@ -62,9 +64,7 @@ func NewCLI(verb string, command Command, name string, exitOnError bool) *CLI {
verb,
restargs,
)
for _, s := range command.Summary() {
fmt.Fprintln(out, " ", s)
}
fmt.Fprint(out, command.Summary())
defaults := cli.getSortedDefaults(restargs != "")
for _, g := range defaults {
fmt.Fprintf(out, "\n%s options:\n\n", g.group)
Expand Down Expand Up @@ -139,12 +139,11 @@ func (cli *CLI) getSortedDefaults(restArgs bool) []defaultGroup {
}
defaults := umaps.Values(defaultsMap)
slices.SortFunc(defaults, func(a, b defaultGroup) int {
aPri := priority[a.group]
bPri := priority[b.group]
if aPri == bPri {
return cmp.Compare(a.group, b.group)
c := cmp.Compare(priority[a.group], priority[b.group])
if c == 0 {
c = cmp.Compare(a.group, b.group)
}
return aPri - bPri
return c
})
return defaults
}
Expand Down
16 changes: 6 additions & 10 deletions code/sonalyze/cmd/clusters/clusters.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
// The output of this verb is a list of clusters with any available metadata.
//
// * For `-remote` there must not be a `-cluster` option
// * When running locally there must be `-jobanalyzer-dir` as for `daemon`
// * `-data-dir` and `-config-file` are illegal, as are all filtering options

package clusters

import (
"cmp"
_ "embed"
"errors"
"io"
"reflect"
Expand All @@ -32,10 +27,11 @@ type ClusterCommand struct {
JobanalyzerDir string
}

func (cc *ClusterCommand) Summary() []string {
return []string{
"Extract information about clusters in the data store",
}
//go:embed summary.txt
var summary string

func (cc *ClusterCommand) Summary() string {
return summary
}

func (cc *ClusterCommand) Add(fs *CLI) {
Expand Down
6 changes: 6 additions & 0 deletions code/sonalyze/cmd/clusters/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Display information about the clusters and overall cluster configuration.

As this operates on the store and not on cluster data in the store, there is
no -cluster argument for remote runs.

For per-node data, use "config" and/or "node".
4 changes: 2 additions & 2 deletions code/sonalyze/cmd/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ type Command interface {
// Return the name of the cpu profile file, if requested
CpuProfileFile() string

// Documentation, one line per string
Summary() []string
// Documentation, with formatting and line breaks
Summary() string

// Add all arguments including shared arguments
Add(fs *CLI)
Expand Down
15 changes: 7 additions & 8 deletions code/sonalyze/cmd/configs/configs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// The "configs" table exposes the config file for a cluster, but only the per-node information.
// The per-cluster information in the config file is exposed by the "clusters" verb.
//
// The "configs" API is therefore very similar to the "nodes" API. However:
// The "configs" API is very similar to the "nodes" API. However:
//
// - The configs API relies only on the config file, it accepts no data store or file list
// - The command line API:
Expand All @@ -16,6 +13,7 @@ package configs

import (
"cmp"
_ "embed"
"errors"
"io"
"reflect"
Expand All @@ -41,10 +39,11 @@ type ConfigCommand struct {
FormatArgs
}

func (cc *ConfigCommand) Summary() []string {
return []string{
"Extract information about nodes in the cluster configuration",
}
//go:embed summary.txt
var summary string

func (cc *ConfigCommand) Summary() string {
return summary
}

func (cc *ConfigCommand) Add(fs *CLI) {
Expand Down
7 changes: 7 additions & 0 deletions code/sonalyze/cmd/configs/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Display information about nodes in a cluster configuration.

The node configuration is time-dependent and is computed from data reported
by the node and additional background information.

For overall cluster data, use "cluster". Also see "node" for closely
related data.
13 changes: 6 additions & 7 deletions code/sonalyze/cmd/jobs/jobs.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Compute jobs aggregates from a set of log entries.

package jobs

import (
_ "embed"
"errors"

. "sonalyze/cmd"
Expand Down Expand Up @@ -254,11 +253,11 @@ type JobsCommand struct /* implements SampleAnalysisCommand */ {

var _ SampleAnalysisCommand = (*JobsCommand)(nil)

func (_ *JobsCommand) Summary() []string {
return []string{
"Select jobs by various criteria and present aggregate information",
"about them.",
}
//go:embed summary.txt
var summary string

func (_ *JobsCommand) Summary() string {
return summary
}

func (jc *JobsCommand) lookupUint(s string) uint {
Expand Down
17 changes: 17 additions & 0 deletions code/sonalyze/cmd/jobs/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Display jobs jobs aggregated from process samples.

A "job" is aggregated from sample streams from one or more processes on one
or more nodes of a cluster. On some clusters, jobs have clearly defined job
numbers (provided by a batch system such as Slurm), while on other clusters,
the job numbers are inferred from the process tree.

As jobs are built from samples, the job data can be noisy and may sometimes
not represent true behavior. This is especially true for short jobs.

Note also:

- A job can be selected by job number, but a time window must be selected
that contains the job or the job will not be found

- By default, only the jobs for the current user's user name are selected,
specify "-user -" to see all users
11 changes: 6 additions & 5 deletions code/sonalyze/cmd/load/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package load

import (
_ "embed"
"errors"

. "sonalyze/cmd"
Expand Down Expand Up @@ -44,11 +45,11 @@ type LoadCommand struct /* implements SampleAnalysisCommand */ {

var _ SampleAnalysisCommand = (*LoadCommand)(nil)

func (_ *LoadCommand) Summary() []string {
return []string{
"Compute aggregate system load across various timeframes based on sample",
"data and present the load data in various formats.",
}
//go:embed summary.txt
var summary string

func (_ *LoadCommand) Summary() string {
return summary
}

func (lc *LoadCommand) Add(fs *CLI) {
Expand Down
8 changes: 8 additions & 0 deletions code/sonalyze/cmd/load/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Compute aggregate load for hosts and groups of hosts.

The aggregation can be performed across various timeframes and will be
based on available sample data.

As not all processes' samples are stored (processes typically have to
be "significant"), the true load can be underreported somewhat, but
probably not by very much.
19 changes: 10 additions & 9 deletions code/sonalyze/cmd/metadata/metadata.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package metadata

import (
_ "embed"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -32,12 +33,11 @@ type MetadataCommand struct /* implements SampleAnalysisCommand */ {

var _ SampleAnalysisCommand = (*MetadataCommand)(nil)

func (_ *MetadataCommand) Summary() []string {
return []string{
"Display metadata about the sample streams in the database.",
"One or more of -files, -times and -bounds must be selected to produce",
"output.",
}
//go:embed summary.txt
var summary string

func (_ *MetadataCommand) Summary() string {
return summary
}

func (mdc *MetadataCommand) Add(fs *CLI) {
Expand All @@ -51,9 +51,10 @@ func (mdc *MetadataCommand) Add(fs *CLI) {
"Merge streams that have the same job ID, across hosts")

fs.Group("operation-selection")
fs.BoolVar(&mdc.Files, "files", false, "List selected files")
fs.BoolVar(&mdc.Times, "times", false, "Show parsed from/to timestamps")
fs.BoolVar(&mdc.Bounds, "bounds", false, "Show host with earliest/latest timestamp")
fs.BoolVar(&mdc.Files, "files", false, "List files selected by the record filter")
fs.BoolVar(&mdc.Times, "times", false, "Parse the -from and -to timestamps")
fs.BoolVar(&mdc.Bounds, "bounds", false,
"List each host with its earliest/latest record timestamp")
}

func (mdc *MetadataCommand) ReifyForRemote(x *ArgReifier) error {
Expand Down
7 changes: 7 additions & 0 deletions code/sonalyze/cmd/metadata/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Display metadata about the sample streams in the database.

One or more of -files, -times and -bounds must be selected to produce
output.

Mostly this command is useful for debugging, but -bounds can be used to
detect whether a node is up more cheaply than the "uptime" operation.
10 changes: 6 additions & 4 deletions code/sonalyze/cmd/nodes/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package nodes

import (
"cmp"
_ "embed"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -43,10 +44,11 @@ type NodeCommand struct {

var _ = (SimpleCommand)((*NodeCommand)(nil))

func (nc *NodeCommand) Summary() []string {
return []string{
"Extract information about nodes in the cluster",
}
//go:embed summary.txt
var summary string

func (nc *NodeCommand) Summary() string {
return summary
}

func (nc *NodeCommand) Add(fs *CLI) {
Expand Down
8 changes: 8 additions & 0 deletions code/sonalyze/cmd/nodes/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Display self-reported information about nodes in a cluster.

For overall cluster data, use "cluster". Also see "config" for
closely related data.

The node configuration is time-dependent and is reported by the node
periodically, it will usually only change if the node is upgraded or
components are inserted/removed.
10 changes: 6 additions & 4 deletions code/sonalyze/cmd/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package parse

import (
"cmp"
_ "embed"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -30,10 +31,11 @@ type ParseCommand struct /* implements SampleAnalysisCommand */ {

var _ SampleAnalysisCommand = (*ParseCommand)(nil)

func (_ *ParseCommand) Summary() []string {
return []string{
"Export sample data in various formats, after optional preprocessing.",
}
//go:embed summary.txt
var summary string

func (_ *ParseCommand) Summary() string {
return summary
}

func (pc *ParseCommand) Add(fs *CLI) {
Expand Down
8 changes: 8 additions & 0 deletions code/sonalyze/cmd/parse/summary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Export sample data in various formats, after optional preprocessing.

This facility is mostly for debugging and experimentation, as the data
volume is typically significant and the data are not necessarily
postprocessed in a way useful to the consumer.

The -merge and -clean options perform some postprocessing, but you need to
know what you're looking at to find these useful.
Loading

0 comments on commit 6f77ec6

Please sign in to comment.