feat(sysinfo): sysinfo segment

cpu, mem, load, ...
This commit is contained in:
lnu 2021-11-13 23:46:06 +01:00 committed by Jan De Dobbeleer
parent 2c1d5cf6e4
commit 25be370618
16 changed files with 219 additions and 154 deletions

View file

@ -47,6 +47,7 @@
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"eamodio.gitlens",
"github.vscode-pull-request-github",
"esbenp.prettier-vscode",
"davidanson.vscode-markdownlint",

View file

@ -49,7 +49,7 @@ The configuration has the following properties:
- template: `string` - A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the
properties below. Defaults to `{{ .Shell }}> `
### Template Properties
## Template Properties
- `.Root`: `boolean` - is the current user root/admin or not
- `.Path`: `string` - the current working directory

View file

@ -1,31 +0,0 @@
---
id: memory
title: Memory
sidebar_label: Memory
---
## Memory
Display physical memory or swap usage percentage.
## Sample Configuration
```json
{
"type": "memory",
"style": "powerline",
"foreground": "#26C6DA",
"background": "#2f2f2f",
"properties": {
"precision": 1,
"prefix": " \uf85a ",
"postfix": "% "
}
}
```
## Properties
- precision: `int` - the number of decimal places to show - defaults to `0`
- use_available: `boolean` - whether to use available or free memory on Linux - defaults to `true`
- memory_type: `enum` - whether to show `physical` memory or `swap` memory - defaults to `physical`

View file

@ -41,7 +41,7 @@ properties below. Defaults does nothing(backward compatibility).
- version_url_template: `string` - A go [text/template][go-text-template] template extended
with [sprig][sprig] utilizing the properties below. Defaults does nothing(backward compatibility).
### Template Properties
## Template Properties
- `.Major`: `string` - is the major version
- `.Minor`: `string` - is the minor version

49
docs/docs/sysinfo.md Normal file
View file

@ -0,0 +1,49 @@
---
id: sysinfo
title: SysInfo
sidebar_label: SysInfo
---
## SysInfo
Display SysInfo.
## Sample Configuration
```json
{
"type":"sysinfo",
"powerline_symbol": "",
"foreground": "#ffffff",
"background": "#8f43f3",
"invert_powerline": true,
"properties": {
"prefix": " \uf85a ",
"postfix": "% ",
"precision": 2,
"template":"{{ round .PhysicalPercentUsed .Precision }}"
},
"style":"powerline"
},
```
## Properties
- Precision: `int` - The precision used for any float values - defaults to 2
- template: `string` - A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the
properties below - defaults to `{{ round .PhysicalPercentUsed .Precision }}> `
## Template Properties
- `.PhysicalTotalMemory`: `int` - is the total of used physical memory
- `.PhysicalFreeMemory`: `int` - is the total of free physical memory
- `.PhysicalPercentUsed`: `float64` - is the percentage of physical memory in usage
- `.SwapTotalMemory`: `int` - is the total of used swap memory
- `.SwapFreeMemory`: `int` - is the percentage of swap memory in usage
- `.SwapPercentUsed`: `float64` - is the current user root/admin or not
- `.Load1`: `float64` - is the current load1 (can be empty on windows)
- `.Load5`: `float64` - is the current load5 (can be empty on windows)
- `.Load15`: `float64` - is the current load15 (can be empty on windows)
- `.CPU`: `[]struct` - an array of [InfoStat][cpuinfo] object, you can use any property it has e.g. `(index .CPU 0).Cores`
[cpuinfo]: https://github.com/shirou/gopsutil/blob/78065a7ce2021f6a78c8d6f586a2683ba501dcec/cpu/cpu.go#L32

View file

