Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8a2b841

Browse files
committed
feat: addcoder stat command for simpler agent metadata declarations
1 parent202b6fc commit8a2b841

File tree

10 files changed

+251
-29
lines changed

10 files changed

+251
-29
lines changed

‎cli/root.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,15 @@ func (r *RootCmd) checkVersions(i *clibase.Invocation, client *codersdk.Client)
680680
returnnil
681681
}
682682

683+
// verboseStderr returns the stderr writer if verbose is set, otherwise
684+
// it returns a discard writer.
685+
func (r*RootCmd)verboseStderr(inv*clibase.Invocation) io.Writer {
686+
ifr.verbose {
687+
returninv.Stderr
688+
}
689+
returnio.Discard
690+
}
691+
683692
func (r*RootCmd)checkWarnings(i*clibase.Invocation,client*codersdk.Client)error {
684693
ifr.noFeatureWarning {
685694
returnnil

‎cli/stat.go‎

Lines changed: 117 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,167 @@
11
package cli
22

33
import (
4+
"bufio"
5+
"bytes"
46
"fmt"
7+
"os"
8+
"strconv"
9+
"strings"
510
"time"
611

712
"github.com/shirou/gopsutil/cpu"
13+
"golang.org/x/xerrors"
814

915
"github.com/coder/coder/cli/clibase"
16+
"github.com/coder/coder/cli/cliui"
1017
)
1118

1219
typestatCmdstruct {
20+
*RootCmd
1321
watch time.Duration
1422
}
1523

16-
func (*RootCmd)stat()*clibase.Cmd {
24+
func (r*RootCmd)stat()*clibase.Cmd {
1725
c:=&clibase.Cmd{
18-
Use:"stat <type> [flags...]",
19-
Short:"Display system resource usage statistics",
20-
Long:"stat can be used as the script for agent metadata blocks.",
21-
Hidden:true,
26+
Use:"stat <type> [flags...]",
27+
Short:"Display local system resource usage statistics",
28+
Long:"stat calls can be used as the script for agent metadata blocks.",
2229
}
23-
varstatCmdstatCmd
30+
sc:=statCmd{RootCmd:r}
2431
c.Options.Add(
2532
clibase.Option{
2633
Flag:"watch",
2734
FlagShorthand:"w",
2835
Description:"Continuously display the statistic on the given interval.",
29-
Value:clibase.DurationOf(&statCmd.watch),
36+
Value:clibase.DurationOf(&sc.watch),
3037
},
3138
)
3239
c.AddSubcommands(
33-
statCmd.cpu(),
40+
sc.cpu(),
3441
)
42+
sc.setWatchLoops(c)
3543
returnc
3644
}
3745

38-
func (sc*statCmd)watchLoop(fn clibase.HandlerFunc) clibase.HandlerFunc {
39-
returnfunc(inv*clibase.Invocation)error {
40-
ifsc.watch==0 {
41-
returnfn(inv)
42-
}
46+
func (sc*statCmd)setWatchLoops(c*clibase.Cmd) {
47+
for_,cmd:=rangec.Children {
48+
innerHandler:=cmd.Handler
49+
cmd.Handler=func(inv*clibase.Invocation)error {
50+
ifsc.watch==0 {
51+
returninnerHandler(inv)
52+
}
4353

44-
ticker:=time.NewTicker(sc.watch)
45-
deferticker.Stop()
54+
ticker:=time.NewTicker(sc.watch)
55+
deferticker.Stop()
4656

47-
forrangeticker.C {
48-
iferr:=fn(inv);err!=nil {
49-
_,_=fmt.Fprintf(inv.Stderr,"error: %v",err)
57+
forrangeticker.C {
58+
iferr:=innerHandler(inv);err!=nil {
59+
_,_=fmt.Fprintf(inv.Stderr,"error: %v",err)
60+
}
5061
}
62+
panic("unreachable")
63+
}
64+
}
65+
}
66+
67+
funccpuUsageFromCgroup(interval time.Duration) (float64,error) {
68+
cgroup,err:=os.OpenFile("/proc/self/cgroup",os.O_RDONLY,0)
69+
iferr!=nil {
70+
return0,err
71+
}
72+
defercgroup.Close()
73+
sc:=bufio.NewScanner(cgroup)
74+
75+
vargroupDirstring
76+
forsc.Scan() {
77+
fields:=strings.Split(sc.Text(),":")
78+
iflen(fields)!=3 {
79+
continue
5180
}
52-
panic("unreachable")
81+
iffields[1]!="cpu,cpuacct" {
82+
continue
83+
}
84+
groupDir=fields[2]
85+
break
86+
}
87+
88+
ifgroupDir=="" {
89+
return0,xerrors.New("no cpu cgroup found")
90+
}
91+
92+
cpuAcct:=func() (int64,error) {
93+
path:=fmt.Sprintf("/sys/fs/cgroup/cpu,cpuacct/%s/cpuacct.usage",groupDir)
94+
95+
byt,err:=os.ReadFile(
96+
path,
97+
)
98+
iferr!=nil {
99+
return0,err
100+
}
101+
102+
returnstrconv.ParseInt(string(bytes.TrimSpace(byt)),10,64)
53103
}
104+
105+
stat1,err:=cpuAcct()
106+
iferr!=nil {
107+
return0,err
108+
}
109+
110+
time.Sleep(interval)
111+
112+
stat2,err:=cpuAcct()
113+
iferr!=nil {
114+
return0,err
115+
}
116+
117+
var (
118+
cpuTime=time.Duration(stat2-stat1)
119+
realTime=interval
120+
)
121+
122+
ncpu,err:=cpu.Counts(true)
123+
iferr!=nil {
124+
return0,err
125+
}
126+
127+
return (cpuTime.Seconds()/realTime.Seconds())*100/float64(ncpu),nil
54128
}
55129

56130
//nolint:revive
57131
func (sc*statCmd)cpu()*clibase.Cmd {
58132
varinterval time.Duration
59133
c:=&clibase.Cmd{
60-
Use:"cpu",
61-
Short:"Display the system's cpu usage",
62-
Long:"Display the system's load average.",
63-
Handler:sc.watchLoop(func(inv*clibase.Invocation)error {
64-
r,err:=cpu.Percent(0,false)
134+
Use:"cpu-usage",
135+
Aliases: []string{"cu"},
136+
Short:"Display the system's cpu usage",
137+
Long:"If inside a cgroup (e.g. docker container), the cpu usage is ",
138+
Handler:func(inv*clibase.Invocation)error {
139+
ifsc.watch!=0 {
140+
interval=sc.watch
141+
}
142+
143+
r,err:=cpuUsageFromCgroup(interval)
65144
iferr!=nil {
66-
returnerr
145+
cliui.Infof(sc.verboseStderr(inv),"cgroup error: %+v",err)
146+
147+
// Use standard methods if cgroup method fails.
148+
rs,err:=cpu.Percent(interval,false)
149+
iferr!=nil {
150+
returnerr
151+
}
152+
r=rs[0]
67153
}
68-
_,_=fmt.Fprintf(inv.Stdout,"%02.0f\n",r[0])
154+
155+
_,_=fmt.Fprintf(inv.Stdout,"%02.0f\n",r)
156+
69157
returnnil
70-
}),
158+
},
71159
Options: []clibase.Option{
72160
{
73161
Flag:"interval",
74162
FlagShorthand:"i",
75-
Description:"The sample collection interval.",
76-
Default:"1s",
163+
Description:`The sample collection interval. If --watch is set, it overrides this value.`,
164+
Default:"0s",
77165
Value:clibase.DurationOf(&interval),
78166
},
79167
},

‎cli/stat_test.go‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/coder/coder/cli/clitest"
10+
)
11+
12+
funcTestStat(t*testing.T) {
13+
t.Parallel()
14+
15+
t.Run("cpu",func(t*testing.T) {
16+
t.Parallel()
17+
inv,_:=clitest.New(t,"stat","cpu")
18+
varout bytes.Buffer
19+
inv.Stdout=&out
20+
clitest.Run(t,inv)
21+
22+
require.Regexp(t,`^[\d]{2}\n$`,out.String())
23+
})
24+
}

‎cli/testdata/coder_--help.golden‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Coder v0.0.0-devel — A tool for provisioning self-hosted development environme
3434
workspace
3535
ssh Start a shell into a workspace
3636
start Start a workspace
37+
stat Display local system resource usage statistics
3738
state Manually manage Terraform state to fix broken workspaces
3839
stop Stop a workspace
3940
templates Manage templates
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Usage: coder stat [flags] <type> [flags...]
2+
3+
Display local system resource usage statistics
4+
5+
stat calls can be used as the script for agent metadata blocks.
6+
7+
Subcommands
8+
cpu Display the system's cpu usage
9+
10+
Options
11+
-w, --watch duration
12+
Continuously display the statistic on the given interval.
13+
14+
---
15+
Run `coder --help` for a list of global options.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Usage: coder stat cpu [flags]
2+
3+
Display the system's cpu usage
4+
5+
If inside a cgroup (e.g. docker container), the cpu usage is
6+
7+
Options
8+
-i, --interval duration (default: 0s)
9+
The sample collection interval. If --watch is set, it overrides this
10+
value.
11+
12+
---
13+
Run `coder --help` for a list of global options.

‎docs/cli.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Coder — A tool for provisioning self-hosted development environments with Terr
4949
|[<code>speedtest</code>](./cli/speedtest)| Run upload and download tests from your machine to a workspace|
5050
|[<code>ssh</code>](./cli/ssh)| Start a shell into a workspace|
5151
|[<code>start</code>](./cli/start)| Start a workspace|
52+
|[<code>stat</code>](./cli/stat)| Display local system resource usage statistics|
5253
|[<code>state</code>](./cli/state)| Manually manage Terraform state to fix broken workspaces|
5354
|[<code>stop</code>](./cli/stop)| Stop a workspace|
5455
|[<code>templates</code>](./cli/templates)| Manage templates|

‎docs/cli/stat.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!-- DO NOT EDIT | GENERATED CONTENT-->
2+
3+
#stat
4+
5+
Display local system resource usage statistics
6+
7+
##Usage
8+
9+
```console
10+
coder stat [flags] <type> [flags...]
11+
```
12+
13+
##Description
14+
15+
```console
16+
stat calls can be used as the script for agent metadata blocks.
17+
```
18+
19+
##Subcommands
20+
21+
| Name| Purpose|
22+
| ------------------------------| ------------------------------|
23+
|[<code>cpu</code>](./stat_cpu)| Display the system's cpu usage|
24+
25+
##Options
26+
27+
###-w, --watch
28+
29+
|||
30+
| ----| ---------------------|
31+
| Type| <code>duration</code>|
32+
33+
Continuously display the statistic on the given interval.

‎docs/cli/stat_cpu.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!-- DO NOT EDIT | GENERATED CONTENT-->
2+
3+
#stat cpu
4+
5+
Display the system's cpu usage
6+
7+
##Usage
8+
9+
```console
10+
coder stat cpu [flags]
11+
```
12+
13+
##Description
14+
15+
```console
16+
If inside a cgroup (e.g. docker container), the cpu usage is
17+
```
18+
19+
##Options
20+
21+
###-i, --interval
22+
23+
|||
24+
| -------| ---------------------|
25+
| Type| <code>duration</code>|
26+
| Default| <code>0s</code>|
27+
28+
The sample collection interval. If --watch is set, it overrides this value.

‎docs/manifest.json‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,16 @@
677677
"description":"Start a workspace",
678678
"path":"cli/start.md"
679679
},
680+
{
681+
"title":"stat",
682+
"description":"Display local system resource usage statistics",
683+
"path":"cli/stat.md"
684+
},
685+
{
686+
"title":"stat cpu",
687+
"description":"Display the system's cpu usage",
688+
"path":"cli/stat_cpu.md"
689+
},
680690
{
681691
"title":"state",
682692
"description":"Manually manage Terraform state to fix broken workspaces",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp