Skip to content

Commit

Permalink
Add top count option (#67)
Browse files Browse the repository at this point in the history
* Add top count option

Signed-off-by: Pan Li <incarnation.p.lee@outlook.com>
Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
Incarnation-p-lee and restyled-commits committed Jul 2, 2022
1 parent f52e5db commit 5e1d29f
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 209 deletions.
80 changes: 42 additions & 38 deletions internal/cmdflags/cmdflags.go
Original file line number Diff line number Diff line change
@@ -1,55 +1,59 @@
package cmdflags

import (
"flag"
"internal/options"
"flag"
"internal/options"
)

type cmdflag struct {
flagName, defaultValue string
description string
flagName, defaultValue string
description string
}

var supportedCmdFlags = []cmdflag {
cmdflag {
flagName: options.SamplingCount,
defaultValue: options.GetNameDefaultValue(options.SamplingCount),
description: "the total count of sampling",
},
cmdflag {
flagName: options.SamplingInterval,
defaultValue: options.GetNameDefaultValue(options.SamplingInterval),
description: "the interval for each sampling, count in seconds",
},
cmdflag {
flagName: options.OutputFormat,
defaultValue: options.GetNameDefaultValue(options.OutputFormat),
description: "the output layout for print",
},
cmdflag {
flagName: options.ProcessIDs,
defaultValue: options.GetNameDefaultValue(options.ProcessIDs),
description: "the comma separated pids for snapshot, -1 indicates all processes",
},
var supportedCmdFlags = []cmdflag{
cmdflag{
flagName: options.SamplingCount,
defaultValue: options.GetNameDefaultValue(options.SamplingCount),
description: "the total count of sampling",
},
cmdflag{
flagName: options.SamplingInterval,
defaultValue: options.GetNameDefaultValue(options.SamplingInterval),
description: "the interval for each sampling, count in seconds",
},
cmdflag{
flagName: options.OutputFormat,
defaultValue: options.GetNameDefaultValue(options.OutputFormat),
description: "the output layout for print",
},
cmdflag{
flagName: options.ProcessIDs,
defaultValue: options.GetNameDefaultValue(options.ProcessIDs),
description: "the comma separated pids for snapshot, -1 indicates all processes",
},
cmdflag{
flagName: options.TopCount,
defaultValue: options.GetNameDefaultValue(options.TopCount),
description: "the top count of process to be printed",
},
}

// ParseOptions will parse the flags from command line to options.
func ParseOptions(ops *options.Options) {
if ops == nil {
return
}
if ops == nil {
return
}

values := make([]string, len(supportedCmdFlags))
values := make([]string, len(supportedCmdFlags))

for i, v := range supportedCmdFlags {
flag.StringVar(&values[i], v.flagName, v.defaultValue, v.description)
}
for i, v := range supportedCmdFlags {
flag.StringVar(&values[i], v.flagName, v.defaultValue, v.description)
}

flag.Parse()
flag.Parse()

for i, v := range supportedCmdFlags {
key, val := v.flagName, values[i]
ops.AppendOption(options.CreateEnabledOption(key, val))
}
for i, v := range supportedCmdFlags {
key, val := v.flagName, values[i]
ops.AppendOption(options.CreateEnabledOption(key, val))
}
}

21 changes: 10 additions & 11 deletions internal/cmdflags/cmdflags_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package cmdflags

import (
"testing"
"internal/options"
"github.com/Incarnation-p-lee/cachalot/pkg/assert"
"github.com/Incarnation-p-lee/cachalot/pkg/assert"
"internal/options"
"testing"
)

func TestParseOptions(t *testing.T) {
ops := options.CreateOptions()
ops := options.CreateOptions()

ParseOptions(ops)
ParseOptions(ops)

assert.IsEqual(t, 4, ops.OptionsCount(), "optionsCount should be 4.")
assert.IsEqual(t, 5, ops.OptionsCount(), "optionsCount should be 5.")

option1, _ := ops.GetOption(0)
option2, _ := ops.GetOption(1)
option1, _ := ops.GetOption(0)
option2, _ := ops.GetOption(1)

assert.IsTrue(t, option1.IsSamplingCount(), "option is sampling count.")
assert.IsTrue(t, option2.IsSamplingInterval(), "option is sampling interval");
assert.IsTrue(t, option1.IsSamplingCount(), "option is sampling count.")
assert.IsTrue(t, option2.IsSamplingInterval(), "option is sampling interval")
}

151 changes: 80 additions & 71 deletions internal/options/options.go
Original file line number Diff line number Diff line change
@@ -1,155 +1,164 @@
package options

import (
"errors"
"fmt"
"strconv"
"errors"
"fmt"
"strconv"
)

// Option compose of key-value pair for one option, it also has one flag for enabled or not.
type Option struct {
Key, Val string
Enabled bool
Key, Val string
Enabled bool
}

// Options is the collection of Option.
type Options struct {
allOptions []Option
allOptions []Option
}

const (
unknownDefaultValue = "unknown default value"

// SamplingCount indicates how many count will be sampled.
SamplingCount = "sampling-count"
// SamplingInterval indicates the interval for each sampling, count in seconds.
SamplingInterval = "sampling-interval"
// OutputFormat indicates the layout when print.
OutputFormat = "out"
// ProcessIDs indicates the id of process.
ProcessIDs = "pids"

// AllProcessIDs indicates all process in a system.
AllProcessIDs = "-1"
// JSONOutput will be printed as json.
JSONOutput = "json"
// TextOutput will be printed as raw text.
TextOutput = "text"
unknownDefaultValue = "unknown default value"

// SamplingCount indicates how many count will be sampled.
SamplingCount = "sampling-count"
// SamplingInterval indicates the interval for each sampling, count in seconds.
SamplingInterval = "sampling-interval"
// OutputFormat indicates the layout when print.
OutputFormat = "out"
// ProcessIDs indicates the id of process.
ProcessIDs = "pids"
// TopCount indicates the limit of print times.
TopCount = "top-count"

// AllProcessIDs indicates all process in a system.
AllProcessIDs = "-1"
// JSONOutput will be printed as json.
JSONOutput = "json"
// TextOutput will be printed as raw text.
TextOutput = "text"
// DefaultTopCount indicates the default print times.
DefaultTopCount = "7"
)

var namesToDefaultValues = map[string]string {
SamplingCount: "10",
SamplingInterval: "10",
OutputFormat: TextOutput,
ProcessIDs: AllProcessIDs,
var namesToDefaultValues = map[string]string{
SamplingCount: "10",
SamplingInterval: "10",
OutputFormat: TextOutput,
ProcessIDs: AllProcessIDs,
TopCount: DefaultTopCount,
}

// GetNameDefaultValue will return the default value for option name, or unknown.
func GetNameDefaultValue(name string) string {
if value, has := namesToDefaultValues[name]; has {
return value
}
if value, has := namesToDefaultValues[name]; has {
return value
}

return unknownDefaultValue
return unknownDefaultValue
}

// CreateEnabledOption will create option enabled with given key.
func CreateEnabledOption(key, val string) Option {
return Option {
Key: key,
Val: val,
Enabled: true,
}
return Option{
Key: key,
Val: val,
Enabled: true,
}
}

// CreateOptions will create the object of Options and return the pointer.
func CreateOptions() *Options {
return &Options {
allOptions: []Option {},
}
return &Options{
allOptions: []Option{},
}
}

// AppendOption will append the Option to the Options.
func (ops *Options) AppendOption(option Option) {
ops.allOptions = append(ops.allOptions, option)
ops.allOptions = append(ops.allOptions, option)
}

func (ops *Options) getOptionVal(key string) string {
val := ""
val := ""

for _, op := range ops.allOptions {
if op.Key == key {
val = op.Val
break
}
}
for _, op := range ops.allOptions {
if op.Key == key {
val = op.Val
break
}
}

return val
return val
}

func (ops *Options) getIntOption(key string) int {
val := ops.getOptionVal(key)
val := ops.getOptionVal(key)

if intVal, err := strconv.Atoi(val); err != nil {
return 0
} else {
return intVal
}
if intVal, err := strconv.Atoi(val); err == nil {
return intVal
}

return 0
}

func (ops *Options) getStringOption(key string) string {
return ops.getOptionVal(key)
return ops.getOptionVal(key)
}

// GetSamplingCount will return the sampling count, or zero if not found or any error.
func (ops *Options) GetSamplingCount() int {
return ops.getIntOption(SamplingCount)
return ops.getIntOption(SamplingCount)
}

// GetSamplingInterval will return the sampling interval, or zero if not found or any error.
func (ops *Options) GetSamplingInterval() int {
return ops.getIntOption(SamplingInterval)
return ops.getIntOption(SamplingInterval)
}

// GetOutputFormat will return the output format, for example, json or text.
func (ops *Options) GetOutputFormat() string {
return ops.getStringOption(OutputFormat)
return ops.getStringOption(OutputFormat)
}

// GetProcessIDs will return the process ids.
func (ops *Options) GetProcessIDs() string {
return ops.getStringOption(ProcessIDs)
return ops.getStringOption(ProcessIDs)
}

// IsAllProcessIDs will return true if all proccess ids, or will return false.
func (ops *Options) IsAllProcessIDs() bool {
return ops.getStringOption(ProcessIDs) == AllProcessIDs
return ops.getStringOption(ProcessIDs) == AllProcessIDs
}

// GetTopCount will return the top count of process to be print.
func (ops *Options) GetTopCount() int {
return ops.getIntOption(TopCount)
}

// GetOption will return the option by index, out of range will return error.
func (ops *Options) GetOption(index int) (Option, error) {
limit := len(ops.allOptions)
limit := len(ops.allOptions)

if index >= limit {
msg := fmt.Sprintf("Requred index %d is out of limit %d.", index, limit)
return Option {}, errors.New(msg)
}
if index >= limit {
msg := fmt.Sprintf("Requred index %d is out of limit %d.", index, limit)
return Option{}, errors.New(msg)
}

return ops.allOptions[index], nil
return ops.allOptions[index], nil
}

// OptionsCount will return the total count of all Options.
func (ops *Options) OptionsCount() int {
return len(ops.allOptions)
return len(ops.allOptions)
}

// IsSamplingCount indicates if the option is sampling count.
func (op *Option) IsSamplingCount() bool {
return op.Key == SamplingCount
return op.Key == SamplingCount
}

// IsSamplingInterval indicates if the option is sampling interval.
func (op *Option) IsSamplingInterval() bool {
return op.Key == SamplingInterval
return op.Key == SamplingInterval
}

Loading

0 comments on commit 5e1d29f

Please sign in to comment.