diff --git a/.travis.yml b/.travis.yml index 30be94b..e49281f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,10 @@ go: - 1.11.x env: - GO111MODULE=on +before_install: + - go get github.com/mattn/goveralls script: + - $GOPATH/bin/goveralls -service=travis-ci - GOOS=windows go install -mod vendor github.com/liujianping/job - GOOS=linux go install -mod vendor github.com/liujianping/job - GOOS=darwin go install -mod vendor github.com/liujianping/job \ No newline at end of file diff --git a/LICENSE b/LICENSE index d645695..80b8683 100644 --- a/LICENSE +++ b/LICENSE @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright [liujianping.itech@qq.com] [liujianping] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index c630440..64377cb 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ job === +[![GoDoc](https://godoc.org/github.com/liujianping/job?status.svg)](https://godoc.org/github.com/liujianping/job) [![Go Report Card](https://goreportcard.com/badge/github.com/liujianping/job)](https://goreportcard.com/report/github.com/liujianping/job) [![Build Status](https://travis-ci.org/liujianping/job.svg?branch=master)](https://travis-ci.org/liujianping/job) [![Version](https://img.shields.io/github/tag/liujianping/job.svg)](https://github.com/liujianping/job/releases) make your short-term command as a long-term job -[![GoDoc](https://godoc.org/github.com/liujianping/job?status.svg)](https://godoc.org/github.com/liujianping/job) [![Go Report Card](https://goreportcard.com/badge/github.com/liujianping/job)](https://goreportcard.com/report/github.com/liujianping/job) [![Build Status](https://travis-ci.org/liujianping/job.svg?branch=master)](https://travis-ci.org/liujianping/job) [![Version](https://img.shields.io/github/tag/liujianping/job.svg)](https://github.com/liujianping/job/releases) ## Install Brew install @@ -44,24 +44,26 @@ Examples: (job config) $: job -f /path/to/job.yaml Flags: - -e, --cmd-env stringToString job command enviromental variables (default []) - -r, --cmd-retry int job command retry times when failed - -d, --cmd-stdout-discard job command stdout discard ? - -t, --cmd-timeout duration job command timeout duration - -c, --concurrent int job concurrent numbers - -f, --config string job config file path - -G, --guarantee job guarantee mode enable ? - -h, --help help for job - -M, --metadata stringToString job metadata definition (default []) - -N, --name string job name definition - -o, --output job yaml config output enable ? - -i, --repeat-interval duration job repeat interval duration - -w, --repeat-interval-nowait job repeat interval nowait for current command done ? - -n, --repeat-times int job repeat times, 0 means forever (default 1) - -R, --report job reporter enable ? - -s, --schedule string job schedule in crontab format - -T, --timeout duration job timeout duration - -V, --verbose job verbose log enable ? + -e, --cmd-env stringToString job command enviromental variables (default []) + -r, --cmd-retry int job command retry times when failed + -d, --cmd-stdout-discard job command stdout discard ? + -t, --cmd-timeout duration job command timeout duration + -c, --concurrent int job concurrent numbers + -f, --config string job config file path + -G, --guarantee job guarantee mode enable ? + -h, --help help for job + -M, --metadata stringToString job metadata definition (default []) + -N, --name string job name definition + -o, --output job yaml config output enable ? + -i, --repeat-interval duration job repeat interval duration + -n, --repeat-times int job repeat times, 0 means forever (default 1) + -R, --report job report enable ? + -P, --report-push-gateway string job report to prometheus push gateway address + -I, --report-push-interval duration job report to prometheus push gateway interval + -s, --schedule string job schedule in crontab format + -T, --timeout duration job timeout duration + -V, --verbose job verbose log enable ? + -v, --version job version ```` #### Output Job @@ -199,4 +201,16 @@ Code distribution: ## TODO -- metrics report to prometheus push gateway support +- support metrics report to prometheus push gateway +- template variables for commands +- more embend commands support, like: + - grpc + - thrift + - database + - smtp + +## Inspired By + +- [https://github.com/rakyll/hey](https://github.com/rakyll/hey) +- [https://github.com/gavv/httpexpect](https://github.com/gavv/httpexpect) +- [https://github.com/ovh/venom](https://github.com/ovh/venom) \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index 3a48f61..90ec734 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -5,14 +5,13 @@ import ( "fmt" "os" - "github.com/x-mod/httpclient" - "github.com/liujianping/job/config" "github.com/liujianping/job/exec" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/x-mod/errors" + "github.com/x-mod/httpclient" "github.com/x-mod/routine" "gopkg.in/yaml.v2" ) @@ -22,23 +21,6 @@ var ( httpConnections = 0 ) -func prepareJDs(configPath string, command string) ([]*config.JD, error) { - jds := []*config.JD{} - if len(configPath) > 0 { - cfs, err := config.ParseJDs(configPath) - if err != nil { - return nil, err - - } - jds = cfs - } else { - jd := config.CommandJD() - jd.Command.Shell.Name = command - jds = append(jds, jd) - } - return jds, nil -} - func optionJDs(jds []*config.JD, options []config.Option, report bool) { for _, jd := range jds { for _, opt := range options { @@ -85,17 +67,19 @@ func withVerbose(ctx context.Context) context.Context { return ctx } -func withTransport(ctx context.Context) context.Context { - if httpConnections > 0 { - return exec.WithTransport(ctx, httpclient.NewHTTPTransport(httpclient.MaxIdleConnections(httpConnections))) - } - return ctx -} - //Main func func Main(cmd *cobra.Command, args []string) { - jds, err := prepareJDs(viper.GetString("config"), args[0]) - exitForErr(err) + jds := []*config.JD{} + if len(viper.GetString("config")) > 0 { + cfs, err := config.ParseJDs(viper.GetString("config")) + exitForErr(err) + jds = append(jds, cfs...) + } + if len(args) > 0 { + jd := config.CommandJD() + jd.Command.Shell.Name = args[0] + jds = append(jds, jd) + } options := []config.Option{} options = append(options, config.Name(viper.GetString("name"))) @@ -142,10 +126,19 @@ func Main(cmd *cobra.Command, args []string) { }) mainOptions = append(mainOptions, routine.Prepare(prepare), routine.Cleanup(cleanup)) } + //context + ctx := context.Background() + if httpConnections > 0 { + httpclient.DefaultMaxConnsPerHost = httpConnections + httpclient.DefaultMaxIdleConnsPerHost = httpConnections + exec.WithTransport(ctx, httpclient.New().GetTransport()) + } + jobs := NewJOBs(jds, reporter) jobs.Sort() + exitForErr(routine.Main( - withVerbose(withTransport(context.TODO())), + withVerbose(ctx), jobs, mainOptions...)) } diff --git a/cmd/root.go b/cmd/root.go index ca353f2..bd9c5e4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -82,6 +82,7 @@ func init() { rootCmd.Flags().StringP("report-push-gateway", "P", "", "job report to prometheus push gateway address") rootCmd.Flags().DurationP("report-push-interval", "I", 0*time.Second, "job report to prometheus push gateway interval") rootCmd.Flags().BoolP("output", "o", false, "job yaml config output enable ?") + // rootCmd.Flags().StringP("output-command-format", "F", "shell", "job yaml config output command format ?") rootCmd.Flags().BoolP("verbose", "V", false, "job verbose log enable ?") rootCmd.Flags().BoolP("version", "v", false, "job version") diff --git a/etc/job.yaml b/etc/job.yaml index afd3cb8..05e4496 100644 --- a/etc/job.yaml +++ b/etc/job.yaml @@ -18,7 +18,7 @@ Job: times: 2 interval: 100ms timeout: 1h - report: true + report: false order: precondition: [""] weight: 4 @@ -32,24 +32,23 @@ Job: stdout: true http: request: - url: "http://localhost:8090/v1/demo.Demo/Hello" - method: POST - headers: - Content-Type: application/json - X-CHIRPEUR-IGNORE: f9mBRGjhuZX9 - body: - json: - hello: "demo" - person: - name: jay - age: 39 + url: "https://github.com" + method: GET + # headers: + # Content-Type: application/json + # body: + # json: + # hello: "demo" + # person: + # name: jay + # age: 39 crontab: "" concurrent: 2 repeat: times: 3 interval: "10ms" timeout: 1h - report: true + report: false order: weight: 3 precondition: diff --git a/exec/http.go b/exec/http.go index 171e505..4e0b0e9 100644 --- a/exec/http.go +++ b/exec/http.go @@ -85,21 +85,21 @@ func (h *HTTPCommand) Execute(ctx context.Context) error { clientOpts = append(clientOpts, httpclient.Request( httpclient.NewRequestBuilder(opts...), )) - if !h.cmd.Stdout { - clientOpts = append(clientOpts, httpclient.Response( - httpclient.NewDiscardResponse(), - )) - } else { + if h.cmd.Stdout { clientOpts = append(clientOpts, httpclient.Response( httpclient.NewDumpResponse(), )) } + if tr, ok := TransportFrom(ctx); ok { clientOpts = append(clientOpts, httpclient.Transport(tr)) } if h.cmd.Timeout > 0 { clientOpts = append(clientOpts, httpclient.Timeout(h.cmd.Timeout)) } + if h.cmd.Retry > 1 { + clientOpts = append(clientOpts, httpclient.Retry(h.cmd.Retry)) + } client := httpclient.New(clientOpts...) return client.Execute(ctx) } diff --git a/go.mod b/go.mod index 3e5369b..bd2540b 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/spf13/cobra v0.0.3 github.com/spf13/viper v1.3.2 github.com/x-mod/errors v0.1.2 - github.com/x-mod/httpclient v0.1.2 + github.com/x-mod/httpclient v0.2.1 github.com/x-mod/routine v1.0.7 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index f4e1b3f..e866448 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -79,6 +80,10 @@ github.com/x-mod/errors v0.1.2 h1:zV3rvurQY6R2c0reAKVQKfq5OL/xxZBHhRQMCSx9FrQ= github.com/x-mod/errors v0.1.2/go.mod h1:d+HrEt85NDHN0I4yJ9pQjy1JZEhPsSNou3sIFu5vXOk= github.com/x-mod/httpclient v0.1.2 h1:OFd6v3yidoJLdOY5XXEaYGG/PUJquftzfzTQf5da368= github.com/x-mod/httpclient v0.1.2/go.mod h1:2ZsKGweQf2SzJcO+ADqYa2KfoDfVB4pzZcrVcWofRfw= +github.com/x-mod/httpclient v0.2.0 h1:mLkEb5aLSp4q07uf3sgtd+e0d1nu9jNESV38rt2NigU= +github.com/x-mod/httpclient v0.2.0/go.mod h1:2ZsKGweQf2SzJcO+ADqYa2KfoDfVB4pzZcrVcWofRfw= +github.com/x-mod/httpclient v0.2.1 h1:rVo9gaCmwbFzRHNN9/E1i2XPP8t369p7gSf8pZyB3B0= +github.com/x-mod/httpclient v0.2.1/go.mod h1:UDXsStYze85qWaiNqMUX7kjfNav2IYrtNbclHR2ATWQ= github.com/x-mod/routine v1.0.7 h1:AyI49i2gg8eCftEyxLw3nXGwBVQ6MQoK1RCauG22XW4= github.com/x-mod/routine v1.0.7/go.mod h1:q3ZiZdpXpY/XgDiETdvSUspjpKfiXXCI9PTPy/gFehE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=