Skip to content

Commit

Permalink
add --reqtime-label, --status-label, --include-statuses, --exclude-st…
Browse files Browse the repository at this point in the history
…atuses
  • Loading branch information
tkuchiki committed Sep 8, 2016
1 parent 5dafe38 commit 43311c9
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 49 deletions.
73 changes: 47 additions & 26 deletions config.go
Expand Up @@ -4,32 +4,37 @@ import (
"gopkg.in/yaml.v2"
"io/ioutil"
"os"
"strings"
)

type Config struct {
File string `yaml:"file"`
Sort string `yaml:"sort"`
Reverse bool `yaml:"reverse"`
QueryString bool `yaml:"query_string"`
Tsv bool `yaml:"tsv"`
ApptimeLabel string `yaml:"apptime_label"`
SizeLabel string `yaml:"size_label"`
MethodLabel string `yaml:"method_label"`
UriLabel string `yaml:"uri_label"`
TimeLabel string `yaml:"time_label"`
Limit int `yaml:"limit"`
Includes []string `yaml:"includes"`
Excludes []string `yaml:"excludes"`
NoHeaders bool `yaml:no_headers`
Aggregates []string `yaml:"aggregates"`
StartTime string `yaml:"start_time"`
EndTime string `yaml:"end_time"`
StartTimeDuration string `yaml:"start_time_duration"`
EndTimeDuration string `yaml:"end_time_duration"`
IncludesStr string
ExcludesStr string
AggregatesStr string
File string `yaml:"file"`
Sort string `yaml:"sort"`
Reverse bool `yaml:"reverse"`
QueryString bool `yaml:"query_string"`
Tsv bool `yaml:"tsv"`
ApptimeLabel string `yaml:"apptime_label"`
ReqtimeLabel string `yaml:"reqtime_label"`
StatusLabel string `yaml:"status_label"`
SizeLabel string `yaml:"size_label"`
MethodLabel string `yaml:"method_label"`
UriLabel string `yaml:"uri_label"`
TimeLabel string `yaml:"time_label"`
Limit int `yaml:"limit"`
Includes []string `yaml:"includes"`
Excludes []string `yaml:"excludes"`
IncludeStatuses []string `yaml:"include_statuses"`
ExcludeStatuses []string `yaml:"exclude_statuses"`
NoHeaders bool `yaml:no_headers`
Aggregates []string `yaml:"aggregates"`
StartTime string `yaml:"start_time"`
EndTime string `yaml:"end_time"`
StartTimeDuration string `yaml:"start_time_duration"`
EndTimeDuration string `yaml:"end_time_duration"`
IncludesStr string
ExcludesStr string
IncludeStatusesStr string
ExcludeStatusesStr string
AggregatesStr string
}