@ -54,7 +54,7 @@ module.exports = {
"java",
"julia",
"kubectl",
"memory",
"sysinfo",
"nbgv",
"node",
"os",

View file

@ -17,7 +17,7 @@ import (
"time"
"github.com/distatus/battery"
"github.com/shirou/gopsutil/process"
process "github.com/shirou/gopsutil/v3/process"
)
const (

View file

@ -7,7 +7,7 @@ import (
"os"
"time"
"github.com/shirou/gopsutil/host"
"github.com/shirou/gopsutil/v3/host"
terminal "github.com/wayneashleyberry/terminal-dimensions"
)

View file

@ -19,11 +19,9 @@ require (
github.com/gookit/config/v2 v2.0.27
github.com/gookit/goutil v0.4.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/jan0660/memory v0.1.2
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.4.2
github.com/sergi/go-diff v1.2.0 // indirect
github.com/shirou/gopsutil v3.21.9+incompatible
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/tklauser/go-sysconf v0.3.9 // indirect
@ -36,6 +34,8 @@ require (
howett.net/plist v0.0.0-20201203080718-1454fab16a06 // indirect
)
require github.com/shirou/gopsutil/v3 v3.21.10
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
@ -43,6 +43,7 @@ require (
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect

View file

@ -5,8 +5,6 @@ github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/JanDeDobbeleer/battery v0.10.0-2 h1:nmFASq8Rmo0sHz6gLT3pXHh7uNABLEgEozKb2tRPgVY=
github.com/JanDeDobbeleer/battery v0.10.0-2/go.mod h1:STnSvFLX//eEpkaN7qWRxCWxrWOcssTDgnG4yqq9BRE=
github.com/JanDeDobbeleer/gopsutil v3.21.9-1+incompatible h1:XaJExIJleF33D1WSjle30LBqegcy2Pguge3wu4wZB7A=
github.com/JanDeDobbeleer/gopsutil v3.21.9-1+incompatible/go.mod h1:7cScMdSKcXHocZHUVqp7KI/2RMf0ZIhl8BGd7Hj3AFQ=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
@ -42,6 +40,8 @@ github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
@ -65,8 +65,6 @@ github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jan0660/memory v0.1.2 h1:Dxc2p3DJIJ+w2D2/OSqg3rf+ZQZ/lcYxiSXfiCNGRnA=
github.com/jan0660/memory v0.1.2/go.mod h1:I9fFv85Tlthw0cS4nXzY9kCtCpNLuYsVVIxhejK50Cg=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@ -77,6 +75,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
@ -105,6 +105,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil/v3 v3.21.10 h1:flTg1DrnV/UVrBqjLgVgDJzx6lf+91rC64/dBHmO2IA=
github.com/shirou/gopsutil/v3 v3.21.10/go.mod h1:t75NhzCZ/dYyPQjyQmrAYP6c8+LCdFANeBMdLPCNnew=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.0 h1:KK3gWIXskZ2O1U/JNTisNcvH+jveJxZYrjbTsrbbnh8=
github.com/shopspring/decimal v1.3.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@ -164,6 +166,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211020064051-0ec99a608a1b h1:byBDhtWGQmWDrv1MlEv/BzGRMkw36h9QqsNnZQcDhRw=
golang.org/x/sys v0.0.0-20211020064051-0ec99a608a1b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@ -176,6 +179,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -124,8 +124,8 @@ const (
Rust SegmentType = "rust"
// OWM writes the weather coming from openweatherdata
OWM SegmentType = "owm"
// Memory writes used memory percentage
Memory SegmentType = "memory"
// SysInfo writes system information (memory, cpu, load)
SysInfo SegmentType = "sysinfo"
// Angular writes which angular cli version us currently active
Angular SegmentType = "angular"
// PHP writes which php version is currently active
@ -260,7 +260,7 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {
Dart: &dart{},
Nbgv: &nbgv{},
Rust: &rust{},
Memory: &memory{},
SysInfo: &sysinfo{},
Angular: &angular{},
PHP: &php{},
}

View file

@ -1,54 +0,0 @@
package main
import (
"strconv"
mem "github.com/jan0660/memory"
)
type memory struct {
props *properties
env environmentInfo
TotalMemory uint64
FreeMemory uint64
}
const (
// Precision number of decimal places to show
Precision Property = "precision"
// UseAvailable if available memory should be used instead of free on Linux
UseAvailable Property = "use_available"
// MemoryType either physical or swap
MemoryType Property = "memory_type"
)
func (n *memory) enabled() bool {
if n.TotalMemory == 0 || n.FreeMemory == 0 {
// failed to get memory information
return false
}
return true
}
func (n *memory) string() string {
// 100.0 / total * used
percentage := 100.0 / float64(n.TotalMemory) * float64(n.TotalMemory-n.FreeMemory)
text := strconv.FormatFloat(percentage, 'f', n.props.getInt(Precision, 0), 64)
return text
}
func (n *memory) init(props *properties, env environmentInfo) {
n.props = props
n.env = env
if props.getString(MemoryType, "physical") == "physical" {
n.TotalMemory = mem.TotalMemory()
if props.getBool(UseAvailable, true) {
n.FreeMemory = mem.AvailableMemory()
return
}
n.FreeMemory = mem.FreeMemory()
return
}
n.TotalMemory = mem.TotalSwap()
n.FreeMemory = mem.FreeSwap()
}

View file

@ -1,35 +0,0 @@
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestMemory(t *testing.T) {
cases := []struct {
Case string
ExpectedString string
ExpectDisabled bool
Memory memory
Precision int
}{
{Case: "50", ExpectedString: "50", Memory: memory{FreeMemory: 50, TotalMemory: 100}},
{Case: "50.0", ExpectedString: "50.0", Memory: memory{FreeMemory: 50, TotalMemory: 100}, Precision: 1},
{Case: "not enabled", ExpectDisabled: true, Memory: memory{FreeMemory: 0, TotalMemory: 0}},
}
for _, tc := range cases {
tc.Memory.env = new(MockedEnvironment)
tc.Memory.props = &properties{
values: map[Property]interface{}{
Precision: tc.Precision,
},
}
if tc.ExpectDisabled {
assert.Equal(t, false, tc.Memory.enabled(), tc.Case)
} else {
assert.Equal(t, tc.ExpectedString, tc.Memory.string(), tc.Case)
}
}
}

90
src/segment_sysinfo.go Normal file
View file

@ -0,0 +1,90 @@
package main
import (
cpu "github.com/shirou/gopsutil/v3/cpu"
load "github.com/shirou/gopsutil/v3/load"
mem "github.com/shirou/gopsutil/v3/mem"
)
type sysinfo struct {
props *properties
env environmentInfo
Precision int
// mem
PhysicalTotalMemory uint64
PhysicalFreeMemory uint64
PhysicalPercentUsed float64
SwapTotalMemory uint64
SwapFreeMemory uint64
SwapPercentUsed float64
// cpu
Times float64
CPU []cpu.InfoStat
// load
Load1 float64
Load5 float64
Load15 float64
}
const (
// Precision number of decimal places to show
Precision Property = "precision"
)
func (s *sysinfo) enabled() bool {
if s.PhysicalPercentUsed == 0 && s.SwapPercentUsed == 0 {
return false
}
return true
}
func (s *sysinfo) string() string {
// keep old memory segment template
segmentTemplate := s.props.getString(SegmentTemplate, "{{ round .PhysicalPercentUsed .Precision }}")
template := &textTemplate{
Template: segmentTemplate,
Context: s,
Env: s.env,
}
text, err := template.render()
if err != nil {
return err.Error()
}
return text
}
func (s *sysinfo) init(props *properties, env environmentInfo) {
s.props = props
s.env = env
s.Precision = s.props.getInt(Precision, 2)
// mem
memStat, err := mem.VirtualMemory()
if err == nil {
s.PhysicalTotalMemory = memStat.Total
s.PhysicalFreeMemory = memStat.Free
s.PhysicalPercentUsed = memStat.UsedPercent
}
swapStat, err := mem.SwapMemory()
if err == nil {
s.SwapTotalMemory = swapStat.Total
s.SwapFreeMemory = swapStat.Free
s.SwapPercentUsed = swapStat.UsedPercent
}
// load
loadStat, err := load.Avg()
if err == nil {
s.Load1 = loadStat.Load1
s.Load5 = loadStat.Load5
s.Load15 = loadStat.Load15
}
// times
processorTimes, err := cpu.Percent(0, false)
if err == nil {
s.Times = processorTimes[0]
}
// cpu
processors, err := cpu.Info()
if err == nil {
s.CPU = processors
}
}

View file

@ -0,0 +1,52 @@
package main
import (
"testing"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/stretchr/testify/assert"
)
func TestSysInfo(t *testing.T) {
cases := []struct {
Case string
ExpectedString string
ExpectDisabled bool
SysInfo sysinfo
Precision int
Template string
}{
{Case: "physical mem", ExpectedString: "50", SysInfo: sysinfo{PhysicalPercentUsed: 50}},
{Case: "physical mem 2 digits", ExpectedString: "60.51", SysInfo: sysinfo{Precision: 2, PhysicalPercentUsed: 60.51}},
{Case: "physical meme rounded", ExpectedString: "61", SysInfo: sysinfo{Precision: 0, PhysicalPercentUsed: 61}},
{
Case: "load",
ExpectedString: "0.22 0.12 0",
Template: "{{ round .Load1 .Precision }} {{round .Load5 .Precision }} {{round .Load15 .Precision }}",
SysInfo: sysinfo{Precision: 2, Load1: 0.22, Load5: 0.12, Load15: 0}},
{Case: "not enabled", ExpectDisabled: true, SysInfo: sysinfo{PhysicalPercentUsed: 0, SwapPercentUsed: 0}},
{
Case: "2 physical cpus",
ExpectedString: "1200 1200 ",
Template: "{{range $cpu := .CPU}}{{round $cpu.Mhz 2 }} {{end}}",
SysInfo: sysinfo{CPU: []cpu.InfoStat{{Mhz: 1200}, {Mhz: 1200}}},
},
}
for _, tc := range cases {
tc.SysInfo.env = new(MockedEnvironment)
tc.SysInfo.props = &properties{
values: map[Property]interface{}{
Precision: tc.Precision,
},
}
if tc.Template != "" {
tc.SysInfo.props.values[SegmentTemplate] = tc.Template
}
if tc.ExpectDisabled {
assert.Equal(t, false, tc.SysInfo.enabled(), tc.Case)
} else {
assert.Equal(t, tc.ExpectedString, tc.SysInfo.string(), tc.Case)
}
}
}

View file

@ -53,10 +53,7 @@
"default": ""
},
"template": {
"type": "string",
"title": "Template text",
"description": "The template to use to render the segment text",
"default": ""
"$ref": "#/definitions/template"
},
"block": {
"type": "object",
@ -169,7 +166,7 @@
"dart",
"rust",
"owm",
"memory",
"sysinfo",
"angular",
"php"
]
@ -1643,12 +1640,12 @@
{
"if": {
"properties": {
"type": { "const": "memory" }
"type": { "const": "sysinfo" }
}
},
"then": {
"title": "Get used memory percentage",
"description": "https://ohmyposh.dev/docs/memory",
"title": "Get sysinfo",
"description": "https://ohmyposh.dev/docs/sysinfo",
"properties": {
"properties": {
"properties": {
@ -1658,18 +1655,8 @@
"description": "number of decimal places to show",
"default": 0
},
"use_available": {
"type": "boolean",
"title": "Use available memory",
"description": "whether to use available or free memory on Linux",
"default": true
},
"memory_type": {
"type": "string",
"enum": ["physical", "swap"],
"title": "Memory type",
"description": "whether to show physical or swap memory",
"default": "physical"
"template": {
"$ref": "#/definitions/template"
}
}
}