func SetConfig(config Config, arg Config) Config {
Expand All @@ -53,6 +58,14 @@ func SetConfig(config Config, arg Config) Config {
config.ApptimeLabel = arg.ApptimeLabel
}

if config.ReqtimeLabel == "" || (config.ReqtimeLabel != "" && arg.ReqtimeLabel != ReqtimeLabel) {
config.ReqtimeLabel = arg.ReqtimeLabel
}

if config.StatusLabel == "" || (config.StatusLabel != "" && arg.StatusLabel != StatusLabel) {
config.StatusLabel = arg.StatusLabel
}

if config.SizeLabel == "" || (config.SizeLabel != "" && arg.SizeLabel != SizeLabel) {
config.SizeLabel = arg.SizeLabel
}
Expand All @@ -74,19 +87,27 @@ func SetConfig(config Config, arg Config) Config {
}

if arg.IncludesStr != "" {
config.Includes = strings.Split(arg.IncludesStr, ",")
config.Includes = Split(arg.IncludesStr, ",")
}

if arg.ExcludesStr != "" {
config.Excludes = strings.Split(arg.ExcludesStr, ",")
config.Excludes = Split(arg.ExcludesStr, ",")
}

if arg.IncludeStatusesStr != "" {
config.IncludeStatuses = Split(arg.IncludeStatusesStr, ",")
}

if arg.ExcludeStatusesStr != "" {
config.ExcludeStatuses = Split(arg.ExcludeStatusesStr, ",")
}

if arg.NoHeaders {
config.NoHeaders = arg.NoHeaders
}

if arg.AggregatesStr != "" {
config.Aggregates = strings.Split(arg.AggregatesStr, ",")
config.Aggregates = Split(arg.AggregatesStr, ",")
}

if arg.StartTime != "" {
Expand Down
123 changes: 100 additions & 23 deletions main.go
Expand Up @@ -16,6 +16,8 @@ import (

const (
ApptimeLabel = "apptime"
ReqtimeLabel = "reqtime"
StatusLabel = "status"
SizeLabel = "size"
MethodLabel = "method"
UriLabel = "uri"
Expand Down Expand Up @@ -47,6 +49,8 @@ var (
queryString = kingpin.Flag("query-string", "include query string").Short('q').Bool()
tsv = kingpin.Flag("tsv", "tsv format (default: table)").Bool()
apptimeLabel = kingpin.Flag("apptime-label", "apptime label").Default(ApptimeLabel).String()
reqtimeLabel = kingpin.Flag("reqtime-label", "reqtime label").Default(ReqtimeLabel).String()
statusLabel = kingpin.Flag("status-label", "status label").Default(StatusLabel).String()
sizeLabel = kingpin.Flag("size-label", "size label").Default(SizeLabel).String()
methodLabel = kingpin.Flag("method-label", "method label").Default(MethodLabel).String()
uriLabel = kingpin.Flag("uri-label", "uri label").Default(UriLabel).String()
Expand All @@ -55,6 +59,8 @@ var (
location = kingpin.Flag("location", "location name").String()
includes = kingpin.Flag("includes", "don't exclude uri matching PATTERN (comma separated)").PlaceHolder("PATTERN,...").String()
excludes = kingpin.Flag("excludes", "exclude uri matching PATTERN (comma separated)").PlaceHolder("PATTERN,...").String()
includeStatuses = kingpin.Flag("include-statuses", "don't exclude status code matching PATTERN (comma separated)").PlaceHolder("PATTERN,...").String()
excludeStatuses = kingpin.Flag("exclude-statuses", "exclude uri status code PATTERN (comma separated)").PlaceHolder("PATTERN,...").String()
noHeaders = kingpin.Flag("noheaders", "print no header line at all (only --tsv)").Bool()
aggregates = kingpin.Flag("aggregates", "aggregate uri matching PATTERN (comma separated)").PlaceHolder("PATTERN,...").String()
startTime = kingpin.Flag("start-time", "since the start time").PlaceHolder("TIME").String()
Expand All @@ -72,7 +78,7 @@ var (

func main() {
kingpin.CommandLine.Help = "Access Log Profiler for LTSV (read from file or stdin)."
kingpin.Version("0.2.4")
kingpin.Version("0.3.0")
kingpin.Parse()

var f *os.File
Expand All @@ -87,24 +93,28 @@ func main() {
}

option := Config{
File: *file,
Reverse: *reverse,
QueryString: *queryString,
Tsv: *tsv,
ApptimeLabel: *apptimeLabel,
SizeLabel: *sizeLabel,
MethodLabel: *methodLabel,
UriLabel: *uriLabel,
TimeLabel: *timeLabel,
Limit: *limit,
IncludesStr: *includes,
ExcludesStr: *excludes,
NoHeaders: *noHeaders,
AggregatesStr: *aggregates,
StartTime: *startTime,
EndTime: *endTime,
StartTimeDuration: *startTimeDuration,
EndTimeDuration: *endTimeDuration,
File: *file,
Reverse: *reverse,
QueryString: *queryString,
Tsv: *tsv,
ApptimeLabel: *apptimeLabel,
ReqtimeLabel: *reqtimeLabel,
StatusLabel: *statusLabel,
SizeLabel: *sizeLabel,
MethodLabel: *methodLabel,
UriLabel: *uriLabel,
TimeLabel: *timeLabel,
Limit: *limit,
IncludesStr: *includes,
ExcludesStr: *excludes,
IncludeStatusesStr: *includeStatuses,
ExcludeStatusesStr: *excludeStatuses,
NoHeaders: *noHeaders,
AggregatesStr: *aggregates,
StartTime: *startTime,
EndTime: *endTime,
StartTimeDuration: *startTimeDuration,
EndTimeDuration: *endTimeDuration,
}

if *max {
Expand Down Expand Up @@ -176,23 +186,59 @@ func main() {
if len(c.Includes) > 0 {
includeRegexps = make([]*regexp.Regexp, 0, len(c.Includes))
for _, pattern := range c.Includes {
includeRegexps = append(includeRegexps, regexp.MustCompile(pattern))
re, rerr := regexp.Compile(pattern)
if rerr != nil {
log.Fatal(err)
}
includeRegexps = append(includeRegexps, re)
}
}

var excludeRegexps []*regexp.Regexp
if len(c.Excludes) > 0 {
excludeRegexps = make([]*regexp.Regexp, 0, len(c.Excludes))
for _, pattern := range c.Excludes {
excludeRegexps = append(excludeRegexps, regexp.MustCompile(pattern))
re, rerr := regexp.Compile(pattern)
if rerr != nil {
log.Fatal(err)
}
excludeRegexps = append(excludeRegexps, re)
}
}

var includeStatusRegexps []*regexp.Regexp
if len(c.IncludeStatuses) > 0 {
includeRegexps = make([]*regexp.Regexp, 0, len(c.Includes))
for _, pattern := range c.IncludeStatuses {
re, rerr := regexp.Compile(pattern)
if rerr != nil {
log.Fatal(err)
}
includeStatusRegexps = append(includeStatusRegexps, re)
}
}

var excludeStatusRegexps []*regexp.Regexp
if len(c.ExcludeStatuses) > 0 {
excludeRegexps = make([]*regexp.Regexp, 0, len(c.Excludes))
for _, pattern := range c.ExcludeStatuses {
re, rerr := regexp.Compile(pattern)
if rerr != nil {
log.Fatal(err)
}
excludeStatusRegexps = append(excludeStatusRegexps, re)
}
}

var aggregateRegexps []*regexp.Regexp
if len(c.Aggregates) > 0 {
aggregateRegexps = make([]*regexp.Regexp, 0, len(c.Aggregates))
for _, pattern := range c.Aggregates {
aggregateRegexps = append(aggregateRegexps, regexp.MustCompile(pattern))
re, rerr := regexp.Compile(pattern)
if rerr != nil {
log.Fatal(err)
}
aggregateRegexps = append(aggregateRegexps, re)
}
}

Expand Down Expand Up @@ -245,7 +291,13 @@ Loop:

resTime, err := strconv.ParseFloat(line[c.ApptimeLabel], 64)
if err != nil {
continue
var reqTime float64
reqTime, err = strconv.ParseFloat(line[c.ReqtimeLabel], 64)
if err != nil {
continue
}

resTime = reqTime
}

bodySize, err := strconv.ParseFloat(line[c.SizeLabel], 64)
Expand Down Expand Up @@ -307,6 +359,31 @@ Loop:
}
}

if len(c.IncludeStatuses) > 0 {
isnotMatched := true
for _, re := range includeStatusRegexps {
if ok := re.Match([]byte(line[c.StatusLabel])); ok && err == nil {
isnotMatched = false
} else if err != nil {
log.Fatal(err)
}
}

if isnotMatched {
continue Loop
}
}

if len(c.ExcludeStatuses) > 0 {
for _, re := range excludeStatusRegexps {
if ok := re.Match([]byte(line[c.StatusLabel])); ok && err == nil {
continue Loop
} else if err != nil {
log.Fatal(err)
}
}
}

isMatched := false
if len(c.Aggregates) > 0 {
for _, re := range aggregateRegexps {
Expand Down
12 changes: 12 additions & 0 deletions util.go
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/olekukonko/tablewriter"
"math"
"os"
"strings"
"time"
)

Expand Down Expand Up @@ -97,3 +98,14 @@ func RequestTimeStddev(requests Percentails, sum, avg float64) (stddev float64)

return math.Sqrt(stddev / n)
}

func Split(val, sep string) []string {
strs := strings.Split(val, sep)
trimedStrs := make([]string, 0, len(strs))

for _, s := range strs {
trimedStrs = append(trimedStrs, strings.Trim(s, " "))
}

return trimedStrs
}

0 comments on commit 43311c9

Please sign in to comment.