├── .gitignore ├── Godeps ├── Godeps.json └── Readme ├── LICENCE ├── README.md ├── main.go ├── metrics ├── metric.go ├── metric_test.go └── metrics_suite_test.go ├── processors ├── container_metric_processor.go ├── container_metric_processor_test.go ├── counter_processor.go ├── counter_processor_test.go ├── heartbeat_processor.go ├── heartbeat_processor_test.go ├── http_start_stop_processor.go ├── http_start_stop_processor_test.go ├── processor.go ├── processors_suite_test.go ├── value_metric_processor.go └── value_metric_processor_test.go ├── token └── token.go ├── validators.go └── vendor ├── github.com ├── alecthomas │ ├── template │ │ ├── README.md │ │ ├── doc.go │ │ ├── exec.go │ │ ├── funcs.go │ │ ├── helper.go │ │ ├── parse │ │ │ ├── lex.go │ │ │ ├── node.go │ │ │ └── parse.go │ │ └── template.go │ └── units │ │ ├── COPYING │ │ ├── README.md │ │ ├── bytes.go │ │ ├── doc.go │ │ ├── si.go │ │ └── util.go ├── cloudfoundry-incubator │ └── uaago │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ └── client.go ├── cloudfoundry │ └── noaa │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── consumer.go │ │ ├── debug_printer.go │ │ ├── errors │ │ ├── error_codes.go │ │ └── unauthorized_error.go │ │ ├── events │ │ ├── envelope.pb.go │ │ ├── error.pb.go │ │ ├── event.go │ │ ├── generate-events.sh │ │ ├── heartbeat.pb.go │ │ ├── http.pb.go │ │ ├── log.pb.go │ │ ├── metric.pb.go │ │ └── uuid.pb.go │ │ ├── sort_container_metrics.go │ │ └── sort_recent.go ├── gogo │ └── protobuf │ │ ├── LICENSE │ │ └── proto │ │ ├── Makefile │ │ ├── clone.go │ │ ├── decode.go │ │ ├── decode_gogo.go │ │ ├── encode.go │ │ ├── encode_gogo.go │ │ ├── equal.go │ │ ├── extensions.go │ │ ├── extensions_gogo.go │ │ ├── lib.go │ │ ├── lib_gogo.go │ │ ├── message_set.go │ │ ├── pointer_reflect.go │ │ ├── pointer_unsafe.go │ │ ├── pointer_unsafe_gogo.go │ │ ├── properties.go │ │ ├── properties_gogo.go │ │ ├── skip_gogo.go │ │ ├── text.go │ │ ├── text_gogo.go │ │ └── text_parser.go ├── gorilla │ └── websocket │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── README.md │ │ ├── client.go │ │ ├── conn.go │ │ ├── doc.go │ │ ├── json.go │ │ ├── server.go │ │ └── util.go └── quipo │ └── statsd │ ├── LICENSE │ ├── README.md │ ├── bufferedclient.go │ ├── client.go │ ├── event │ ├── absolute.go │ ├── fabsolute.go │ ├── fgauge.go │ ├── fgaugedelta.go │ ├── gauge.go │ ├── gaugedelta.go │ ├── increment.go │ ├── interface.go │ ├── precisiontiming.go │ ├── timing.go │ └── total.go │ ├── interface.go │ └── noopclient.go └── gopkg.in └── alecthomas └── kingpin.v2 ├── .travis.yml ├── COPYING ├── README.md ├── app.go ├── args.go ├── cmd.go ├── doc.go ├── flags.go ├── global.go ├── guesswidth.go ├── guesswidth_unix.go ├── model.go ├── parser.go ├── parsers.go ├── repeated.go ├── repeated.json ├── templates.go ├── usage.go └── values.go /.gitignore: -------------------------------------------------------------------------------- 1 | bin/* 2 | graphite-nozzle 3 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/pivotal-cf/graphite-nozzle", 3 | "GoVersion": "go1.6", 4 | "GodepVersion": "v79", 5 | "Packages": [ 6 | "." 7 | ], 8 | "Deps": [ 9 | { 10 | "ImportPath": "github.com/alecthomas/template", 11 | "Rev": "b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0" 12 | }, 13 | { 14 | "ImportPath": "github.com/alecthomas/template/parse", 15 | "Rev": "b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0" 16 | }, 17 | { 18 | "ImportPath": "github.com/alecthomas/units", 19 | "Rev": "6b4e7dc5e3143b85ea77909c72caf89416fc2915" 20 | }, 21 | { 22 | "ImportPath": "github.com/cloudfoundry-incubator/uaago", 23 | "Rev": "1627a524bb8637bae9bbb61c42593db3e436d08f" 24 | }, 25 | { 26 | "ImportPath": "github.com/cloudfoundry/noaa", 27 | "Rev": "4f20c9fdf29bf4790685685c2701d6b00f30b99c" 28 | }, 29 | { 30 | "ImportPath": "github.com/cloudfoundry/noaa/errors", 31 | "Rev": "4f20c9fdf29bf4790685685c2701d6b00f30b99c" 32 | }, 33 | { 34 | "ImportPath": "github.com/cloudfoundry/noaa/events", 35 | "Rev": "4f20c9fdf29bf4790685685c2701d6b00f30b99c" 36 | }, 37 | { 38 | "ImportPath": "github.com/gogo/protobuf/proto", 39 | "Comment": "v0.1-59-g0414533", 40 | "Rev": "04145330265d088c218da8916c50eab3814c76a0" 41 | }, 42 | { 43 | "ImportPath": "github.com/gorilla/websocket", 44 | "Rev": "9007e29a7c93fc3dcebbdbf742ce0efaf19e6510" 45 | }, 46 | { 47 | "ImportPath": "github.com/quipo/statsd", 48 | "Rev": "39c3fe59a6c334d5aefddf41f3c16595301c80e1" 49 | }, 50 | { 51 | "ImportPath": "github.com/quipo/statsd/event", 52 | "Rev": "39c3fe59a6c334d5aefddf41f3c16595301c80e1" 53 | }, 54 | { 55 | "ImportPath": "gopkg.in/alecthomas/kingpin.v2", 56 | "Comment": "v2.0.8", 57 | "Rev": "a7274600e78d26876a32d8b293cbb0cd324f61a2" 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # graphite-nozzle 2 | 3 | This library consumes events off the Cloud Foundry Firehose, processes them, and then sends them off to a StatsD endpoint. Note that it is still being developed and shouldn't be considered production-ready. 4 | 5 | ## Getting Started 6 | 7 | * A user who has access to the Cloud Foundry Firehose configured in 8 | your manifest 9 | 10 | ``` 11 | properties: 12 | uaa: 13 | clients: 14 | graphite-nozzle: 15 | access-token-validity: 1209600 16 | authorized-grant-types: authorization_code,client_credentials,refresh_token 17 | override: true 18 | secret: 19 | scope: openid,oauth.approvals,doppler.firehose 20 | authorities: oauth.login,doppler.firehose 21 | 22 | ``` 23 | 24 | * A Graphite and StatsD server (see [here](https://github.com/CloudCredo/graphite-statsd-boshrelease) for a Graphite/StatsD BOSH release). 25 | * Golang installed and configured (see [here](https://golang.org/doc/install) for a tutorial on how to do this). 26 | * godep (see [here](https://github.com/tools/godep) for installation instructions). 27 | 28 | Once you've met all the prerequisites, you'll need to download the library and install the dependencies: 29 | 30 | ``` 31 | mkdir -p $GOPATH/src/github.com/pivotal-cf 32 | cd $GOPATH/src/github.com/pivotal-cf 33 | git clone git@github.com:pivotal-cf/graphite-nozzle.git 34 | cd graphite-nozzle 35 | godep restore 36 | godep go build 37 | ``` 38 | 39 | Finally, run the app: 40 | 41 | ``` 42 | ./graphite-nozzle --help 43 | ``` 44 | 45 | ## Metrics Overview 46 | 47 | Following is a brief overview of the metrics that graphite-nozzle will extract from the Firehose and send off to Graphite. 48 | 49 | ### CounterEvent 50 | 51 | CounterEvents represent the increment of a counter. graphite-nozzle will send these through to StatsD as a Counter metric. These metrics appear in the Graphite Web UI under `Graphite.stats.counters..ops.`. 52 | 53 | ### ContainerMetric 54 | 55 | CPU, RAM and disk usage metrics for app containers will be sent through to StatsD as a Gauge metric. Note that ContainerMetric Events will not appear on the Firehose by default (at the moment) so you'll need to run a separate app to generate these. There is a sample ContainerMetric-generating app included in the noaa repository [here](https://github.com/cloudfoundry/noaa/tree/master/container_metrics_sample). These metrics appear in the Graphite Web UI under `Graphite.stats.gauges..apps...`. 56 | 57 | ### Heartbeat 58 | 59 | Heartbeat Events indicate liveness of the emitter and provide counts of the number of Events processed by the emitter. These metrics get sent through to StatsD as Gauge metrics. graphite-nozzle also increments a Counter metric for each component whenever a Heartbeat Event is received. These metrics appear in the Graphite Web UI under `Graphite.stats.gauges..ops..heartbeats.*`. 60 | 61 | ### HTTPStartStop 62 | 63 | HTTP requests passing through the Cloud Foundry routers get recorded as HTTPStartStop Events. graphite-nozzle takes these events and extracts useful information, such as the response time and status code. These metrics are then sent through to StatsD. The following table gives an overview of the HTTP metrics graphite-nozzle handles: 64 | 65 | | Name | Description | StatsD Metric Type | 66 | | ---- | ----------- | ------------------ | 67 | | HttpStartStopResponseTime | HTTP response times in milliseconds | Timer | 68 | | HttpStartStopStatusCodeCount | A count of each HTTP status code | Counter | 69 | 70 | 71 | For all HTTPStartStop Events, the hostname is extracted from the URI and used in the Metric name. `.` characters are also replaced with `_` characters. This means that, for example, HTTP requests to `http://api.mycf.com/v2/info` will be recorded under `http://api_mycf_com` in the Graphite web UI. This is to avoid polluting the UI with hundreds of endpoints. 72 | 73 | Also note that 2 HTTPStartStop Events are generated per HTTP request to an application running in Cloud Foundry. graphite-nozzle will only increment the StatusCode counter for the HttpStartStop Events where `PeerType` == `PeerType_Client`. This is in order to accurately graph the incoming HTTP requests. 74 | 75 | ### ValueMetric 76 | 77 | Any ValueMetric Event that appears on the Firehose will be sent through to StatsD as a Gauge metric. This includes metrics such as numCPUS, numGoRoutines, memoryStats, etc. These metrics appear in the Graphite web UI under `Graphite.stats.gauges..ops.`. 78 | 79 | ## Testing 80 | 81 | To run the test suite, first make sure you have ginkgo and gomega installed: 82 | 83 | ``` 84 | go get github.com/onsi/ginkgo/ginkgo 85 | go get github.com/onsi/gomega 86 | ``` 87 | 88 | Then run `ginkgo -r` from root of this repository. 89 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // Inspired by the noaa firehose sample script 4 | // https://github.com/cloudfoundry/noaa/blob/master/firehose_sample/main.go 5 | 6 | import ( 7 | "crypto/tls" 8 | "fmt" 9 | "os" 10 | 11 | "github.com/cloudfoundry/noaa" 12 | "github.com/cloudfoundry/noaa/events" 13 | "github.com/pivotal-cf/graphite-nozzle/metrics" 14 | "github.com/pivotal-cf/graphite-nozzle/processors" 15 | "github.com/pivotal-cf/graphite-nozzle/token" 16 | "github.com/quipo/statsd" 17 | "gopkg.in/alecthomas/kingpin.v2" 18 | ) 19 | 20 | var ( 21 | dopplerEndpoint = kingpin.Flag("doppler-endpoint", "Doppler endpoint").Default("wss://doppler.10.244.0.34.xip.io:443").OverrideDefaultFromEnvar("DOPPLER_ENDPOINT").String() 22 | uaaEndpoint = kingpin.Flag("uaa-endpoint", "UAA endpoint").Default("https://uaa.10.244.0.34.xip.io").OverrideDefaultFromEnvar("UAA_ENDPOINT").String() 23 | subscriptionId = kingpin.Flag("subscription-id", "Id for the subscription.").Default("firehose").OverrideDefaultFromEnvar("SUBSCRIPTION_ID").String() 24 | statsdEndpoint = kingpin.Flag("statsd-endpoint", "Statsd endpoint").Default("10.244.11.2:8125").OverrideDefaultFromEnvar("STATSD_ENDPOINT").String() 25 | statsdPrefix = kingpin.Flag("statsd-prefix", "Statsd prefix").Default("mycf.").OverrideDefaultFromEnvar("STATSD_PREFIX").String() 26 | statsdProtocol = kingpin.Flag("statsd-protocol", "Statsd protocol, either udp or tcp").Default("udp").OverrideDefaultFromEnvar("STATSD_PROTOCOL").String() 27 | prefixJob = kingpin.Flag("prefix-job", "Prefix metric names with job.index").Default("false").OverrideDefaultFromEnvar("PREFIX_JOB").Bool() 28 | username = kingpin.Flag("username", "Firehose username.").Default("admin").OverrideDefaultFromEnvar("FIREHOSE_USERNAME").String() 29 | password = kingpin.Flag("password", "Firehose password.").Default("admin").OverrideDefaultFromEnvar("FIREHOSE_PASSWORD").String() 30 | skipSSLValidation = kingpin.Flag("skip-ssl-validation", "Please don't").Default("false").OverrideDefaultFromEnvar("SKIP_SSL_VALIDATION").Bool() 31 | debug = kingpin.Flag("debug", "Enable debug mode. This disables forwarding to statsd and prints to stdout").Default("false").OverrideDefaultFromEnvar("DEBUG").Bool() 32 | ) 33 | 34 | func main() { 35 | kingpin.Parse() 36 | 37 | err := ValidateStatsdProtocol(*statsdProtocol) 38 | if err != nil { 39 | fmt.Println(err) 40 | os.Exit(-1) 41 | } 42 | 43 | tokenFetcher := &token.UAATokenFetcher{ 44 | UaaUrl: *uaaEndpoint, 45 | Username: *username, 46 | Password: *password, 47 | InsecureSSLSkipVerify: *skipSSLValidation, 48 | } 49 | 50 | authToken, err := tokenFetcher.FetchAuthToken() 51 | if err != nil { 52 | fmt.Println(err) 53 | os.Exit(-1) 54 | } 55 | 56 | consumer := noaa.NewConsumer(*dopplerEndpoint, &tls.Config{InsecureSkipVerify: *skipSSLValidation}, nil) 57 | 58 | httpStartStopProcessor := processors.NewHttpStartStopProcessor() 59 | valueMetricProcessor := processors.NewValueMetricProcessor() 60 | containerMetricProcessor := processors.NewContainerMetricProcessor() 61 | heartbeatProcessor := processors.NewHeartbeatProcessor() 62 | counterProcessor := processors.NewCounterProcessor() 63 | 64 | //Initialising statsd sender 65 | sender := statsd.NewStatsdClient(*statsdEndpoint, *statsdPrefix) 66 | 67 | switch statsdProtocol := *statsdProtocol; statsdProtocol { 68 | case "udp": 69 | sender.CreateSocket() 70 | fmt.Println("Using udp protocol for statsd") 71 | case "tcp": 72 | sender.CreateTCPSocket() 73 | fmt.Println("Using tcp protocol for statsd") 74 | } 75 | 76 | var processedMetrics []metrics.Metric 77 | var proc_err error 78 | 79 | msgChan := make(chan *events.Envelope) 80 | go func() { 81 | defer close(msgChan) 82 | errorChan := make(chan error) 83 | go consumer.Firehose(*subscriptionId, authToken, msgChan, errorChan, nil) 84 | 85 | for err := range errorChan { 86 | fmt.Fprintf(os.Stderr, "%v\n", err.Error()) 87 | } 88 | }() 89 | 90 | for msg := range msgChan { 91 | eventType := msg.GetEventType() 92 | 93 | // graphite-nozzle can handle CounterEvent, ContainerMetric, Heartbeat, 94 | // HttpStartStop and ValueMetric events 95 | switch eventType { 96 | case events.Envelope_ContainerMetric: 97 | processedMetrics, proc_err = containerMetricProcessor.Process(msg) 98 | case events.Envelope_CounterEvent: 99 | processedMetrics, proc_err = counterProcessor.Process(msg) 100 | case events.Envelope_Heartbeat: 101 | processedMetrics, proc_err = heartbeatProcessor.Process(msg) 102 | case events.Envelope_HttpStartStop: 103 | processedMetrics, proc_err = httpStartStopProcessor.Process(msg) 104 | case events.Envelope_ValueMetric: 105 | processedMetrics, proc_err = valueMetricProcessor.Process(msg) 106 | default: 107 | // do nothing 108 | } 109 | 110 | if proc_err != nil { 111 | fmt.Fprintf(os.Stderr, "%v\n", proc_err.Error()) 112 | } else { 113 | if !*debug { 114 | if len(processedMetrics) > 0 { 115 | for _, metric := range processedMetrics { 116 | var prefix string 117 | if *prefixJob { 118 | prefix = msg.GetJob() + "." + msg.GetIndex() 119 | } 120 | metric.Send(sender, prefix) 121 | } 122 | } 123 | } else { 124 | for _, msg := range processedMetrics { 125 | fmt.Println(msg) 126 | } 127 | } 128 | } 129 | processedMetrics = nil 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /metrics/metric.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import "time" 4 | 5 | type StatsdClient interface { 6 | Gauge(stat string, value int64) error 7 | FGauge(stat string, value float64) error 8 | Incr(stat string, count int64) error 9 | Timing(string, int64) error 10 | PrecisionTiming(stat string, delta time.Duration) error 11 | } 12 | 13 | type Metric interface { 14 | Send(StatsdClient, string) error 15 | } 16 | 17 | type CounterMetric struct { 18 | Stat string 19 | Value int64 20 | } 21 | 22 | type GaugeMetric struct { 23 | Stat string 24 | Value int64 25 | } 26 | 27 | type FGaugeMetric struct { 28 | Stat string 29 | Value float64 30 | } 31 | 32 | type TimingMetric struct { 33 | Stat string 34 | Value int64 35 | } 36 | 37 | type PrecisionTimingMetric struct { 38 | Stat string 39 | Value time.Duration 40 | } 41 | 42 | func NewCounterMetric(stat string, value int64) *CounterMetric { 43 | return &CounterMetric{ 44 | Stat: stat, 45 | Value: value, 46 | } 47 | } 48 | 49 | func NewGaugeMetric(stat string, value int64) *GaugeMetric { 50 | return &GaugeMetric{ 51 | Stat: stat, 52 | Value: value, 53 | } 54 | } 55 | 56 | func NewFGaugeMetric(stat string, value float64) *FGaugeMetric { 57 | return &FGaugeMetric{ 58 | Stat: stat, 59 | Value: value, 60 | } 61 | } 62 | 63 | func NewTimingMetric(stat string, value int64) *TimingMetric { 64 | return &TimingMetric{ 65 | Stat: stat, 66 | Value: value, 67 | } 68 | } 69 | 70 | func NewPrecisionTimingMetric(stat string, value time.Duration) *PrecisionTimingMetric { 71 | return &PrecisionTimingMetric{ 72 | Stat: stat, 73 | Value: value, 74 | } 75 | } 76 | 77 | // prefixName applies a prefix to a metric name if the prefix is not empty. 78 | func prefixName(prefix, name string) string { 79 | if prefix != "" { 80 | name = prefix + "." + name 81 | } 82 | return name 83 | } 84 | 85 | func (m CounterMetric) Send(statsdClient StatsdClient, prefix string) error { 86 | return statsdClient.Incr(prefixName(prefix, m.Stat), m.Value) 87 | } 88 | 89 | func (m GaugeMetric) Send(statsdClient StatsdClient, prefix string) error { 90 | return statsdClient.Gauge(prefixName(prefix, m.Stat), m.Value) 91 | } 92 | 93 | func (m FGaugeMetric) Send(statsdClient StatsdClient, prefix string) error { 94 | return statsdClient.FGauge(prefixName(prefix, m.Stat), m.Value) 95 | } 96 | 97 | func (m TimingMetric) Send(statsdClient StatsdClient, prefix string) error { 98 | return statsdClient.Timing(prefixName(prefix, m.Stat), m.Value) 99 | } 100 | 101 | func (m PrecisionTimingMetric) Send(statsdClient StatsdClient, prefix string) error { 102 | return statsdClient.PrecisionTiming(prefixName(prefix, m.Stat), m.Value) 103 | } 104 | -------------------------------------------------------------------------------- /metrics/metrics_suite_test.go: -------------------------------------------------------------------------------- 1 | package metrics_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestMetric(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Metrics Suite") 13 | } 14 | -------------------------------------------------------------------------------- /processors/container_metric_processor.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "github.com/pivotal-cf/graphite-nozzle/metrics" 6 | "strconv" 7 | ) 8 | 9 | type ContainerMetricProcessor struct{} 10 | 11 | func NewContainerMetricProcessor() *ContainerMetricProcessor { 12 | return &ContainerMetricProcessor{} 13 | } 14 | 15 | func (p *ContainerMetricProcessor) Process(e *events.Envelope) ([]metrics.Metric, error) { 16 | processedMetrics := make([]metrics.Metric, 3) 17 | containerMetricEvent := e.GetContainerMetric() 18 | 19 | processedMetrics[0] = metrics.Metric(p.ProcessContainerMetricCPU(containerMetricEvent)) 20 | processedMetrics[1] = metrics.Metric(p.ProcessContainerMetricMemory(containerMetricEvent)) 21 | processedMetrics[2] = metrics.Metric(p.ProcessContainerMetricDisk(containerMetricEvent)) 22 | 23 | return processedMetrics, nil 24 | } 25 | 26 | func (p *ContainerMetricProcessor) ProcessContainerMetricCPU(e *events.ContainerMetric) metrics.GaugeMetric { 27 | appID := e.GetApplicationId() 28 | instanceIndex := strconv.Itoa(int(e.GetInstanceIndex())) 29 | 30 | stat := "apps." + appID + ".cpu." + instanceIndex 31 | metric := metrics.NewGaugeMetric(stat, int64(e.GetCpuPercentage())) 32 | 33 | return *metric 34 | } 35 | 36 | func (p *ContainerMetricProcessor) ProcessContainerMetricMemory(e *events.ContainerMetric) metrics.GaugeMetric { 37 | appID := e.GetApplicationId() 38 | instanceIndex := strconv.Itoa(int(e.GetInstanceIndex())) 39 | 40 | stat := "apps." + appID + ".memoryBytes." + instanceIndex 41 | metric := metrics.NewGaugeMetric(stat, int64(e.GetMemoryBytes())) 42 | 43 | return *metric 44 | } 45 | 46 | func (p *ContainerMetricProcessor) ProcessContainerMetricDisk(e *events.ContainerMetric) metrics.GaugeMetric { 47 | appID := e.GetApplicationId() 48 | instanceIndex := strconv.Itoa(int(e.GetInstanceIndex())) 49 | 50 | stat := "apps." + appID + ".diskBytes." + instanceIndex 51 | metric := metrics.NewGaugeMetric(stat, int64(e.GetDiskBytes())) 52 | 53 | return *metric 54 | } 55 | -------------------------------------------------------------------------------- /processors/container_metric_processor_test.go: -------------------------------------------------------------------------------- 1 | package processors_test 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | . "github.com/pivotal-cf/graphite-nozzle/processors" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | ) 10 | 11 | var _ = Describe("ContainerMetricProcessor", func() { 12 | var ( 13 | processor *ContainerMetricProcessor 14 | event *events.Envelope 15 | containerMetricEvent *events.ContainerMetric 16 | ) 17 | 18 | BeforeEach(func() { 19 | processor = NewContainerMetricProcessor() 20 | 21 | applicationId := "60a13b0f-fce7-4c02-b92a-d43d583877ed" 22 | instanceIndex := int32(0) 23 | cpuPercentage := float64(70.75) 24 | memoryBytes := uint64(1024) 25 | diskBytes := uint64(2048) 26 | 27 | containerMetricEvent = &events.ContainerMetric{ 28 | ApplicationId: &applicationId, 29 | InstanceIndex: &instanceIndex, 30 | CpuPercentage: &cpuPercentage, 31 | MemoryBytes: &memoryBytes, 32 | DiskBytes: &diskBytes, 33 | } 34 | 35 | event = &events.Envelope{ 36 | ContainerMetric: containerMetricEvent, 37 | } 38 | }) 39 | 40 | Describe("#Process", func() { 41 | It("returns a Metric for each of the ProcessContainerMetric* methods", func() { 42 | processedMetrics, err := processor.Process(event) 43 | 44 | Expect(err).To(BeNil()) 45 | Expect(processedMetrics).To(HaveLen(3)) 46 | }) 47 | }) 48 | 49 | Describe("#ProcessContainerMetricCPU", func() { 50 | It("formats the Stat string to include the ContainerMetric's app ID and instance index", func() { 51 | metric := processor.ProcessContainerMetricCPU(containerMetricEvent) 52 | 53 | Expect(metric.Stat).To(Equal("apps.60a13b0f-fce7-4c02-b92a-d43d583877ed.cpu.0")) 54 | }) 55 | 56 | It("sets the Metric Value to the value of the ContainerMetric cpuPercentage", func() { 57 | metric := processor.ProcessContainerMetricCPU(containerMetricEvent) 58 | 59 | Expect(metric.Value).To(Equal(int64(70))) 60 | }) 61 | }) 62 | 63 | Describe("#ProcessContainerMetricMemory", func() { 64 | It("formats the Stat string to include the ContainerMetric's app ID and instance index", func() { 65 | metric := processor.ProcessContainerMetricMemory(containerMetricEvent) 66 | 67 | Expect(metric.Stat).To(Equal("apps.60a13b0f-fce7-4c02-b92a-d43d583877ed.memoryBytes.0")) 68 | }) 69 | 70 | It("sets the Metric Value to the value of the ContainerMetric memoryBytes", func() { 71 | metric := processor.ProcessContainerMetricMemory(containerMetricEvent) 72 | 73 | Expect(metric.Value).To(Equal(int64(1024))) 74 | }) 75 | }) 76 | 77 | Describe("#ProcessContainerMetricDisk", func() { 78 | It("formats the Stat string to include the ContainerMetric's app ID and instance index", func() { 79 | metric := processor.ProcessContainerMetricDisk(containerMetricEvent) 80 | 81 | Expect(metric.Stat).To(Equal("apps.60a13b0f-fce7-4c02-b92a-d43d583877ed.diskBytes.0")) 82 | }) 83 | 84 | It("sets the Metric Value to the value of the ContainerMetric diskBytes", func() { 85 | metric := processor.ProcessContainerMetricDisk(containerMetricEvent) 86 | 87 | Expect(metric.Value).To(Equal(int64(2048))) 88 | }) 89 | }) 90 | 91 | }) 92 | -------------------------------------------------------------------------------- /processors/counter_processor.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "github.com/pivotal-cf/graphite-nozzle/metrics" 6 | ) 7 | 8 | type CounterProcessor struct{} 9 | 10 | func NewCounterProcessor() *CounterProcessor { 11 | return &CounterProcessor{} 12 | } 13 | 14 | func (p *CounterProcessor) Process(e *events.Envelope) ([]metrics.Metric, error) { 15 | processedMetrics := make([]metrics.Metric, 1) 16 | counterEvent := e.GetCounterEvent() 17 | 18 | processedMetrics[0] = metrics.Metric(p.ProcessCounter(counterEvent)) 19 | 20 | return processedMetrics, nil 21 | } 22 | 23 | func (p *CounterProcessor) ProcessCounter(event *events.CounterEvent) *metrics.CounterMetric { 24 | stat := "ops." + event.GetName() 25 | metric := metrics.NewCounterMetric(stat, int64(event.GetDelta())) 26 | 27 | return metric 28 | } 29 | -------------------------------------------------------------------------------- /processors/counter_processor_test.go: -------------------------------------------------------------------------------- 1 | package processors_test 2 | 3 | import ( 4 | . "github.com/pivotal-cf/graphite-nozzle/processors" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | 9 | "github.com/cloudfoundry/noaa/events" 10 | ) 11 | 12 | var _ = Describe("CounterEventProcessor", func() { 13 | var ( 14 | processor *CounterProcessor 15 | event *events.Envelope 16 | counterEvent *events.CounterEvent 17 | ) 18 | 19 | BeforeEach(func() { 20 | processor = NewCounterProcessor() 21 | 22 | name := "pollCount" 23 | delta := uint64(1) 24 | 25 | counterEvent = &events.CounterEvent{ 26 | Name: &name, 27 | Delta: &delta, 28 | } 29 | 30 | event = &events.Envelope{ 31 | CounterEvent: counterEvent, 32 | } 33 | }) 34 | 35 | Describe("#Process", func() { 36 | It("returns a Metric for each of the ProcessCounter* methods", func() { 37 | processedMetrics, err := processor.Process(event) 38 | 39 | Expect(err).To(BeNil()) 40 | Expect(processedMetrics).To(HaveLen(1)) 41 | }) 42 | }) 43 | 44 | Describe("#ProcessCounter", func() { 45 | It("formats the Stat string to include the Counter's name", func() { 46 | metric := processor.ProcessCounter(counterEvent) 47 | 48 | Expect(metric.Stat).To(Equal("ops." + "pollCount")) 49 | }) 50 | 51 | It("sets the Metric Value to the value of the Counter's delta", func() { 52 | metric := processor.ProcessCounter(counterEvent) 53 | 54 | Expect(metric.Value).To(Equal(int64(1))) 55 | }) 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /processors/heartbeat_processor.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "github.com/pivotal-cf/graphite-nozzle/metrics" 6 | ) 7 | 8 | type HeartbeatProcessor struct{} 9 | 10 | func NewHeartbeatProcessor() *HeartbeatProcessor { 11 | return &HeartbeatProcessor{} 12 | } 13 | 14 | func (p *HeartbeatProcessor) Process(e *events.Envelope) ([]metrics.Metric, error) { 15 | processedMetrics := make([]metrics.Metric, 4) 16 | heartbeat := e.GetHeartbeat() 17 | origin := e.GetOrigin() 18 | 19 | processedMetrics[0] = metrics.Metric(p.ProcessHeartbeatCount(heartbeat, origin)) 20 | processedMetrics[1] = metrics.Metric(p.ProcessHeartbeatEventsSentCount(heartbeat, origin)) 21 | processedMetrics[2] = metrics.Metric(p.ProcessHeartbeatEventsReceivedCount(heartbeat, origin)) 22 | processedMetrics[3] = metrics.Metric(p.ProcessHeartbeatEventsErrorCount(heartbeat, origin)) 23 | 24 | return processedMetrics, nil 25 | } 26 | 27 | func (p *HeartbeatProcessor) ProcessHeartbeatCount(e *events.Heartbeat, origin string) *metrics.CounterMetric { 28 | stat := "ops." + origin + ".heartbeats.count" 29 | metric := metrics.NewCounterMetric(stat, int64(1)) 30 | 31 | return metric 32 | } 33 | 34 | func (p *HeartbeatProcessor) ProcessHeartbeatEventsSentCount(e *events.Heartbeat, origin string) *metrics.GaugeMetric { 35 | stat := "ops." + origin + ".heartbeats.eventsSentCount" 36 | metric := metrics.NewGaugeMetric(stat, int64(e.GetSentCount())) 37 | 38 | return metric 39 | } 40 | 41 | func (p *HeartbeatProcessor) ProcessHeartbeatEventsReceivedCount(e *events.Heartbeat, origin string) *metrics.GaugeMetric { 42 | stat := "ops." + origin + ".heartbeats.eventsReceivedCount" 43 | metric := metrics.NewGaugeMetric(stat, int64(e.GetReceivedCount())) 44 | 45 | return metric 46 | } 47 | 48 | func (p *HeartbeatProcessor) ProcessHeartbeatEventsErrorCount(e *events.Heartbeat, origin string) *metrics.GaugeMetric { 49 | stat := "ops." + origin + ".heartbeats.eventsErrorCount" 50 | metric := metrics.NewGaugeMetric(stat, int64(e.GetErrorCount())) 51 | 52 | return metric 53 | } 54 | -------------------------------------------------------------------------------- /processors/heartbeat_processor_test.go: -------------------------------------------------------------------------------- 1 | package processors_test 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | . "github.com/pivotal-cf/graphite-nozzle/processors" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | ) 10 | 11 | var _ = Describe("Heartbeat", func() { 12 | var ( 13 | processor *HeartbeatProcessor 14 | event *events.Envelope 15 | heartbeatEvent *events.Heartbeat 16 | origin string 17 | ) 18 | 19 | BeforeEach(func() { 20 | processor = NewHeartbeatProcessor() 21 | 22 | origin = "router__0" 23 | sentCount := uint64(5491) 24 | receivedCount := uint64(5491) 25 | errorCount := uint64(1) 26 | 27 | heartbeatEvent = &events.Heartbeat{ 28 | SentCount: &sentCount, 29 | ReceivedCount: &receivedCount, 30 | ErrorCount: &errorCount, 31 | } 32 | 33 | event = &events.Envelope{ 34 | Origin: &origin, 35 | Heartbeat: heartbeatEvent, 36 | } 37 | }) 38 | 39 | Describe("#Process", func() { 40 | It("returns a Metric for each of the ProcessHeartbeat* methods", func() { 41 | processedMetrics, err := processor.Process(event) 42 | 43 | Expect(err).To(BeNil()) 44 | Expect(processedMetrics).To(HaveLen(4)) 45 | }) 46 | }) 47 | 48 | Describe("#ProcessHeartbeatCount", func() { 49 | It("formats the Stat string to include the Heartbeat's Origin", func() { 50 | metric := processor.ProcessHeartbeatCount(heartbeatEvent, origin) 51 | 52 | Expect(metric.Stat).To(Equal("ops.router__0.heartbeats.count")) 53 | }) 54 | 55 | It("sets the increment value for the CounterMetric to 1", func() { 56 | metric := processor.ProcessHeartbeatCount(heartbeatEvent, origin) 57 | 58 | Expect(metric.Value).To(Equal(int64(1))) 59 | }) 60 | }) 61 | 62 | Describe("#ProcessHeartbeatEventsSentCount", func() { 63 | It("formats the Stat string to include the Heartbeat's Origin", func() { 64 | metric := processor.ProcessHeartbeatEventsSentCount(heartbeatEvent, origin) 65 | 66 | Expect(metric.Stat).To(Equal("ops.router__0.heartbeats.eventsSentCount")) 67 | }) 68 | 69 | It("sets the Metric Value to the value of the sentCount", func() { 70 | metric := processor.ProcessHeartbeatEventsSentCount(heartbeatEvent, origin) 71 | 72 | Expect(metric.Value).To(Equal(int64(5491))) 73 | }) 74 | }) 75 | 76 | Describe("#ProcessHeartbeatEventsReceivedCount", func() { 77 | It("formats the Stat string to include the Heartbeat's Origin", func() { 78 | metric := processor.ProcessHeartbeatEventsReceivedCount(heartbeatEvent, origin) 79 | 80 | Expect(metric.Stat).To(Equal("ops.router__0.heartbeats.eventsReceivedCount")) 81 | }) 82 | 83 | It("sets the Metric Value to the value of the receivedCount", func() { 84 | metric := processor.ProcessHeartbeatEventsReceivedCount(heartbeatEvent, origin) 85 | 86 | Expect(metric.Value).To(Equal(int64(5491))) 87 | }) 88 | }) 89 | 90 | Describe("#ProcessHeartbeatEventsErrorCount", func() { 91 | It("formats the Stat string to include the Heartbeat's Origin", func() { 92 | metric := processor.ProcessHeartbeatEventsErrorCount(heartbeatEvent, origin) 93 | 94 | Expect(metric.Stat).To(Equal("ops.router__0.heartbeats.eventsErrorCount")) 95 | }) 96 | 97 | It("sets the Metric Value to the value of the errorCount", func() { 98 | metric := processor.ProcessHeartbeatEventsErrorCount(heartbeatEvent, origin) 99 | 100 | Expect(metric.Value).To(Equal(int64(1))) 101 | }) 102 | }) 103 | }) 104 | -------------------------------------------------------------------------------- /processors/http_start_stop_processor.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "errors" 5 | "github.com/cloudfoundry/noaa/events" 6 | "github.com/pivotal-cf/graphite-nozzle/metrics" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | type HttpStartStopProcessor struct{} 12 | 13 | func NewHttpStartStopProcessor() *HttpStartStopProcessor { 14 | return &HttpStartStopProcessor{} 15 | } 16 | 17 | func (p *HttpStartStopProcessor) Process(e *events.Envelope) (processedMetrics []metrics.Metric, err error) { 18 | 19 | defer func() { 20 | if r := recover(); r != nil { 21 | switch x := r.(type) { 22 | case string: 23 | err = errors.New(x) 24 | case error: 25 | err = x 26 | default: 27 | err = errors.New("Unknown error") 28 | } 29 | processedMetrics = nil 30 | } 31 | }() 32 | 33 | processedMetrics = make([]metrics.Metric, 4) 34 | httpStartStopEvent := e.GetHttpStartStop() 35 | 36 | processedMetrics[0] = metrics.Metric(p.ProcessHttpStartStopResponseTime(httpStartStopEvent)) 37 | processedMetrics[1] = metrics.Metric(p.ProcessHttpStartStopStatusCodeCount(httpStartStopEvent)) 38 | processedMetrics[2] = metrics.Metric(p.ProcessHttpStartStopHttpErrorCount(httpStartStopEvent)) 39 | processedMetrics[3] = metrics.Metric(p.ProcessHttpStartStopHttpRequestCount(httpStartStopEvent)) 40 | 41 | return 42 | } 43 | 44 | 45 | //we want to be able to parse events whether they contain the scheme 46 | //element in their uri field or not 47 | func (p *HttpStartStopProcessor) parseEventUri(uri string) string { 48 | 49 | hostname := "" 50 | 51 | //we first remove the scheme 52 | if strings.Contains(uri, "://") { 53 | uri = strings.Split(uri, "://")[1] 54 | } 55 | 56 | //and then proceed with extracting the hostname 57 | hostname = strings.Split(uri, "/")[0] 58 | hostname = strings.Replace(hostname, ".", "_", -1) 59 | hostname = strings.Replace(hostname, ":", "_", -1) 60 | 61 | if !(len(hostname) > 0) { 62 | panic(errors.New("Hostname cannot be extracted from Event uri: " + uri)) 63 | } 64 | 65 | return hostname 66 | } 67 | 68 | func (p *HttpStartStopProcessor) ProcessHttpStartStopResponseTime(event *events.HttpStartStop) *metrics.TimingMetric { 69 | statPrefix := "http.responsetimes." 70 | hostname := p.parseEventUri(event.GetUri()) 71 | stat := statPrefix + hostname 72 | 73 | startTimestamp := event.GetStartTimestamp() 74 | stopTimestamp := event.GetStopTimestamp() 75 | durationNanos := stopTimestamp - startTimestamp 76 | durationMillis := durationNanos / 1000000 // NB: loss of precision here 77 | metric := metrics.NewTimingMetric(stat, durationMillis) 78 | 79 | return metric 80 | } 81 | 82 | func (p *HttpStartStopProcessor) ProcessHttpStartStopStatusCodeCount(event *events.HttpStartStop) *metrics.CounterMetric { 83 | statPrefix := "http.statuscodes." 84 | hostname := p.parseEventUri(event.GetUri()) 85 | stat := statPrefix + hostname + "." + strconv.Itoa(int(event.GetStatusCode())) 86 | 87 | metric := metrics.NewCounterMetric(stat, isPeer(event)) 88 | 89 | return metric 90 | } 91 | 92 | func (p *HttpStartStopProcessor) ProcessHttpStartStopHttpErrorCount(event *events.HttpStartStop) *metrics.CounterMetric { 93 | var incrementValue int64 94 | 95 | statPrefix := "http.errors." 96 | hostname := p.parseEventUri(event.GetUri()) 97 | stat := statPrefix + hostname 98 | 99 | if 299 < event.GetStatusCode() && 1 == isPeer(event) { 100 | incrementValue = 1 101 | } else { 102 | incrementValue = 0 103 | } 104 | 105 | metric := metrics.NewCounterMetric(stat, incrementValue) 106 | 107 | return metric 108 | } 109 | 110 | func (p *HttpStartStopProcessor) ProcessHttpStartStopHttpRequestCount(event *events.HttpStartStop) *metrics.CounterMetric { 111 | statPrefix := "http.requests." 112 | hostname := p.parseEventUri(event.GetUri()) 113 | stat := statPrefix + hostname 114 | metric := metrics.NewCounterMetric(stat, isPeer(event)) 115 | 116 | return metric 117 | } 118 | 119 | func isPeer(event *events.HttpStartStop) int64 { 120 | if event.GetPeerType() == events.PeerType_Client { 121 | return 1 122 | } else { 123 | return 0 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /processors/http_start_stop_processor_test.go: -------------------------------------------------------------------------------- 1 | package processors_test 2 | 3 | import ( 4 | . "github.com/pivotal-cf/graphite-nozzle/processors" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | 9 | "github.com/cloudfoundry/noaa/events" 10 | ) 11 | 12 | var _ = Describe("HttpStartStopProcessor", func() { 13 | var ( 14 | processor *HttpStartStopProcessor 15 | event *events.Envelope 16 | httpStartStopEvent *events.HttpStartStop 17 | startTimestamp int64 18 | stopTimestamp int64 19 | method events.Method 20 | uri string 21 | statusCode int32 22 | peerType events.PeerType 23 | ) 24 | 25 | BeforeEach(func() { 26 | 27 | startTimestamp = int64(1425881484152112140) 28 | stopTimestamp = int64(1425881484161498528) 29 | method = events.Method_GET 30 | uri = "http://api.10.244.0.34.xip.io:443/v2/info" 31 | statusCode = int32(200) 32 | peerType = events.PeerType_Client 33 | }) 34 | 35 | JustBeforeEach(func() { 36 | processor = NewHttpStartStopProcessor() 37 | 38 | httpStartStopEvent = &events.HttpStartStop{ 39 | StartTimestamp: &startTimestamp, 40 | StopTimestamp: &stopTimestamp, 41 | Method: &method, 42 | Uri: &uri, 43 | StatusCode: &statusCode, 44 | PeerType: &peerType, 45 | } 46 | 47 | event = &events.Envelope{ 48 | HttpStartStop: httpStartStopEvent, 49 | } 50 | }) 51 | 52 | Describe("#Process", func() { 53 | Context("with a properly formatted event which contains the schema", func() { 54 | It("returns a Metric for each of the ProcessHttpStartStop* methods", func() { 55 | processedMetrics, err := processor.Process(event) 56 | 57 | Expect(err).To(BeNil()) 58 | Expect(processedMetrics).To(HaveLen(4)) 59 | }) 60 | }) 61 | 62 | Context("with a properly formatted event which does not contain the schema", func() { 63 | BeforeEach(func() { 64 | uri = "api.10.244.0.34.xip.io/v2/info:443" 65 | }) 66 | It("returns a Metric for each of the ProcessHttpStartStop* methods", func() { 67 | processedMetrics, err := processor.Process(event) 68 | 69 | Expect(err).To(BeNil()) 70 | Expect(processedMetrics).To(HaveLen(4)) 71 | }) 72 | }) 73 | 74 | Context("the Event uri field is empty", func() { 75 | BeforeEach(func() { 76 | uri = "" 77 | }) 78 | 79 | It("returns an error", func() { 80 | processedMetrics, err := processor.Process(event) 81 | 82 | Expect(processedMetrics).To(BeNil()) 83 | Expect(err).Should(HaveOccurred()) 84 | }) 85 | }) 86 | }) 87 | 88 | Describe("#ProcessHttpStartStopResponseTime", func() { 89 | It("formats the Stat string to include the hostname", func() { 90 | metric := processor.ProcessHttpStartStopResponseTime(httpStartStopEvent) 91 | 92 | Expect(metric.Stat).To(Equal("http.responsetimes.api_10_244_0_34_xip_io_443")) 93 | }) 94 | 95 | It("calculates the HTTP response time in milliseconds", func() { 96 | metric := processor.ProcessHttpStartStopResponseTime(httpStartStopEvent) 97 | 98 | Expect(metric.Value).To(Equal(int64(9))) 99 | }) 100 | }) 101 | 102 | Describe("#ProcessHttpStartStopStatusCodeCount", func() { 103 | Context("with a HTTP 200 status code", func() { 104 | It("formats the Stat string to include the hostname and the status code", func() { 105 | metric := processor.ProcessHttpStartStopStatusCodeCount(httpStartStopEvent) 106 | 107 | Expect(metric.Stat).To(Equal("http.statuscodes.api_10_244_0_34_xip_io_443.200")) 108 | }) 109 | 110 | It("it does not increment the error counter by one", func() { 111 | metric := processor.ProcessHttpStartStopHttpErrorCount(httpStartStopEvent) 112 | Expect(metric.Stat).To(Equal("http.errors.api_10_244_0_34_xip_io_443")) 113 | Expect(metric.Value).To(Equal(int64(0))) 114 | }) 115 | 116 | It("increments the requests counter by one", func() { 117 | metric := processor.ProcessHttpStartStopHttpRequestCount(httpStartStopEvent) 118 | Expect(metric.Stat).To(Equal("http.requests.api_10_244_0_34_xip_io_443")) 119 | Expect(metric.Value).To(Equal(int64(1))) 120 | }) 121 | }) 122 | 123 | Context("with a HTTP 404 status code", func() { 124 | It("formats the Stat string to include the hostname and the status code", func() { 125 | statusCode := int32(404) 126 | httpStartStopEvent.StatusCode = &statusCode 127 | metric := processor.ProcessHttpStartStopStatusCodeCount(httpStartStopEvent) 128 | 129 | Expect(metric.Stat).To(Equal("http.statuscodes.api_10_244_0_34_xip_io_443.404")) 130 | }) 131 | 132 | It("increments the error counter by one", func() { 133 | statusCode := int32(404) 134 | httpStartStopEvent.StatusCode = &statusCode 135 | metric := processor.ProcessHttpStartStopHttpErrorCount(httpStartStopEvent) 136 | Expect(metric.Stat).To(Equal("http.errors.api_10_244_0_34_xip_io_443")) 137 | Expect(metric.Value).To(Equal(int64(1))) 138 | }) 139 | 140 | It("increments the requests counter by one", func() { 141 | statusCode := int32(404) 142 | httpStartStopEvent.StatusCode = &statusCode 143 | metric := processor.ProcessHttpStartStopHttpRequestCount(httpStartStopEvent) 144 | Expect(metric.Stat).To(Equal("http.requests.api_10_244_0_34_xip_io_443")) 145 | Expect(metric.Value).To(Equal(int64(1))) 146 | }) 147 | }) 148 | 149 | Context("when PeerType == PeerType_Client", func() { 150 | It("sets the increment value for the CounterMetric to 1", func() { 151 | metric := processor.ProcessHttpStartStopStatusCodeCount(httpStartStopEvent) 152 | 153 | Expect(metric.Value).To(Equal(int64(1))) 154 | }) 155 | }) 156 | 157 | Context("when PeerType == PeerType_Server", func() { 158 | It("sets the increment value for the CounterMetric to 0", func() { 159 | peerType := events.PeerType_Server 160 | httpStartStopEvent.PeerType = &peerType 161 | metric := processor.ProcessHttpStartStopStatusCodeCount(httpStartStopEvent) 162 | 163 | Expect(metric.Value).To(Equal(int64(0))) 164 | }) 165 | }) 166 | 167 | }) 168 | }) 169 | -------------------------------------------------------------------------------- /processors/processor.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "github.com/pivotal-cf/graphite-nozzle/metrics" 6 | ) 7 | 8 | type Processor interface { 9 | Process(e *events.Envelope) ([]metrics.Metric, error) 10 | } 11 | -------------------------------------------------------------------------------- /processors/processors_suite_test.go: -------------------------------------------------------------------------------- 1 | package processors_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestProcessors(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Processors Suite") 13 | } 14 | -------------------------------------------------------------------------------- /processors/value_metric_processor.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "github.com/pivotal-cf/graphite-nozzle/metrics" 6 | ) 7 | 8 | type ValueMetricProcessor struct{} 9 | 10 | func NewValueMetricProcessor() *ValueMetricProcessor { 11 | return &ValueMetricProcessor{} 12 | } 13 | 14 | func (p *ValueMetricProcessor) Process(e *events.Envelope) ([]metrics.Metric, error) { 15 | processedMetrics := make([]metrics.Metric, 1) 16 | valueMetricEvent := e.GetValueMetric() 17 | 18 | processedMetrics[0] = p.ProcessValueMetric(valueMetricEvent, e.GetOrigin()) 19 | 20 | return processedMetrics, nil 21 | } 22 | 23 | func (p *ValueMetricProcessor) ProcessValueMetric(event *events.ValueMetric, origin string) *metrics.FGaugeMetric { 24 | statPrefix := "ops." + origin + "." 25 | valueMetricName := event.GetName() 26 | stat := statPrefix + valueMetricName 27 | metric := metrics.NewFGaugeMetric(stat, event.GetValue()) 28 | 29 | return metric 30 | } 31 | -------------------------------------------------------------------------------- /processors/value_metric_processor_test.go: -------------------------------------------------------------------------------- 1 | package processors_test 2 | 3 | import ( 4 | . "github.com/pivotal-cf/graphite-nozzle/processors" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | 9 | "github.com/cloudfoundry/noaa/events" 10 | ) 11 | 12 | var _ = Describe("ValueMetricProcessor", func() { 13 | var ( 14 | processor *ValueMetricProcessor 15 | event *events.Envelope 16 | valueMetricEvent *events.ValueMetric 17 | origin string 18 | ) 19 | 20 | BeforeEach(func() { 21 | processor = NewValueMetricProcessor() 22 | 23 | origin = "router__0" 24 | name := "numCPUS" 25 | unit := "count" 26 | value := float64(4) 27 | 28 | valueMetricEvent = &events.ValueMetric{ 29 | Name: &name, 30 | Unit: &unit, 31 | Value: &value, 32 | } 33 | 34 | event = &events.Envelope{ 35 | Origin: &origin, 36 | ValueMetric: valueMetricEvent, 37 | } 38 | }) 39 | 40 | Describe("#Process", func() { 41 | It("returns a Metric for each of the ProcessValueMetric* methods", func() { 42 | processedMetrics, err := processor.Process(event) 43 | 44 | Expect(err).To(BeNil()) 45 | Expect(processedMetrics).To(HaveLen(1)) 46 | }) 47 | }) 48 | 49 | Describe("#ProcessValueMetric", func() { 50 | It("formats the Stat string to include the ValueMetric's name and Origin", func() { 51 | metric := processor.ProcessValueMetric(valueMetricEvent, origin) 52 | 53 | Expect(metric.Stat).To(Equal("ops.router__0.numCPUS")) 54 | }) 55 | 56 | It("sets the Metric Value to the value of the ValueMetric", func() { 57 | metric := processor.ProcessValueMetric(valueMetricEvent, origin) 58 | 59 | Expect(metric.Value).To(Equal(float64(4))) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /token/token.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | // Stolen from https://github.com/cloudfoundry-incubator/datadog-firehose-nozzle/blob/master/uaatokenfetcher/uaa_token_fetcher.go 4 | 5 | import ( 6 | "github.com/cloudfoundry-incubator/uaago" 7 | ) 8 | 9 | type UAATokenFetcher struct { 10 | UaaUrl string 11 | Username string 12 | Password string 13 | InsecureSSLSkipVerify bool 14 | } 15 | 16 | func (uaa *UAATokenFetcher) FetchAuthToken() (string, error) { 17 | uaaClient, err := uaago.NewClient(uaa.UaaUrl) 18 | if err != nil { 19 | return "", err 20 | } 21 | 22 | var authToken string 23 | authToken, err = uaaClient.GetAuthToken(uaa.Username, uaa.Password, uaa.InsecureSSLSkipVerify) 24 | if err != nil { 25 | return "", err 26 | } 27 | return authToken, nil 28 | } 29 | -------------------------------------------------------------------------------- /validators.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | func ValidateStatsdProtocol(statsdProtocol string) (err error) { 8 | err_msg := "Statsd protocol needs to be one of: ['tcp', 'udp']" 9 | switch statsdProtocol { 10 | case "udp", "tcp": 11 | err = nil 12 | default: 13 | err = errors.New(err_msg) 14 | } 15 | 16 | return err 17 | } -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/template/README.md: -------------------------------------------------------------------------------- 1 | # Go's `text/template` package with newline elision 2 | 3 | This is a fork of Go 1.4's [text/template](http://golang.org/pkg/text/template/) package with one addition: a backslash immediately after a closing delimiter will delete all subsequent newlines until a non-newline. 4 | 5 | eg. 6 | 7 | ``` 8 | {{if true}}\ 9 | hello 10 | {{end}}\ 11 | ``` 12 | 13 | Will result in: 14 | 15 | ``` 16 | hello\n 17 | ``` 18 | 19 | Rather than: 20 | 21 | ``` 22 | \n 23 | hello\n 24 | \n 25 | ``` 26 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/template/helper.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Helper functions to make constructing templates easier. 6 | 7 | package template 8 | 9 | import ( 10 | "fmt" 11 | "io/ioutil" 12 | "path/filepath" 13 | ) 14 | 15 | // Functions and methods to parse templates. 16 | 17 | // Must is a helper that wraps a call to a function returning (*Template, error) 18 | // and panics if the error is non-nil. It is intended for use in variable 19 | // initializations such as 20 | // var t = template.Must(template.New("name").Parse("text")) 21 | func Must(t *Template, err error) *Template { 22 | if err != nil { 23 | panic(err) 24 | } 25 | return t 26 | } 27 | 28 | // ParseFiles creates a new Template and parses the template definitions from 29 | // the named files. The returned template's name will have the (base) name and 30 | // (parsed) contents of the first file. There must be at least one file. 31 | // If an error occurs, parsing stops and the returned *Template is nil. 32 | func ParseFiles(filenames ...string) (*Template, error) { 33 | return parseFiles(nil, filenames...) 34 | } 35 | 36 | // ParseFiles parses the named files and associates the resulting templates with 37 | // t. If an error occurs, parsing stops and the returned template is nil; 38 | // otherwise it is t. There must be at least one file. 39 | func (t *Template) ParseFiles(filenames ...string) (*Template, error) { 40 | return parseFiles(t, filenames...) 41 | } 42 | 43 | // parseFiles is the helper for the method and function. If the argument 44 | // template is nil, it is created from the first file. 45 | func parseFiles(t *Template, filenames ...string) (*Template, error) { 46 | if len(filenames) == 0 { 47 | // Not really a problem, but be consistent. 48 | return nil, fmt.Errorf("template: no files named in call to ParseFiles") 49 | } 50 | for _, filename := range filenames { 51 | b, err := ioutil.ReadFile(filename) 52 | if err != nil { 53 | return nil, err 54 | } 55 | s := string(b) 56 | name := filepath.Base(filename) 57 | // First template becomes return value if not already defined, 58 | // and we use that one for subsequent New calls to associate 59 | // all the templates together. Also, if this file has the same name 60 | // as t, this file becomes the contents of t, so 61 | // t, err := New(name).Funcs(xxx).ParseFiles(name) 62 | // works. Otherwise we create a new template associated with t. 63 | var tmpl *Template 64 | if t == nil { 65 | t = New(name) 66 | } 67 | if name == t.Name() { 68 | tmpl = t 69 | } else { 70 | tmpl = t.New(name) 71 | } 72 | _, err = tmpl.Parse(s) 73 | if err != nil { 74 | return nil, err 75 | } 76 | } 77 | return t, nil 78 | } 79 | 80 | // ParseGlob creates a new Template and parses the template definitions from the 81 | // files identified by the pattern, which must match at least one file. The 82 | // returned template will have the (base) name and (parsed) contents of the 83 | // first file matched by the pattern. ParseGlob is equivalent to calling 84 | // ParseFiles with the list of files matched by the pattern. 85 | func ParseGlob(pattern string) (*Template, error) { 86 | return parseGlob(nil, pattern) 87 | } 88 | 89 | // ParseGlob parses the template definitions in the files identified by the 90 | // pattern and associates the resulting templates with t. The pattern is 91 | // processed by filepath.Glob and must match at least one file. ParseGlob is 92 | // equivalent to calling t.ParseFiles with the list of files matched by the 93 | // pattern. 94 | func (t *Template) ParseGlob(pattern string) (*Template, error) { 95 | return parseGlob(t, pattern) 96 | } 97 | 98 | // parseGlob is the implementation of the function and method ParseGlob. 99 | func parseGlob(t *Template, pattern string) (*Template, error) { 100 | filenames, err := filepath.Glob(pattern) 101 | if err != nil { 102 | return nil, err 103 | } 104 | if len(filenames) == 0 { 105 | return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) 106 | } 107 | return parseFiles(t, filenames...) 108 | } 109 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/template/template.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package template 6 | 7 | import ( 8 | "fmt" 9 | "reflect" 10 | "github.com/alecthomas/template/parse" 11 | ) 12 | 13 | // common holds the information shared by related templates. 14 | type common struct { 15 | tmpl map[string]*Template 16 | // We use two maps, one for parsing and one for execution. 17 | // This separation makes the API cleaner since it doesn't 18 | // expose reflection to the client. 19 | parseFuncs FuncMap 20 | execFuncs map[string]reflect.Value 21 | } 22 | 23 | // Template is the representation of a parsed template. The *parse.Tree 24 | // field is exported only for use by html/template and should be treated 25 | // as unexported by all other clients. 26 | type Template struct { 27 | name string 28 | *parse.Tree 29 | *common 30 | leftDelim string 31 | rightDelim string 32 | } 33 | 34 | // New allocates a new template with the given name. 35 | func New(name string) *Template { 36 | return &Template{ 37 | name: name, 38 | } 39 | } 40 | 41 | // Name returns the name of the template. 42 | func (t *Template) Name() string { 43 | return t.name 44 | } 45 | 46 | // New allocates a new template associated with the given one and with the same 47 | // delimiters. The association, which is transitive, allows one template to 48 | // invoke another with a {{template}} action. 49 | func (t *Template) New(name string) *Template { 50 | t.init() 51 | return &Template{ 52 | name: name, 53 | common: t.common, 54 | leftDelim: t.leftDelim, 55 | rightDelim: t.rightDelim, 56 | } 57 | } 58 | 59 | func (t *Template) init() { 60 | if t.common == nil { 61 | t.common = new(common) 62 | t.tmpl = make(map[string]*Template) 63 | t.parseFuncs = make(FuncMap) 64 | t.execFuncs = make(map[string]reflect.Value) 65 | } 66 | } 67 | 68 | // Clone returns a duplicate of the template, including all associated 69 | // templates. The actual representation is not copied, but the name space of 70 | // associated templates is, so further calls to Parse in the copy will add 71 | // templates to the copy but not to the original. Clone can be used to prepare 72 | // common templates and use them with variant definitions for other templates 73 | // by adding the variants after the clone is made. 74 | func (t *Template) Clone() (*Template, error) { 75 | nt := t.copy(nil) 76 | nt.init() 77 | nt.tmpl[t.name] = nt 78 | for k, v := range t.tmpl { 79 | if k == t.name { // Already installed. 80 | continue 81 | } 82 | // The associated templates share nt's common structure. 83 | tmpl := v.copy(nt.common) 84 | nt.tmpl[k] = tmpl 85 | } 86 | for k, v := range t.parseFuncs { 87 | nt.parseFuncs[k] = v 88 | } 89 | for k, v := range t.execFuncs { 90 | nt.execFuncs[k] = v 91 | } 92 | return nt, nil 93 | } 94 | 95 | // copy returns a shallow copy of t, with common set to the argument. 96 | func (t *Template) copy(c *common) *Template { 97 | nt := New(t.name) 98 | nt.Tree = t.Tree 99 | nt.common = c 100 | nt.leftDelim = t.leftDelim 101 | nt.rightDelim = t.rightDelim 102 | return nt 103 | } 104 | 105 | // AddParseTree creates a new template with the name and parse tree 106 | // and associates it with t. 107 | func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) { 108 | if t.common != nil && t.tmpl[name] != nil { 109 | return nil, fmt.Errorf("template: redefinition of template %q", name) 110 | } 111 | nt := t.New(name) 112 | nt.Tree = tree 113 | t.tmpl[name] = nt 114 | return nt, nil 115 | } 116 | 117 | // Templates returns a slice of the templates associated with t, including t 118 | // itself. 119 | func (t *Template) Templates() []*Template { 120 | if t.common == nil { 121 | return nil 122 | } 123 | // Return a slice so we don't expose the map. 124 | m := make([]*Template, 0, len(t.tmpl)) 125 | for _, v := range t.tmpl { 126 | m = append(m, v) 127 | } 128 | return m 129 | } 130 | 131 | // Delims sets the action delimiters to the specified strings, to be used in 132 | // subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template 133 | // definitions will inherit the settings. An empty delimiter stands for the 134 | // corresponding default: {{ or }}. 135 | // The return value is the template, so calls can be chained. 136 | func (t *Template) Delims(left, right string) *Template { 137 | t.leftDelim = left 138 | t.rightDelim = right 139 | return t 140 | } 141 | 142 | // Funcs adds the elements of the argument map to the template's function map. 143 | // It panics if a value in the map is not a function with appropriate return 144 | // type. However, it is legal to overwrite elements of the map. The return 145 | // value is the template, so calls can be chained. 146 | func (t *Template) Funcs(funcMap FuncMap) *Template { 147 | t.init() 148 | addValueFuncs(t.execFuncs, funcMap) 149 | addFuncs(t.parseFuncs, funcMap) 150 | return t 151 | } 152 | 153 | // Lookup returns the template with the given name that is associated with t, 154 | // or nil if there is no such template. 155 | func (t *Template) Lookup(name string) *Template { 156 | if t.common == nil { 157 | return nil 158 | } 159 | return t.tmpl[name] 160 | } 161 | 162 | // Parse parses a string into a template. Nested template definitions will be 163 | // associated with the top-level template t. Parse may be called multiple times 164 | // to parse definitions of templates to associate with t. It is an error if a 165 | // resulting template is non-empty (contains content other than template 166 | // definitions) and would replace a non-empty template with the same name. 167 | // (In multiple calls to Parse with the same receiver template, only one call 168 | // can contain text other than space, comments, and template definitions.) 169 | func (t *Template) Parse(text string) (*Template, error) { 170 | t.init() 171 | trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins) 172 | if err != nil { 173 | return nil, err 174 | } 175 | // Add the newly parsed trees, including the one for t, into our common structure. 176 | for name, tree := range trees { 177 | // If the name we parsed is the name of this template, overwrite this template. 178 | // The associate method checks it's not a redefinition. 179 | tmpl := t 180 | if name != t.name { 181 | tmpl = t.New(name) 182 | } 183 | // Even if t == tmpl, we need to install it in the common.tmpl map. 184 | if replace, err := t.associate(tmpl, tree); err != nil { 185 | return nil, err 186 | } else if replace { 187 | tmpl.Tree = tree 188 | } 189 | tmpl.leftDelim = t.leftDelim 190 | tmpl.rightDelim = t.rightDelim 191 | } 192 | return t, nil 193 | } 194 | 195 | // associate installs the new template into the group of templates associated 196 | // with t. It is an error to reuse a name except to overwrite an empty 197 | // template. The two are already known to share the common structure. 198 | // The boolean return value reports wither to store this tree as t.Tree. 199 | func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) { 200 | if new.common != t.common { 201 | panic("internal error: associate not common") 202 | } 203 | name := new.name 204 | if old := t.tmpl[name]; old != nil { 205 | oldIsEmpty := parse.IsEmptyTree(old.Root) 206 | newIsEmpty := parse.IsEmptyTree(tree.Root) 207 | if newIsEmpty { 208 | // Whether old is empty or not, new is empty; no reason to replace old. 209 | return false, nil 210 | } 211 | if !oldIsEmpty { 212 | return false, fmt.Errorf("template: redefinition of template %q", name) 213 | } 214 | } 215 | t.tmpl[name] = new 216 | return true, nil 217 | } 218 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/README.md: -------------------------------------------------------------------------------- 1 | # Units - Helpful unit multipliers and functions for Go 2 | 3 | The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package. 4 | 5 | It allows for code like this: 6 | 7 | ```go 8 | n, err := ParseBase2Bytes("1KB") 9 | // n == 1024 10 | n = units.Mebibyte * 512 11 | ``` 12 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/bytes.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | // Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte, 4 | // etc.). 5 | type Base2Bytes int64 6 | 7 | // Base-2 byte units. 8 | const ( 9 | Kibibyte Base2Bytes = 1024 10 | KiB = Kibibyte 11 | Mebibyte = Kibibyte * 1024 12 | MiB = Mebibyte 13 | Gibibyte = Mebibyte * 1024 14 | GiB = Gibibyte 15 | Tebibyte = Gibibyte * 1024 16 | TiB = Tebibyte 17 | Pebibyte = Tebibyte * 1024 18 | PiB = Pebibyte 19 | Exbibyte = Pebibyte * 1024 20 | EiB = Exbibyte 21 | ) 22 | 23 | var ( 24 | bytesUnitMap = MakeUnitMap("iB", "B", 1024) 25 | oldBytesUnitMap = MakeUnitMap("B", "B", 1024) 26 | ) 27 | 28 | // ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB 29 | // and KiB are both 1024. 30 | func ParseBase2Bytes(s string) (Base2Bytes, error) { 31 | n, err := ParseUnit(s, bytesUnitMap) 32 | if err != nil { 33 | n, err = ParseUnit(s, oldBytesUnitMap) 34 | } 35 | return Base2Bytes(n), err 36 | } 37 | 38 | func (b Base2Bytes) String() string { 39 | return ToString(int64(b), 1024, "iB", "B") 40 | } 41 | 42 | var ( 43 | metricBytesUnitMap = MakeUnitMap("B", "B", 1000) 44 | ) 45 | 46 | // MetricBytes are SI byte units (1000 bytes in a kilobyte). 47 | type MetricBytes SI 48 | 49 | // SI base-10 byte units. 50 | const ( 51 | Kilobyte MetricBytes = 1000 52 | KB = Kilobyte 53 | Megabyte = Kilobyte * 1000 54 | MB = Megabyte 55 | Gigabyte = Megabyte * 1000 56 | GB = Gigabyte 57 | Terabyte = Gigabyte * 1000 58 | TB = Terabyte 59 | Petabyte = Terabyte * 1000 60 | PB = Petabyte 61 | Exabyte = Petabyte * 1000 62 | EB = Exabyte 63 | ) 64 | 65 | // ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes. 66 | func ParseMetricBytes(s string) (MetricBytes, error) { 67 | n, err := ParseUnit(s, metricBytesUnitMap) 68 | return MetricBytes(n), err 69 | } 70 | 71 | func (m MetricBytes) String() string { 72 | return ToString(int64(m), 1000, "B", "B") 73 | } 74 | 75 | // ParseStrictBytes supports both iB and B suffixes for base 2 and metric, 76 | // respectively. That is, KiB represents 1024 and KB represents 1000. 77 | func ParseStrictBytes(s string) (int64, error) { 78 | n, err := ParseUnit(s, bytesUnitMap) 79 | if err != nil { 80 | n, err = ParseUnit(s, metricBytesUnitMap) 81 | } 82 | return int64(n), err 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/doc.go: -------------------------------------------------------------------------------- 1 | // Package units provides helpful unit multipliers and functions for Go. 2 | // 3 | // The goal of this package is to have functionality similar to the time [1] package. 4 | // 5 | // 6 | // [1] http://golang.org/pkg/time/ 7 | // 8 | // It allows for code like this: 9 | // 10 | // n, err := ParseBase2Bytes("1KB") 11 | // // n == 1024 12 | // n = units.Mebibyte * 512 13 | package units 14 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/si.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | // SI units. 4 | type SI int64 5 | 6 | // SI unit multiples. 7 | const ( 8 | Kilo SI = 1000 9 | Mega = Kilo * 1000 10 | Giga = Mega * 1000 11 | Tera = Giga * 1000 12 | Peta = Tera * 1000 13 | Exa = Peta * 1000 14 | ) 15 | 16 | func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 { 17 | return map[string]float64{ 18 | shortSuffix: 1, 19 | "K" + suffix: float64(scale), 20 | "M" + suffix: float64(scale * scale), 21 | "G" + suffix: float64(scale * scale * scale), 22 | "T" + suffix: float64(scale * scale * scale * scale), 23 | "P" + suffix: float64(scale * scale * scale * scale * scale), 24 | "E" + suffix: float64(scale * scale * scale * scale * scale * scale), 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/util.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | var ( 10 | siUnits = []string{"", "K", "M", "G", "T", "P", "E"} 11 | ) 12 | 13 | func ToString(n int64, scale int64, suffix, baseSuffix string) string { 14 | mn := len(siUnits) 15 | out := make([]string, mn) 16 | for i, m := range siUnits { 17 | if n%scale != 0 || i == 0 && n == 0 { 18 | s := suffix 19 | if i == 0 { 20 | s = baseSuffix 21 | } 22 | out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s) 23 | } 24 | n /= scale 25 | if n == 0 { 26 | break 27 | } 28 | } 29 | return strings.Join(out, "") 30 | } 31 | 32 | // Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123 33 | var errLeadingInt = errors.New("units: bad [0-9]*") // never printed 34 | 35 | // leadingInt consumes the leading [0-9]* from s. 36 | func leadingInt(s string) (x int64, rem string, err error) { 37 | i := 0 38 | for ; i < len(s); i++ { 39 | c := s[i] 40 | if c < '0' || c > '9' { 41 | break 42 | } 43 | if x >= (1<<63-10)/10 { 44 | // overflow 45 | return 0, "", errLeadingInt 46 | } 47 | x = x*10 + int64(c) - '0' 48 | } 49 | return x, s[i:], nil 50 | } 51 | 52 | func ParseUnit(s string, unitMap map[string]float64) (int64, error) { 53 | // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+ 54 | orig := s 55 | f := float64(0) 56 | neg := false 57 | 58 | // Consume [-+]? 59 | if s != "" { 60 | c := s[0] 61 | if c == '-' || c == '+' { 62 | neg = c == '-' 63 | s = s[1:] 64 | } 65 | } 66 | // Special case: if all that is left is "0", this is zero. 67 | if s == "0" { 68 | return 0, nil 69 | } 70 | if s == "" { 71 | return 0, errors.New("units: invalid " + orig) 72 | } 73 | for s != "" { 74 | g := float64(0) // this element of the sequence 75 | 76 | var x int64 77 | var err error 78 | 79 | // The next character must be [0-9.] 80 | if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) { 81 | return 0, errors.New("units: invalid " + orig) 82 | } 83 | // Consume [0-9]* 84 | pl := len(s) 85 | x, s, err = leadingInt(s) 86 | if err != nil { 87 | return 0, errors.New("units: invalid " + orig) 88 | } 89 | g = float64(x) 90 | pre := pl != len(s) // whether we consumed anything before a period 91 | 92 | // Consume (\.[0-9]*)? 93 | post := false 94 | if s != "" && s[0] == '.' { 95 | s = s[1:] 96 | pl := len(s) 97 | x, s, err = leadingInt(s) 98 | if err != nil { 99 | return 0, errors.New("units: invalid " + orig) 100 | } 101 | scale := 1.0 102 | for n := pl - len(s); n > 0; n-- { 103 | scale *= 10 104 | } 105 | g += float64(x) / scale 106 | post = pl != len(s) 107 | } 108 | if !pre && !post { 109 | // no digits (e.g. ".s" or "-.s") 110 | return 0, errors.New("units: invalid " + orig) 111 | } 112 | 113 | // Consume unit. 114 | i := 0 115 | for ; i < len(s); i++ { 116 | c := s[i] 117 | if c == '.' || ('0' <= c && c <= '9') { 118 | break 119 | } 120 | } 121 | u := s[:i] 122 | s = s[i:] 123 | unit, ok := unitMap[u] 124 | if !ok { 125 | return 0, errors.New("units: unknown unit " + u + " in " + orig) 126 | } 127 | 128 | f += g * unit 129 | } 130 | 131 | if neg { 132 | f = -f 133 | } 134 | if f < float64(-1<<63) || f > float64(1<<63-1) { 135 | return 0, errors.New("units: overflow parsing unit") 136 | } 137 | return int64(f), nil 138 | } 139 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry-incubator/uaago/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry-incubator/uaago/README.md: -------------------------------------------------------------------------------- 1 | # uaago 2 | 3 | UAA client for golang. 4 | 5 | ## Usage 6 | 7 | See [sample_cli](/sample_cli). You can run this like this: 8 | 9 | ```bash 10 | $ go build -o bin/sample-cli sample_cli/main.go 11 | $ ./bin/sample-cli [URL] [USER] [PASS] 12 | ``` 13 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry-incubator/uaago/client.go: -------------------------------------------------------------------------------- 1 | package uaago 2 | 3 | import ( 4 | "crypto/tls" 5 | "encoding/json" 6 | "fmt" 7 | "net/http" 8 | "net/url" 9 | "strings" 10 | ) 11 | 12 | type Client struct { 13 | uaaUrl *url.URL 14 | } 15 | 16 | func NewClient(uaaUrl string) (*Client, error) { 17 | if len(uaaUrl) == 0 { 18 | return nil, fmt.Errorf("client: missing url") 19 | } 20 | 21 | parsedURL, err := url.Parse(uaaUrl) 22 | if err != nil { 23 | return nil, err 24 | } 25 | 26 | return &Client{ 27 | uaaUrl: parsedURL, 28 | }, nil 29 | } 30 | 31 | func (c *Client) GetAuthToken(username, password string, insecureSkipVerify bool) (string, error) { 32 | data := url.Values{ 33 | "client_id": {username}, 34 | "grant_type": {"client_credentials"}, 35 | } 36 | 37 | request, err := http.NewRequest("POST", fmt.Sprintf("%s/oauth/token", c.uaaUrl), strings.NewReader(data.Encode())) 38 | if err != nil { 39 | return "", err 40 | } 41 | request.SetBasicAuth(username, password) 42 | request.Header.Set("Content-Type", "application/x-www-form-urlencoded") 43 | 44 | config := &tls.Config{InsecureSkipVerify: insecureSkipVerify} 45 | tr := &http.Transport{TLSClientConfig: config} 46 | httpClient := &http.Client{Transport: tr} 47 | 48 | resp, err := httpClient.Do(request) 49 | if err != nil { 50 | return "", err 51 | } 52 | 53 | if resp.StatusCode != http.StatusOK { 54 | return "", fmt.Errorf("Received a status code %v", resp.Status) 55 | } 56 | 57 | jsonData := make(map[string]interface{}) 58 | decoder := json.NewDecoder(resp.Body) 59 | err = decoder.Decode(&jsonData) 60 | 61 | return fmt.Sprintf("%s %s", jsonData["token_type"], jsonData["access_token"]), err 62 | } 63 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/.gitignore: -------------------------------------------------------------------------------- 1 | *.coverprofile 2 | src/ 3 | bin/ 4 | pkg/ 5 | .idea 6 | *.iml 7 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | notifications: 3 | email: 4 | - cf-lamb@pivotallabs.com 5 | before_install: 6 | - 'if [[ "${TRAVIS_GO_VERSION}" =~ 1.[2-3] ]]; then go get code.google.com/p/go.tools/cmd/cover; else go get golang.org/x/tools/cmd/cover; fi' 7 | - go get github.com/mattn/goveralls 8 | - go get github.com/onsi/ginkgo/ginkgo 9 | after_success: 10 | - 'echo "mode: set" > all.coverprofile' 11 | - 'find . -name "*.coverprofile" -exec grep -v mode: {} >> all.coverprofile \;' 12 | - PATH=$HOME/gopath/bin:$PATH goveralls -coverprofile=all.coverprofile -repotoken=$COVERALLS_TOKEN 13 | install: 14 | - go get -d -v -t ./... 15 | 16 | script: PATH=$HOME/gopath/bin:$PATH ginkgo --race --randomizeAllSpecs --failOnPending --skipMeasurements --cover 17 | 18 | go: 19 | - 1.2 20 | - 1.3 21 | - 1.4 22 | - tip 23 | 24 | matrix: 25 | allow_failures: 26 | - go: 1.3 27 | - go: tip 28 | 29 | env: 30 | global: 31 | secure: wulSvmmwbaIe8APoYwTjN6zLFdIXYrazmBTOuFpyui0BUpxmKdXJ/hEMVVI0p3BvehYkKU+xVrjjBc3/IZgUXFybM9MwYQ+CH4wtsMSp0ndHnzkYGaxut1kUXb+e5edjJ5bOi9Xy9qGxeH9rqpl/F1z4piGnujd2jJjVTlwVXGM= 32 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/README.md: -------------------------------------------------------------------------------- 1 | #NOAA 2 | 3 | [![Build Status](https://travis-ci.org/cloudfoundry/noaa.svg?branch=master)](https://travis-ci.org/cloudfoundry/noaa) 4 | [![Coverage Status](https://coveralls.io/repos/cloudfoundry/noaa/badge.png)](https://coveralls.io/r/cloudfoundry/noaa) 5 | [![GoDoc](https://godoc.org/github.com/cloudfoundry/noaa?status.png)](https://godoc.org/github.com/cloudfoundry/noaa) 6 | 7 | NOAA is a client library to consume metric and log messages from Doppler. 8 | 9 | ##WARNING 10 | 11 | This library does not work with Go 1.3 through 1.3.3, due to a bug in the standard libraries. 12 | 13 | ##Usage 14 | 15 | See the included sample applications. In order to use the samples, you will have to export the following environment variable: 16 | 17 | * `CF_ACCESS_TOKEN` - You can get this value by executing (`$ cf oauth-token`). Example: 18 | 19 | ```bash 20 | export CF_ACCESS_TOKEN="bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI3YmM2MzllOC0wZGM0LTQ4YzItYTAzYS0xYjkyYzRhMWFlZTIiLCJzdWIiOiI5YTc5MTVkOS04MDc1LTQ3OTUtOTBmOS02MGM0MTU0YTJlMDkiLCJzY29wZSI6WyJzY2ltLnJlYWQiLCJjbG91ZF9jb250cm9sbGVyLmFkbWluIiwicGFzc3dvcmQud3JpdGUiLCJzY2ltLndyaXRlIiwib3BlbmlkIiwiY2xvdWRfY29udHJvbGxlci53cml0ZSIsImNsb3VkX2NvbnRyb2xsZXIucmVhZCJdLCJjbGllbnRfaWQiOiJjZiIsImNpZCI6ImNmIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjlhNzkxNWQ5LTgwNzUtNDc5NS05MGY5LTYwYzQxNTRhMmUwOSIsInVzZXJfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsImlhdCI6MTQwNDg0NzU3NywiZXhwIjoxNDA0ODQ4MTc3LCJpc3MiOiJodHRwczovL3VhYS4xMC4yNDQuMC4zNC54aXAuaW8vb2F1dGgvdG9rZW4iLCJhdWQiOlsic2NpbSIsIm9wZW5pZCIsImNsb3VkX2NvbnRyb2xsZXIiLCJwYXNzd29yZCJdfQ.mAaOJthCotW763lf9fysygqdES_Mz1KFQ3HneKbwY4VJx-ARuxxiLh8l_8Srx7NJBwGlyEtfYOCBcIdvyeDCiQ0wT78Zw7ZJYFjnJ5-ZkDy5NbMqHbImDFkHRnPzKFjJHip39jyjAZpkFcrZ8_pUD8XxZraqJ4zEf6LFdAHKFBM" 21 | ``` 22 | 23 | * `DOPPLER_ADDR` - It is based on your environment. Example: 24 | 25 | ```bash 26 | export DOPPLER_ADDR="wss://doppler.10.244.0.34.xip.io:443" 27 | ``` 28 | 29 | ###Application logs 30 | 31 | The `sample/main.go` application streams logs for a particular app. The following environment variable needs to be set: 32 | 33 | * `APP_GUID` - You can get this value from running `$ cf app APP --guid`. Example: 34 | 35 | ``` 36 | export APP_GUID=55fdb274-d6c9-4b8c-9b1f-9b7e7f3a346c 37 | ``` 38 | 39 | Then you can run the sample app like this: 40 | 41 | ``` 42 | go build -o bin/sample sample/main.go 43 | bin/sample 44 | ``` 45 | 46 | ###Logs and metrics firehose 47 | 48 | The `firehose_sample/main.go` application streams metrics data and logs for all apps. 49 | 50 | You can run the firehose sample app like this: 51 | 52 | ``` 53 | go build -o bin/firehose_sample firehose_sample/main.go 54 | bin/firehose_sample 55 | ``` 56 | 57 | Multiple subscribers may connect to the firehose endpoint, each with a unique subscription_id (configurable in `main.go`). Each subscriber (in practice, a pool of clients with a common subscription_id) receives the entire stream. For each subscription_id, all data will be distributed evenly among that subscriber's client pool. 58 | 59 | 60 | ###Container metrics 61 | 62 | The `container_metrics_sample/main.go` application streams container metrics for the specified appId. 63 | 64 | You can run the container metrics sample app like this: 65 | 66 | ``` 67 | go build -o bin/containermetrics_sample container_metrics_sample/main.go 68 | bin/containermetrics_sample 69 | ``` 70 | 71 | For more information to setup a test environment in order to pull container metrics look at the README.md in the container_metrics_sample. 72 | 73 | ##Development 74 | 75 | Use `go get -d -v -t ./... && ginkgo --race --randomizeAllSpecs --failOnPending --skipMeasurements --cover` to 76 | run the tests. 77 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/debug_printer.go: -------------------------------------------------------------------------------- 1 | package noaa 2 | 3 | type DebugPrinter interface { 4 | Print(title, dump string) 5 | } 6 | 7 | type nullDebugPrinter struct { 8 | } 9 | 10 | func (nullDebugPrinter) Print(title, body string) { 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/errors/error_codes.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | const ERR_LOST_CONNECTION = int32(1) 4 | const ERR_DIAL = int32(2) 5 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/errors/unauthorized_error.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | type UnauthorizedError struct { 4 | description string 5 | } 6 | 7 | func NewUnauthorizedError(description string) error { 8 | return &UnauthorizedError{description: description} 9 | } 10 | 11 | func (err *UnauthorizedError) Error() string { 12 | return "Unauthorized error: " + err.description 13 | } 14 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/events/error.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. 2 | // source: error.proto 3 | // DO NOT EDIT! 4 | 5 | package events 6 | 7 | import proto "github.com/gogo/protobuf/proto" 8 | import math "math" 9 | 10 | // discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" 11 | 12 | import io "io" 13 | import fmt "fmt" 14 | import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" 15 | 16 | // Reference imports to suppress errors if they are not otherwise used. 17 | var _ = proto.Marshal 18 | var _ = math.Inf 19 | 20 | // / An Error event represents an error in the originating process. 21 | type Error struct { 22 | Source *string `protobuf:"bytes,1,req,name=source" json:"source,omitempty"` 23 | Code *int32 `protobuf:"varint,2,req,name=code" json:"code,omitempty"` 24 | Message *string `protobuf:"bytes,3,req,name=message" json:"message,omitempty"` 25 | XXX_unrecognized []byte `json:"-"` 26 | } 27 | 28 | func (m *Error) Reset() { *m = Error{} } 29 | func (m *Error) String() string { return proto.CompactTextString(m) } 30 | func (*Error) ProtoMessage() {} 31 | 32 | func (m *Error) GetSource() string { 33 | if m != nil && m.Source != nil { 34 | return *m.Source 35 | } 36 | return "" 37 | } 38 | 39 | func (m *Error) GetCode() int32 { 40 | if m != nil && m.Code != nil { 41 | return *m.Code 42 | } 43 | return 0 44 | } 45 | 46 | func (m *Error) GetMessage() string { 47 | if m != nil && m.Message != nil { 48 | return *m.Message 49 | } 50 | return "" 51 | } 52 | 53 | func init() { 54 | } 55 | func (m *Error) Unmarshal(data []byte) error { 56 | var hasFields [1]uint64 57 | l := len(data) 58 | index := 0 59 | for index < l { 60 | var wire uint64 61 | for shift := uint(0); ; shift += 7 { 62 | if index >= l { 63 | return io.ErrUnexpectedEOF 64 | } 65 | b := data[index] 66 | index++ 67 | wire |= (uint64(b) & 0x7F) << shift 68 | if b < 0x80 { 69 | break 70 | } 71 | } 72 | fieldNum := int32(wire >> 3) 73 | wireType := int(wire & 0x7) 74 | switch fieldNum { 75 | case 1: 76 | if wireType != 2 { 77 | return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) 78 | } 79 | var stringLen uint64 80 | for shift := uint(0); ; shift += 7 { 81 | if index >= l { 82 | return io.ErrUnexpectedEOF 83 | } 84 | b := data[index] 85 | index++ 86 | stringLen |= (uint64(b) & 0x7F) << shift 87 | if b < 0x80 { 88 | break 89 | } 90 | } 91 | postIndex := index + int(stringLen) 92 | if postIndex > l { 93 | return io.ErrUnexpectedEOF 94 | } 95 | s := string(data[index:postIndex]) 96 | m.Source = &s 97 | index = postIndex 98 | hasFields[0] |= uint64(0x00000001) 99 | case 2: 100 | if wireType != 0 { 101 | return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) 102 | } 103 | var v int32 104 | for shift := uint(0); ; shift += 7 { 105 | if index >= l { 106 | return io.ErrUnexpectedEOF 107 | } 108 | b := data[index] 109 | index++ 110 | v |= (int32(b) & 0x7F) << shift 111 | if b < 0x80 { 112 | break 113 | } 114 | } 115 | m.Code = &v 116 | hasFields[0] |= uint64(0x00000002) 117 | case 3: 118 | if wireType != 2 { 119 | return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) 120 | } 121 | var stringLen uint64 122 | for shift := uint(0); ; shift += 7 { 123 | if index >= l { 124 | return io.ErrUnexpectedEOF 125 | } 126 | b := data[index] 127 | index++ 128 | stringLen |= (uint64(b) & 0x7F) << shift 129 | if b < 0x80 { 130 | break 131 | } 132 | } 133 | postIndex := index + int(stringLen) 134 | if postIndex > l { 135 | return io.ErrUnexpectedEOF 136 | } 137 | s := string(data[index:postIndex]) 138 | m.Message = &s 139 | index = postIndex 140 | hasFields[0] |= uint64(0x00000004) 141 | default: 142 | var sizeOfWire int 143 | for { 144 | sizeOfWire++ 145 | wire >>= 7 146 | if wire == 0 { 147 | break 148 | } 149 | } 150 | index -= sizeOfWire 151 | skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) 152 | if err != nil { 153 | return err 154 | } 155 | if (index + skippy) > l { 156 | return io.ErrUnexpectedEOF 157 | } 158 | m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) 159 | index += skippy 160 | } 161 | } 162 | if hasFields[0]&uint64(0x00000001) == 0 { 163 | return github_com_gogo_protobuf_proto.NewRequiredNotSetError("source") 164 | } 165 | if hasFields[0]&uint64(0x00000002) == 0 { 166 | return github_com_gogo_protobuf_proto.NewRequiredNotSetError("code") 167 | } 168 | if hasFields[0]&uint64(0x00000004) == 0 { 169 | return github_com_gogo_protobuf_proto.NewRequiredNotSetError("message") 170 | } 171 | 172 | return nil 173 | } 174 | func (m *Error) Size() (n int) { 175 | var l int 176 | _ = l 177 | if m.Source != nil { 178 | l = len(*m.Source) 179 | n += 1 + l + sovError(uint64(l)) 180 | } 181 | if m.Code != nil { 182 | n += 1 + sovError(uint64(*m.Code)) 183 | } 184 | if m.Message != nil { 185 | l = len(*m.Message) 186 | n += 1 + l + sovError(uint64(l)) 187 | } 188 | if m.XXX_unrecognized != nil { 189 | n += len(m.XXX_unrecognized) 190 | } 191 | return n 192 | } 193 | 194 | func sovError(x uint64) (n int) { 195 | for { 196 | n++ 197 | x >>= 7 198 | if x == 0 { 199 | break 200 | } 201 | } 202 | return n 203 | } 204 | func sozError(x uint64) (n int) { 205 | return sovError(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 206 | } 207 | func (m *Error) Marshal() (data []byte, err error) { 208 | size := m.Size() 209 | data = make([]byte, size) 210 | n, err := m.MarshalTo(data) 211 | if err != nil { 212 | return nil, err 213 | } 214 | return data[:n], nil 215 | } 216 | 217 | func (m *Error) MarshalTo(data []byte) (n int, err error) { 218 | var i int 219 | _ = i 220 | var l int 221 | _ = l 222 | if m.Source == nil { 223 | return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("source") 224 | } else { 225 | data[i] = 0xa 226 | i++ 227 | i = encodeVarintError(data, i, uint64(len(*m.Source))) 228 | i += copy(data[i:], *m.Source) 229 | } 230 | if m.Code == nil { 231 | return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("code") 232 | } else { 233 | data[i] = 0x10 234 | i++ 235 | i = encodeVarintError(data, i, uint64(*m.Code)) 236 | } 237 | if m.Message == nil { 238 | return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("message") 239 | } else { 240 | data[i] = 0x1a 241 | i++ 242 | i = encodeVarintError(data, i, uint64(len(*m.Message))) 243 | i += copy(data[i:], *m.Message) 244 | } 245 | if m.XXX_unrecognized != nil { 246 | i += copy(data[i:], m.XXX_unrecognized) 247 | } 248 | return i, nil 249 | } 250 | 251 | func encodeFixed64Error(data []byte, offset int, v uint64) int { 252 | data[offset] = uint8(v) 253 | data[offset+1] = uint8(v >> 8) 254 | data[offset+2] = uint8(v >> 16) 255 | data[offset+3] = uint8(v >> 24) 256 | data[offset+4] = uint8(v >> 32) 257 | data[offset+5] = uint8(v >> 40) 258 | data[offset+6] = uint8(v >> 48) 259 | data[offset+7] = uint8(v >> 56) 260 | return offset + 8 261 | } 262 | func encodeFixed32Error(data []byte, offset int, v uint32) int { 263 | data[offset] = uint8(v) 264 | data[offset+1] = uint8(v >> 8) 265 | data[offset+2] = uint8(v >> 16) 266 | data[offset+3] = uint8(v >> 24) 267 | return offset + 4 268 | } 269 | func encodeVarintError(data []byte, offset int, v uint64) int { 270 | for v >= 1<<7 { 271 | data[offset] = uint8(v&0x7f | 0x80) 272 | v >>= 7 273 | offset++ 274 | } 275 | data[offset] = uint8(v) 276 | return offset + 1 277 | } 278 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/events/event.go: -------------------------------------------------------------------------------- 1 | package events 2 | 3 | type Event interface { 4 | ProtoMessage() 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/events/generate-events.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | OUT_DIR=`dirname $0` 4 | OUT_DIR=`cd $OUT_DIR && pwd` 5 | 6 | PROTO_DIR=$OUT_DIR/../dropsonde-protocol 7 | 8 | cd $PROTO_DIR 9 | ./generate-go.sh $OUT_DIR -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/events/uuid.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. 2 | // source: uuid.proto 3 | // DO NOT EDIT! 4 | 5 | package events 6 | 7 | import proto "github.com/gogo/protobuf/proto" 8 | import math "math" 9 | 10 | // discarding unused import gogoproto "github.com/gogo/protobuf/gogoproto/gogo.pb" 11 | 12 | import io "io" 13 | import fmt "fmt" 14 | import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" 15 | 16 | // Reference imports to suppress errors if they are not otherwise used. 17 | var _ = proto.Marshal 18 | var _ = math.Inf 19 | 20 | // / Type representing a 128-bit UUID. 21 | // 22 | // The bytes of the UUID should be packed in little-endian **byte** (not bit) order. For example, the UUID `f47ac10b-58cc-4372-a567-0e02b2c3d479` should be encoded as `UUID{ low: 0x7243cc580bc17af4, high: 0x79d4c3b2020e67a5 }` 23 | type UUID struct { 24 | Low *uint64 `protobuf:"varint,1,req,name=low" json:"low,omitempty"` 25 | High *uint64 `protobuf:"varint,2,req,name=high" json:"high,omitempty"` 26 | XXX_unrecognized []byte `json:"-"` 27 | } 28 | 29 | func (m *UUID) Reset() { *m = UUID{} } 30 | func (m *UUID) String() string { return proto.CompactTextString(m) } 31 | func (*UUID) ProtoMessage() {} 32 | 33 | func (m *UUID) GetLow() uint64 { 34 | if m != nil && m.Low != nil { 35 | return *m.Low 36 | } 37 | return 0 38 | } 39 | 40 | func (m *UUID) GetHigh() uint64 { 41 | if m != nil && m.High != nil { 42 | return *m.High 43 | } 44 | return 0 45 | } 46 | 47 | func init() { 48 | } 49 | func (m *UUID) Unmarshal(data []byte) error { 50 | var hasFields [1]uint64 51 | l := len(data) 52 | index := 0 53 | for index < l { 54 | var wire uint64 55 | for shift := uint(0); ; shift += 7 { 56 | if index >= l { 57 | return io.ErrUnexpectedEOF 58 | } 59 | b := data[index] 60 | index++ 61 | wire |= (uint64(b) & 0x7F) << shift 62 | if b < 0x80 { 63 | break 64 | } 65 | } 66 | fieldNum := int32(wire >> 3) 67 | wireType := int(wire & 0x7) 68 | switch fieldNum { 69 | case 1: 70 | if wireType != 0 { 71 | return fmt.Errorf("proto: wrong wireType = %d for field Low", wireType) 72 | } 73 | var v uint64 74 | for shift := uint(0); ; shift += 7 { 75 | if index >= l { 76 | return io.ErrUnexpectedEOF 77 | } 78 | b := data[index] 79 | index++ 80 | v |= (uint64(b) & 0x7F) << shift 81 | if b < 0x80 { 82 | break 83 | } 84 | } 85 | m.Low = &v 86 | hasFields[0] |= uint64(0x00000001) 87 | case 2: 88 | if wireType != 0 { 89 | return fmt.Errorf("proto: wrong wireType = %d for field High", wireType) 90 | } 91 | var v uint64 92 | for shift := uint(0); ; shift += 7 { 93 | if index >= l { 94 | return io.ErrUnexpectedEOF 95 | } 96 | b := data[index] 97 | index++ 98 | v |= (uint64(b) & 0x7F) << shift 99 | if b < 0x80 { 100 | break 101 | } 102 | } 103 | m.High = &v 104 | hasFields[0] |= uint64(0x00000002) 105 | default: 106 | var sizeOfWire int 107 | for { 108 | sizeOfWire++ 109 | wire >>= 7 110 | if wire == 0 { 111 | break 112 | } 113 | } 114 | index -= sizeOfWire 115 | skippy, err := github_com_gogo_protobuf_proto.Skip(data[index:]) 116 | if err != nil { 117 | return err 118 | } 119 | if (index + skippy) > l { 120 | return io.ErrUnexpectedEOF 121 | } 122 | m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...) 123 | index += skippy 124 | } 125 | } 126 | if hasFields[0]&uint64(0x00000001) == 0 { 127 | return github_com_gogo_protobuf_proto.NewRequiredNotSetError("low") 128 | } 129 | if hasFields[0]&uint64(0x00000002) == 0 { 130 | return github_com_gogo_protobuf_proto.NewRequiredNotSetError("high") 131 | } 132 | 133 | return nil 134 | } 135 | func (m *UUID) Size() (n int) { 136 | var l int 137 | _ = l 138 | if m.Low != nil { 139 | n += 1 + sovUuid(uint64(*m.Low)) 140 | } 141 | if m.High != nil { 142 | n += 1 + sovUuid(uint64(*m.High)) 143 | } 144 | if m.XXX_unrecognized != nil { 145 | n += len(m.XXX_unrecognized) 146 | } 147 | return n 148 | } 149 | 150 | func sovUuid(x uint64) (n int) { 151 | for { 152 | n++ 153 | x >>= 7 154 | if x == 0 { 155 | break 156 | } 157 | } 158 | return n 159 | } 160 | func sozUuid(x uint64) (n int) { 161 | return sovUuid(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 162 | } 163 | func (m *UUID) Marshal() (data []byte, err error) { 164 | size := m.Size() 165 | data = make([]byte, size) 166 | n, err := m.MarshalTo(data) 167 | if err != nil { 168 | return nil, err 169 | } 170 | return data[:n], nil 171 | } 172 | 173 | func (m *UUID) MarshalTo(data []byte) (n int, err error) { 174 | var i int 175 | _ = i 176 | var l int 177 | _ = l 178 | if m.Low == nil { 179 | return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("low") 180 | } else { 181 | data[i] = 0x8 182 | i++ 183 | i = encodeVarintUuid(data, i, uint64(*m.Low)) 184 | } 185 | if m.High == nil { 186 | return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("high") 187 | } else { 188 | data[i] = 0x10 189 | i++ 190 | i = encodeVarintUuid(data, i, uint64(*m.High)) 191 | } 192 | if m.XXX_unrecognized != nil { 193 | i += copy(data[i:], m.XXX_unrecognized) 194 | } 195 | return i, nil 196 | } 197 | 198 | func encodeFixed64Uuid(data []byte, offset int, v uint64) int { 199 | data[offset] = uint8(v) 200 | data[offset+1] = uint8(v >> 8) 201 | data[offset+2] = uint8(v >> 16) 202 | data[offset+3] = uint8(v >> 24) 203 | data[offset+4] = uint8(v >> 32) 204 | data[offset+5] = uint8(v >> 40) 205 | data[offset+6] = uint8(v >> 48) 206 | data[offset+7] = uint8(v >> 56) 207 | return offset + 8 208 | } 209 | func encodeFixed32Uuid(data []byte, offset int, v uint32) int { 210 | data[offset] = uint8(v) 211 | data[offset+1] = uint8(v >> 8) 212 | data[offset+2] = uint8(v >> 16) 213 | data[offset+3] = uint8(v >> 24) 214 | return offset + 4 215 | } 216 | func encodeVarintUuid(data []byte, offset int, v uint64) int { 217 | for v >= 1<<7 { 218 | data[offset] = uint8(v&0x7f | 0x80) 219 | v >>= 7 220 | offset++ 221 | } 222 | data[offset] = uint8(v) 223 | return offset + 1 224 | } 225 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/sort_container_metrics.go: -------------------------------------------------------------------------------- 1 | package noaa 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "sort" 6 | ) 7 | 8 | // SortContainerMetrics sorts a slice of containerMetrics by InstanceIndex. 9 | // 10 | // The input slice is sorted; the return value is simply a pointer to the same slice. 11 | func SortContainerMetrics(messages []*events.ContainerMetric) []*events.ContainerMetric { 12 | sort.Sort(containerMetricSlice(messages)) 13 | return messages 14 | } 15 | 16 | type containerMetricSlice []*events.ContainerMetric 17 | 18 | func (lms containerMetricSlice) Len() int { 19 | return len(lms) 20 | } 21 | 22 | func (lms containerMetricSlice) Less(i, j int) bool { 23 | return (*(lms[i])).GetInstanceIndex() < (*(lms[j])).GetInstanceIndex() 24 | } 25 | 26 | func (lms containerMetricSlice) Swap(i, j int) { 27 | lms[i], lms[j] = lms[j], lms[i] 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/cloudfoundry/noaa/sort_recent.go: -------------------------------------------------------------------------------- 1 | package noaa 2 | 3 | import ( 4 | "github.com/cloudfoundry/noaa/events" 5 | "sort" 6 | ) 7 | 8 | // SortRecent sorts a slice of LogMessages by timestamp. The sort is stable, so messages with the same timestamp are sorted 9 | // in the order that they are received. 10 | // 11 | // The input slice is sorted; the return value is simply a pointer to the same slice. 12 | func SortRecent(messages []*events.LogMessage) []*events.LogMessage { 13 | sort.Stable(logMessageSlice(messages)) 14 | return messages 15 | } 16 | 17 | type logMessageSlice []*events.LogMessage 18 | 19 | func (lms logMessageSlice) Len() int { 20 | return len(lms) 21 | } 22 | 23 | func (lms logMessageSlice) Less(i, j int) bool { 24 | return *(lms[i]).Timestamp < *(lms[j]).Timestamp 25 | } 26 | 27 | func (lms logMessageSlice) Swap(i, j int) { 28 | lms[i], lms[j] = lms[j], lms[i] 29 | } 30 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/LICENSE: -------------------------------------------------------------------------------- 1 | Extensions for Protocol Buffers to create more go like structures. 2 | 3 | Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 4 | http://github.com/gogo/protobuf/gogoproto 5 | 6 | Go support for Protocol Buffers - Google's data interchange format 7 | 8 | Copyright 2010 The Go Authors. All rights reserved. 9 | https://github.com/golang/protobuf 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are 13 | met: 14 | 15 | * Redistributions of source code must retain the above copyright 16 | notice, this list of conditions and the following disclaimer. 17 | * Redistributions in binary form must reproduce the above 18 | copyright notice, this list of conditions and the following disclaimer 19 | in the documentation and/or other materials provided with the 20 | distribution. 21 | * Neither the name of Google Inc. nor the names of its 22 | contributors may be used to endorse or promote products derived from 23 | this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | 37 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/Makefile: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers - Google's data interchange format 2 | # 3 | # Copyright 2010 The Go Authors. All rights reserved. 4 | # https://github.com/golang/protobuf 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | install: 33 | go install 34 | 35 | test: install generate-test-pbs 36 | go test 37 | 38 | 39 | generate-test-pbs: 40 | make install 41 | make -C testdata 42 | protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto 43 | make 44 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/decode_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "reflect" 31 | ) 32 | 33 | // Decode a reference to a struct pointer. 34 | func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) { 35 | raw, e := o.DecodeRawBytes(false) 36 | if e != nil { 37 | return e 38 | } 39 | 40 | // If the object can unmarshal itself, let it. 41 | if p.isUnmarshaler { 42 | panic("not supported, since this is a pointer receiver") 43 | } 44 | 45 | obuf := o.buf 46 | oi := o.index 47 | o.buf = raw 48 | o.index = 0 49 | 50 | bas := structPointer_FieldPointer(base, p.field) 51 | 52 | err = o.unmarshalType(p.stype, p.sprop, false, bas) 53 | o.buf = obuf 54 | o.index = oi 55 | 56 | return err 57 | } 58 | 59 | // Decode a slice of references to struct pointers ([]struct). 60 | func (o *Buffer) dec_slice_ref_struct(p *Properties, is_group bool, base structPointer) error { 61 | newBas := appendStructPointer(base, p.field, p.sstype) 62 | 63 | if is_group { 64 | panic("not supported, maybe in future, if requested.") 65 | } 66 | 67 | raw, err := o.DecodeRawBytes(false) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | // If the object can unmarshal itself, let it. 73 | if p.isUnmarshaler { 74 | panic("not supported, since this is not a pointer receiver.") 75 | } 76 | 77 | obuf := o.buf 78 | oi := o.index 79 | o.buf = raw 80 | o.index = 0 81 | 82 | err = o.unmarshalType(p.stype, p.sprop, is_group, newBas) 83 | 84 | o.buf = obuf 85 | o.index = oi 86 | 87 | return err 88 | } 89 | 90 | // Decode a slice of references to struct pointers. 91 | func (o *Buffer) dec_slice_ref_struct_message(p *Properties, base structPointer) error { 92 | return o.dec_slice_ref_struct(p, false, base) 93 | } 94 | 95 | func setPtrCustomType(base structPointer, f field, v interface{}) { 96 | if v == nil { 97 | return 98 | } 99 | structPointer_SetStructPointer(base, f, structPointer(reflect.ValueOf(v).Pointer())) 100 | } 101 | 102 | func setCustomType(base structPointer, f field, value interface{}) { 103 | if value == nil { 104 | return 105 | } 106 | v := reflect.ValueOf(value).Elem() 107 | t := reflect.TypeOf(value).Elem() 108 | kind := t.Kind() 109 | switch kind { 110 | case reflect.Slice: 111 | slice := reflect.MakeSlice(t, v.Len(), v.Cap()) 112 | reflect.Copy(slice, v) 113 | oldHeader := structPointer_GetSliceHeader(base, f) 114 | oldHeader.Data = slice.Pointer() 115 | oldHeader.Len = v.Len() 116 | oldHeader.Cap = v.Cap() 117 | default: 118 | l := 1 119 | size := reflect.TypeOf(value).Elem().Size() 120 | if kind == reflect.Array { 121 | l = reflect.TypeOf(value).Elem().Len() 122 | size = reflect.TypeOf(value).Size() 123 | } 124 | total := int(size) * l 125 | structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), total) 126 | } 127 | } 128 | 129 | func (o *Buffer) dec_custom_bytes(p *Properties, base structPointer) error { 130 | b, err := o.DecodeRawBytes(true) 131 | if err != nil { 132 | return err 133 | } 134 | i := reflect.New(p.ctype.Elem()).Interface() 135 | custom := (i).(Unmarshaler) 136 | if err := custom.Unmarshal(b); err != nil { 137 | return err 138 | } 139 | setPtrCustomType(base, p.field, custom) 140 | return nil 141 | } 142 | 143 | func (o *Buffer) dec_custom_ref_bytes(p *Properties, base structPointer) error { 144 | b, err := o.DecodeRawBytes(true) 145 | if err != nil { 146 | return err 147 | } 148 | i := reflect.New(p.ctype).Interface() 149 | custom := (i).(Unmarshaler) 150 | if err := custom.Unmarshal(b); err != nil { 151 | return err 152 | } 153 | if custom != nil { 154 | setCustomType(base, p.field, custom) 155 | } 156 | return nil 157 | } 158 | 159 | // Decode a slice of bytes ([]byte) into a slice of custom types. 160 | func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error { 161 | b, err := o.DecodeRawBytes(true) 162 | if err != nil { 163 | return err 164 | } 165 | i := reflect.New(p.ctype.Elem()).Interface() 166 | custom := (i).(Unmarshaler) 167 | if err := custom.Unmarshal(b); err != nil { 168 | return err 169 | } 170 | newBas := appendStructPointer(base, p.field, p.ctype) 171 | 172 | setCustomType(newBas, 0, custom) 173 | 174 | return nil 175 | } 176 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/extensions_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "bytes" 31 | "errors" 32 | "fmt" 33 | "reflect" 34 | "sort" 35 | "strings" 36 | ) 37 | 38 | func GetBoolExtension(pb extendableProto, extension *ExtensionDesc, ifnotset bool) bool { 39 | if reflect.ValueOf(pb).IsNil() { 40 | return ifnotset 41 | } 42 | value, err := GetExtension(pb, extension) 43 | if err != nil { 44 | return ifnotset 45 | } 46 | if value == nil { 47 | return ifnotset 48 | } 49 | if value.(*bool) == nil { 50 | return ifnotset 51 | } 52 | return *(value.(*bool)) 53 | } 54 | 55 | func (this *Extension) Equal(that *Extension) bool { 56 | return bytes.Equal(this.enc, that.enc) 57 | } 58 | 59 | func SizeOfExtensionMap(m map[int32]Extension) (n int) { 60 | return sizeExtensionMap(m) 61 | } 62 | 63 | type sortableMapElem struct { 64 | field int32 65 | ext Extension 66 | } 67 | 68 | func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions { 69 | s := make(sortableExtensions, 0, len(m)) 70 | for k, v := range m { 71 | s = append(s, &sortableMapElem{field: k, ext: v}) 72 | } 73 | return s 74 | } 75 | 76 | type sortableExtensions []*sortableMapElem 77 | 78 | func (this sortableExtensions) Len() int { return len(this) } 79 | 80 | func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] } 81 | 82 | func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field } 83 | 84 | func (this sortableExtensions) String() string { 85 | sort.Sort(this) 86 | ss := make([]string, len(this)) 87 | for i := range this { 88 | ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext) 89 | } 90 | return "map[" + strings.Join(ss, ",") + "]" 91 | } 92 | 93 | func StringFromExtensionsMap(m map[int32]Extension) string { 94 | return newSortableExtensionsFromMap(m).String() 95 | } 96 | 97 | func StringFromExtensionsBytes(ext []byte) string { 98 | m, err := BytesToExtensionsMap(ext) 99 | if err != nil { 100 | panic(err) 101 | } 102 | return StringFromExtensionsMap(m) 103 | } 104 | 105 | func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) { 106 | if err := encodeExtensionMap(m); err != nil { 107 | return 0, err 108 | } 109 | keys := make([]int, 0, len(m)) 110 | for k := range m { 111 | keys = append(keys, int(k)) 112 | } 113 | sort.Ints(keys) 114 | for _, k := range keys { 115 | n += copy(data[n:], m[int32(k)].enc) 116 | } 117 | return n, nil 118 | } 119 | 120 | func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) { 121 | if m[id].value == nil || m[id].desc == nil { 122 | return m[id].enc, nil 123 | } 124 | if err := encodeExtensionMap(m); err != nil { 125 | return nil, err 126 | } 127 | return m[id].enc, nil 128 | } 129 | 130 | func size(buf []byte, wire int) (int, error) { 131 | switch wire { 132 | case WireVarint: 133 | _, n := DecodeVarint(buf) 134 | return n, nil 135 | case WireFixed64: 136 | return 8, nil 137 | case WireBytes: 138 | v, n := DecodeVarint(buf) 139 | return int(v) + n, nil 140 | case WireFixed32: 141 | return 4, nil 142 | case WireStartGroup: 143 | offset := 0 144 | for { 145 | u, n := DecodeVarint(buf[offset:]) 146 | fwire := int(u & 0x7) 147 | offset += n 148 | if fwire == WireEndGroup { 149 | return offset, nil 150 | } 151 | s, err := size(buf[offset:], wire) 152 | if err != nil { 153 | return 0, err 154 | } 155 | offset += s 156 | } 157 | } 158 | return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire) 159 | } 160 | 161 | func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) { 162 | m := make(map[int32]Extension) 163 | i := 0 164 | for i < len(buf) { 165 | tag, n := DecodeVarint(buf[i:]) 166 | if n <= 0 { 167 | return nil, fmt.Errorf("unable to decode varint") 168 | } 169 | fieldNum := int32(tag >> 3) 170 | wireType := int(tag & 0x7) 171 | l, err := size(buf[i+n:], wireType) 172 | if err != nil { 173 | return nil, err 174 | } 175 | end := i + int(l) + n 176 | m[int32(fieldNum)] = Extension{enc: buf[i:end]} 177 | i = end 178 | } 179 | return m, nil 180 | } 181 | 182 | func NewExtension(e []byte) Extension { 183 | ee := Extension{enc: make([]byte, len(e))} 184 | copy(ee.enc, e) 185 | return ee 186 | } 187 | 188 | func (this Extension) GoString() string { 189 | if this.enc == nil { 190 | if err := encodeExtension(&this); err != nil { 191 | panic(err) 192 | } 193 | } 194 | return fmt.Sprintf("proto.NewExtension(%#v)", this.enc) 195 | } 196 | 197 | func SetUnsafeExtension(pb extendableProto, fieldNum int32, value interface{}) error { 198 | typ := reflect.TypeOf(pb).Elem() 199 | ext, ok := extensionMaps[typ] 200 | if !ok { 201 | return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) 202 | } 203 | desc, ok := ext[fieldNum] 204 | if !ok { 205 | return errors.New("proto: bad extension number; not in declared ranges") 206 | } 207 | return setExtension(pb, desc, value) 208 | } 209 | 210 | func GetUnsafeExtension(pb extendableProto, fieldNum int32) (interface{}, error) { 211 | typ := reflect.TypeOf(pb).Elem() 212 | ext, ok := extensionMaps[typ] 213 | if !ok { 214 | return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) 215 | } 216 | desc, ok := ext[fieldNum] 217 | if !ok { 218 | return nil, fmt.Errorf("unregistered field number %d", fieldNum) 219 | } 220 | return GetExtension(pb, desc) 221 | } 222 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/lib_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "encoding/json" 31 | "strconv" 32 | ) 33 | 34 | func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) { 35 | s, ok := m[value] 36 | if !ok { 37 | s = strconv.Itoa(int(value)) 38 | } 39 | return json.Marshal(s) 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | // +build !appengine 28 | 29 | // This file contains the implementation of the proto field accesses using package unsafe. 30 | 31 | package proto 32 | 33 | import ( 34 | "reflect" 35 | "unsafe" 36 | ) 37 | 38 | func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} { 39 | point := unsafe.Pointer(uintptr(p) + uintptr(f)) 40 | r := reflect.NewAt(t, point) 41 | return r.Interface() 42 | } 43 | 44 | func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} { 45 | point := unsafe.Pointer(uintptr(p) + uintptr(f)) 46 | r := reflect.NewAt(t, point) 47 | if r.Elem().IsNil() { 48 | return nil 49 | } 50 | return r.Elem().Interface() 51 | } 52 | 53 | func copyUintPtr(oldptr, newptr uintptr, size int) { 54 | oldbytes := make([]byte, 0) 55 | oldslice := (*reflect.SliceHeader)(unsafe.Pointer(&oldbytes)) 56 | oldslice.Data = oldptr 57 | oldslice.Len = size 58 | oldslice.Cap = size 59 | newbytes := make([]byte, 0) 60 | newslice := (*reflect.SliceHeader)(unsafe.Pointer(&newbytes)) 61 | newslice.Data = newptr 62 | newslice.Len = size 63 | newslice.Cap = size 64 | copy(newbytes, oldbytes) 65 | } 66 | 67 | func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) { 68 | copyUintPtr(uintptr(oldptr), uintptr(newptr), size) 69 | } 70 | 71 | func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer { 72 | size := typ.Elem().Size() 73 | oldHeader := structPointer_GetSliceHeader(base, f) 74 | newLen := oldHeader.Len + 1 75 | slice := reflect.MakeSlice(typ, newLen, newLen) 76 | bas := toStructPointer(slice) 77 | for i := 0; i < oldHeader.Len; i++ { 78 | newElemptr := uintptr(bas) + uintptr(i)*size 79 | oldElemptr := oldHeader.Data + uintptr(i)*size 80 | copyUintPtr(oldElemptr, newElemptr, int(size)) 81 | } 82 | 83 | oldHeader.Data = uintptr(bas) 84 | oldHeader.Len = newLen 85 | oldHeader.Cap = newLen 86 | 87 | return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size))) 88 | } 89 | 90 | func structPointer_FieldPointer(p structPointer, f field) structPointer { 91 | return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f))) 92 | } 93 | 94 | func structPointer_GetRefStructPointer(p structPointer, f field) structPointer { 95 | return structPointer((*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))) 96 | } 97 | 98 | func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader { 99 | return (*reflect.SliceHeader)(unsafe.Pointer(uintptr(p) + uintptr(f))) 100 | } 101 | 102 | func structPointer_Add(p structPointer, size field) structPointer { 103 | return structPointer(unsafe.Pointer(uintptr(p) + uintptr(size))) 104 | } 105 | 106 | func structPointer_Len(p structPointer, f field) int { 107 | return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f)))) 108 | } 109 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/properties_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "fmt" 31 | "os" 32 | "reflect" 33 | ) 34 | 35 | func (p *Properties) setCustomEncAndDec(typ reflect.Type) { 36 | p.ctype = typ 37 | if p.Repeated { 38 | p.enc = (*Buffer).enc_custom_slice_bytes 39 | p.dec = (*Buffer).dec_custom_slice_bytes 40 | p.size = size_custom_slice_bytes 41 | } else if typ.Kind() == reflect.Ptr { 42 | p.enc = (*Buffer).enc_custom_bytes 43 | p.dec = (*Buffer).dec_custom_bytes 44 | p.size = size_custom_bytes 45 | } else { 46 | p.enc = (*Buffer).enc_custom_ref_bytes 47 | p.dec = (*Buffer).dec_custom_ref_bytes 48 | p.size = size_custom_ref_bytes 49 | } 50 | } 51 | 52 | func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) { 53 | t2 := typ.Elem() 54 | p.sstype = typ 55 | p.stype = t2 56 | p.isMarshaler = isMarshaler(t2) 57 | p.isUnmarshaler = isUnmarshaler(t2) 58 | p.enc = (*Buffer).enc_slice_ref_struct_message 59 | p.dec = (*Buffer).dec_slice_ref_struct_message 60 | p.size = size_slice_ref_struct_message 61 | if p.Wire != "bytes" { 62 | fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T \n", typ, t2) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/skip_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "fmt" 31 | "io" 32 | ) 33 | 34 | func Skip(data []byte) (n int, err error) { 35 | l := len(data) 36 | index := 0 37 | for index < l { 38 | var wire uint64 39 | for shift := uint(0); ; shift += 7 { 40 | if index >= l { 41 | return 0, io.ErrUnexpectedEOF 42 | } 43 | b := data[index] 44 | index++ 45 | wire |= (uint64(b) & 0x7F) << shift 46 | if b < 0x80 { 47 | break 48 | } 49 | } 50 | wireType := int(wire & 0x7) 51 | switch wireType { 52 | case 0: 53 | for { 54 | if index >= l { 55 | return 0, io.ErrUnexpectedEOF 56 | } 57 | index++ 58 | if data[index-1] < 0x80 { 59 | break 60 | } 61 | } 62 | return index, nil 63 | case 1: 64 | index += 8 65 | return index, nil 66 | case 2: 67 | var length int 68 | for shift := uint(0); ; shift += 7 { 69 | if index >= l { 70 | return 0, io.ErrUnexpectedEOF 71 | } 72 | b := data[index] 73 | index++ 74 | length |= (int(b) & 0x7F) << shift 75 | if b < 0x80 { 76 | break 77 | } 78 | } 79 | index += length 80 | return index, nil 81 | case 3: 82 | for { 83 | var innerWire uint64 84 | var start int = index 85 | for shift := uint(0); ; shift += 7 { 86 | if index >= l { 87 | return 0, io.ErrUnexpectedEOF 88 | } 89 | b := data[index] 90 | index++ 91 | innerWire |= (uint64(b) & 0x7F) << shift 92 | if b < 0x80 { 93 | break 94 | } 95 | } 96 | innerWireType := int(innerWire & 0x7) 97 | if innerWireType == 4 { 98 | break 99 | } 100 | next, err := Skip(data[start:]) 101 | if err != nil { 102 | return 0, err 103 | } 104 | index = start + next 105 | } 106 | return index, nil 107 | case 4: 108 | return index, nil 109 | case 5: 110 | index += 4 111 | return index, nil 112 | default: 113 | return 0, fmt.Errorf("proto: illegal wireType %d", wireType) 114 | } 115 | } 116 | panic("unreachable") 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/gogo/protobuf/proto/text_gogo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 2 | // http://github.com/gogo/protobuf/gogoproto 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | package proto 28 | 29 | import ( 30 | "fmt" 31 | "reflect" 32 | ) 33 | 34 | func writeEnum(w *textWriter, v reflect.Value, props *Properties) error { 35 | m, ok := enumStringMaps[props.Enum] 36 | if !ok { 37 | if err := writeAny(w, v, props); err != nil { 38 | return err 39 | } 40 | } 41 | key := int32(0) 42 | if v.Kind() == reflect.Ptr { 43 | key = int32(v.Elem().Int()) 44 | } else { 45 | key = int32(v.Int()) 46 | } 47 | s, ok := m[key] 48 | if !ok { 49 | if err := writeAny(w, v, props); err != nil { 50 | return err 51 | } 52 | } 53 | _, err := fmt.Fprint(w, s) 54 | return err 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.1 5 | - 1.2 6 | - tip 7 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of Gorilla WebSocket authors for copyright 2 | # purposes. 3 | # 4 | # Please keep the list sorted. 5 | 6 | Gary Burd 7 | Joachim Bauch 8 | 9 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/README.md: -------------------------------------------------------------------------------- 1 | # Gorilla WebSocket 2 | 3 | Gorilla WebSocket is a [Go](http://golang.org/) implementation of the 4 | [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. 5 | 6 | ### Documentation 7 | 8 | * [API Reference](http://godoc.org/github.com/gorilla/websocket) 9 | * [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) 10 | * [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) 11 | 12 | ### Status 13 | 14 | The Gorilla WebSocket package provides a complete and tested implementation of 15 | the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The 16 | package API is stable. 17 | 18 | ### Installation 19 | 20 | go get github.com/gorilla/websocket 21 | 22 | ### Protocol Compliance 23 | 24 | The Gorilla WebSocket package passes the server tests in the [Autobahn Test 25 | Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn 26 | subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). 27 | 28 | ### Gorilla WebSocket compared with other packages 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Limit size of received messageYesNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
48 | 49 | Notes: 50 | 51 | 1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). 52 | 2. The application can get the type of a received data message by implementing 53 | a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) 54 | function. 55 | 3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. 56 | Read returns when the input buffer is full or a frame boundary is 57 | encountered. Each call to Write sends a single frame message. The Gorilla 58 | io.Reader and io.WriteCloser operate on a single WebSocket message. 59 | 60 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/client.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "crypto/tls" 9 | "errors" 10 | "net" 11 | "net/http" 12 | "net/url" 13 | "strings" 14 | "time" 15 | ) 16 | 17 | // ErrBadHandshake is returned when the server response to opening handshake is 18 | // invalid. 19 | var ErrBadHandshake = errors.New("websocket: bad handshake") 20 | 21 | // NewClient creates a new client connection using the given net connection. 22 | // The URL u specifies the host and request URI. Use requestHeader to specify 23 | // the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies 24 | // (Cookie). Use the response.Header to get the selected subprotocol 25 | // (Sec-WebSocket-Protocol) and cookies (Set-Cookie). 26 | // 27 | // If the WebSocket handshake fails, ErrBadHandshake is returned along with a 28 | // non-nil *http.Response so that callers can handle redirects, authentication, 29 | // etc. 30 | func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { 31 | challengeKey, err := generateChallengeKey() 32 | if err != nil { 33 | return nil, nil, err 34 | } 35 | acceptKey := computeAcceptKey(challengeKey) 36 | 37 | c = newConn(netConn, false, readBufSize, writeBufSize) 38 | p := c.writeBuf[:0] 39 | p = append(p, "GET "...) 40 | p = append(p, u.RequestURI()...) 41 | p = append(p, " HTTP/1.1\r\nHost: "...) 42 | p = append(p, u.Host...) 43 | // "Upgrade" is capitalized for servers that do not use case insensitive 44 | // comparisons on header tokens. 45 | p = append(p, "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: "...) 46 | p = append(p, challengeKey...) 47 | p = append(p, "\r\n"...) 48 | for k, vs := range requestHeader { 49 | for _, v := range vs { 50 | p = append(p, k...) 51 | p = append(p, ": "...) 52 | p = append(p, v...) 53 | p = append(p, "\r\n"...) 54 | } 55 | } 56 | p = append(p, "\r\n"...) 57 | 58 | if _, err := netConn.Write(p); err != nil { 59 | return nil, nil, err 60 | } 61 | 62 | resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET", URL: u}) 63 | if err != nil { 64 | return nil, nil, err 65 | } 66 | if resp.StatusCode != 101 || 67 | !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || 68 | !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || 69 | resp.Header.Get("Sec-Websocket-Accept") != acceptKey { 70 | return nil, resp, ErrBadHandshake 71 | } 72 | c.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") 73 | return c, resp, nil 74 | } 75 | 76 | // A Dialer contains options for connecting to WebSocket server. 77 | type Dialer struct { 78 | // NetDial specifies the dial function for creating TCP connections. If 79 | // NetDial is nil, net.Dial is used. 80 | NetDial func(network, addr string) (net.Conn, error) 81 | 82 | // TLSClientConfig specifies the TLS configuration to use with tls.Client. 83 | // If nil, the default configuration is used. 84 | TLSClientConfig *tls.Config 85 | 86 | // HandshakeTimeout specifies the duration for the handshake to complete. 87 | HandshakeTimeout time.Duration 88 | 89 | // Input and output buffer sizes. If the buffer size is zero, then a 90 | // default value of 4096 is used. 91 | ReadBufferSize, WriteBufferSize int 92 | 93 | // Subprotocols specifies the client's requested subprotocols. 94 | Subprotocols []string 95 | } 96 | 97 | var errMalformedURL = errors.New("malformed ws or wss URL") 98 | 99 | // parseURL parses the URL. The url.Parse function is not used here because 100 | // url.Parse mangles the path. 101 | func parseURL(s string) (*url.URL, error) { 102 | // From the RFC: 103 | // 104 | // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ] 105 | // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ] 106 | // 107 | // We don't use the net/url parser here because the dialer interface does 108 | // not provide a way for applications to work around percent deocding in 109 | // the net/url parser. 110 | 111 | var u url.URL 112 | switch { 113 | case strings.HasPrefix(s, "ws://"): 114 | u.Scheme = "ws" 115 | s = s[len("ws://"):] 116 | case strings.HasPrefix(s, "wss://"): 117 | u.Scheme = "wss" 118 | s = s[len("wss://"):] 119 | default: 120 | return nil, errMalformedURL 121 | } 122 | 123 | u.Host = s 124 | u.Opaque = "/" 125 | if i := strings.Index(s, "/"); i >= 0 { 126 | u.Host = s[:i] 127 | u.Opaque = s[i:] 128 | } 129 | 130 | return &u, nil 131 | } 132 | 133 | func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { 134 | hostPort = u.Host 135 | hostNoPort = u.Host 136 | if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { 137 | hostNoPort = hostNoPort[:i] 138 | } else { 139 | if u.Scheme == "wss" { 140 | hostPort += ":443" 141 | } else { 142 | hostPort += ":80" 143 | } 144 | } 145 | return hostPort, hostNoPort 146 | } 147 | 148 | // DefaultDialer is a dialer with all fields set to the default zero values. 149 | var DefaultDialer *Dialer 150 | 151 | // Dial creates a new client connection. Use requestHeader to specify the 152 | // origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). 153 | // Use the response.Header to get the selected subprotocol 154 | // (Sec-WebSocket-Protocol) and cookies (Set-Cookie). 155 | // 156 | // If the WebSocket handshake fails, ErrBadHandshake is returned along with a 157 | // non-nil *http.Response so that callers can handle redirects, authentication, 158 | // etc. 159 | func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { 160 | u, err := parseURL(urlStr) 161 | if err != nil { 162 | return nil, nil, err 163 | } 164 | 165 | hostPort, hostNoPort := hostPortNoPort(u) 166 | 167 | if d == nil { 168 | d = &Dialer{} 169 | } 170 | 171 | var deadline time.Time 172 | if d.HandshakeTimeout != 0 { 173 | deadline = time.Now().Add(d.HandshakeTimeout) 174 | } 175 | 176 | netDial := d.NetDial 177 | if netDial == nil { 178 | netDialer := &net.Dialer{Deadline: deadline} 179 | netDial = netDialer.Dial 180 | } 181 | 182 | netConn, err := netDial("tcp", hostPort) 183 | if err != nil { 184 | return nil, nil, err 185 | } 186 | 187 | defer func() { 188 | if netConn != nil { 189 | netConn.Close() 190 | } 191 | }() 192 | 193 | if err := netConn.SetDeadline(deadline); err != nil { 194 | return nil, nil, err 195 | } 196 | 197 | if u.Scheme == "wss" { 198 | cfg := d.TLSClientConfig 199 | if cfg == nil { 200 | cfg = &tls.Config{ServerName: hostNoPort} 201 | } else if cfg.ServerName == "" { 202 | shallowCopy := *cfg 203 | cfg = &shallowCopy 204 | cfg.ServerName = hostNoPort 205 | } 206 | tlsConn := tls.Client(netConn, cfg) 207 | netConn = tlsConn 208 | if err := tlsConn.Handshake(); err != nil { 209 | return nil, nil, err 210 | } 211 | if !cfg.InsecureSkipVerify { 212 | if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { 213 | return nil, nil, err 214 | } 215 | } 216 | } 217 | 218 | if len(d.Subprotocols) > 0 { 219 | h := http.Header{} 220 | for k, v := range requestHeader { 221 | h[k] = v 222 | } 223 | h.Set("Sec-Websocket-Protocol", strings.Join(d.Subprotocols, ", ")) 224 | requestHeader = h 225 | } 226 | 227 | conn, resp, err := NewClient(netConn, u, requestHeader, d.ReadBufferSize, d.WriteBufferSize) 228 | if err != nil { 229 | return nil, resp, err 230 | } 231 | 232 | netConn.SetDeadline(time.Time{}) 233 | netConn = nil // to avoid close in defer. 234 | return conn, resp, nil 235 | } 236 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package websocket implements the WebSocket protocol defined in RFC 6455. 6 | // 7 | // Overview 8 | // 9 | // The Conn type represents a WebSocket connection. A server application uses 10 | // the Upgrade function from an Upgrader object with a HTTP request handler 11 | // to get a pointer to a Conn: 12 | // 13 | // var upgrader = websocket.Upgrader{ 14 | // ReadBufferSize: 1024, 15 | // WriteBufferSize: 1024, 16 | // } 17 | // 18 | // func handler(w http.ResponseWriter, r *http.Request) { 19 | // conn, err := upgrader.Upgrade(w, r, nil) 20 | // if err != nil { 21 | // log.Println(err) 22 | // return 23 | // } 24 | // ... Use conn to send and receive messages. 25 | // } 26 | // 27 | // Call the connection WriteMessage and ReadMessages methods to send and 28 | // receive messages as a slice of bytes. This snippet of code shows how to echo 29 | // messages using these methods: 30 | // 31 | // for { 32 | // messageType, p, err := conn.ReadMessage() 33 | // if err != nil { 34 | // return 35 | // } 36 | // if err = conn.WriteMessage(messageType, p); err != nil { 37 | // return err 38 | // } 39 | // } 40 | // 41 | // In above snippet of code, p is a []byte and messageType is an int with value 42 | // websocket.BinaryMessage or websocket.TextMessage. 43 | // 44 | // An application can also send and receive messages using the io.WriteCloser 45 | // and io.Reader interfaces. To send a message, call the connection NextWriter 46 | // method to get an io.WriteCloser, write the message to the writer and close 47 | // the writer when done. To receive a message, call the connection NextReader 48 | // method to get an io.Reader and read until io.EOF is returned. This snippet 49 | // snippet shows how to echo messages using the NextWriter and NextReader 50 | // methods: 51 | // 52 | // for { 53 | // messageType, r, err := conn.NextReader() 54 | // if err != nil { 55 | // return 56 | // } 57 | // w, err := conn.NextWriter(messageType) 58 | // if err != nil { 59 | // return err 60 | // } 61 | // if _, err := io.Copy(w, r); err != nil { 62 | // return err 63 | // } 64 | // if err := w.Close(); err != nil { 65 | // return err 66 | // } 67 | // } 68 | // 69 | // Data Messages 70 | // 71 | // The WebSocket protocol distinguishes between text and binary data messages. 72 | // Text messages are interpreted as UTF-8 encoded text. The interpretation of 73 | // binary messages is left to the application. 74 | // 75 | // This package uses the TextMessage and BinaryMessage integer constants to 76 | // identify the two data message types. The ReadMessage and NextReader methods 77 | // return the type of the received message. The messageType argument to the 78 | // WriteMessage and NextWriter methods specifies the type of a sent message. 79 | // 80 | // It is the application's responsibility to ensure that text messages are 81 | // valid UTF-8 encoded text. 82 | // 83 | // Control Messages 84 | // 85 | // The WebSocket protocol defines three types of control messages: close, ping 86 | // and pong. Call the connection WriteControl, WriteMessage or NextWriter 87 | // methods to send a control message to the peer. 88 | // 89 | // Connections handle received ping and pong messages by invoking a callback 90 | // function set with SetPingHandler and SetPongHandler methods. These callback 91 | // functions can be invoked from the ReadMessage method, the NextReader method 92 | // or from a call to the data message reader returned from NextReader. 93 | // 94 | // Connections handle received close messages by returning an error from the 95 | // ReadMessage method, the NextReader method or from a call to the data message 96 | // reader returned from NextReader. 97 | // 98 | // Concurrency 99 | // 100 | // Connections do not support concurrent calls to the write methods 101 | // (NextWriter, SetWriteDeadline, WriteMessage) or concurrent calls to the read 102 | // methods methods (NextReader, SetReadDeadline, ReadMessage). Connections do 103 | // support a concurrent reader and writer. 104 | // 105 | // The Close and WriteControl methods can be called concurrently with all other 106 | // methods. 107 | // 108 | // Read is Required 109 | // 110 | // The application must read the connection to process ping and close messages 111 | // sent from the peer. If the application is not otherwise interested in 112 | // messages from the peer, then the application should start a goroutine to read 113 | // and discard messages from the peer. A simple example is: 114 | // 115 | // func readLoop(c *websocket.Conn) { 116 | // for { 117 | // if _, _, err := c.NextReader(); err != nil { 118 | // c.Close() 119 | // break 120 | // } 121 | // } 122 | // } 123 | // 124 | // Origin Considerations 125 | // 126 | // Web browsers allow Javascript applications to open a WebSocket connection to 127 | // any host. It's up to the server to enforce an origin policy using the Origin 128 | // request header sent by the browser. 129 | // 130 | // The Upgrader calls the function specified in the CheckOrigin field to check 131 | // the origin. If the CheckOrigin function returns false, then the Upgrade 132 | // method fails the WebSocket handshake with HTTP status 403. 133 | // 134 | // If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail 135 | // the handshake if the Origin request header is present and not equal to the 136 | // Host request header. 137 | // 138 | // An application can allow connections from any origin by specifying a 139 | // function that always returns true: 140 | // 141 | // var upgrader = websocket.Upgrader{ 142 | // CheckOrigin: func(r *http.Request) bool { return true }, 143 | // } 144 | // 145 | // The deprecated Upgrade function does not enforce an origin policy. It's the 146 | // application's responsibility to check the Origin header before calling 147 | // Upgrade. 148 | package websocket 149 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "encoding/json" 9 | ) 10 | 11 | // WriteJSON is deprecated, use c.WriteJSON instead. 12 | func WriteJSON(c *Conn, v interface{}) error { 13 | return c.WriteJSON(v) 14 | } 15 | 16 | // WriteJSON writes the JSON encoding of v to the connection. 17 | // 18 | // See the documentation for encoding/json Marshal for details about the 19 | // conversion of Go values to JSON. 20 | func (c *Conn) WriteJSON(v interface{}) error { 21 | w, err := c.NextWriter(TextMessage) 22 | if err != nil { 23 | return err 24 | } 25 | err1 := json.NewEncoder(w).Encode(v) 26 | err2 := w.Close() 27 | if err1 != nil { 28 | return err1 29 | } 30 | return err2 31 | } 32 | 33 | // ReadJSON is deprecated, use c.ReadJSON instead. 34 | func ReadJSON(c *Conn, v interface{}) error { 35 | return c.ReadJSON(v) 36 | } 37 | 38 | // ReadJSON reads the next JSON-encoded message from the connection and stores 39 | // it in the value pointed to by v. 40 | // 41 | // See the documentation for the encoding/json Unmarshal function for details 42 | // about the conversion of JSON to a Go value. 43 | func (c *Conn) ReadJSON(v interface{}) error { 44 | _, r, err := c.NextReader() 45 | if err != nil { 46 | return err 47 | } 48 | return json.NewDecoder(r).Decode(v) 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "crypto/rand" 9 | "crypto/sha1" 10 | "encoding/base64" 11 | "io" 12 | "net/http" 13 | "strings" 14 | ) 15 | 16 | // tokenListContainsValue returns true if the 1#token header with the given 17 | // name contains token. 18 | func tokenListContainsValue(header http.Header, name string, value string) bool { 19 | for _, v := range header[name] { 20 | for _, s := range strings.Split(v, ",") { 21 | if strings.EqualFold(value, strings.TrimSpace(s)) { 22 | return true 23 | } 24 | } 25 | } 26 | return false 27 | } 28 | 29 | var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") 30 | 31 | func computeAcceptKey(challengeKey string) string { 32 | h := sha1.New() 33 | h.Write([]byte(challengeKey)) 34 | h.Write(keyGUID) 35 | return base64.StdEncoding.EncodeToString(h.Sum(nil)) 36 | } 37 | 38 | func generateChallengeKey() (string, error) { 39 | p := make([]byte, 16) 40 | if _, err := io.ReadFull(rand.Reader, p); err != nil { 41 | return "", err 42 | } 43 | return base64.StdEncoding.EncodeToString(p), nil 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Lorenzo Alberton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/README.md: -------------------------------------------------------------------------------- 1 | # StatsD client (Golang) 2 | 3 | [![GoDoc](https://godoc.org/github.com/quipo/statsd?status.png)](http://godoc.org/github.com/quipo/statsd) 4 | 5 | ## Introduction 6 | 7 | Go Client library for [StatsD](https://github.com/etsy/statsd/). Contains a direct and a buffered client. 8 | The buffered version will hold and aggregate values for the same key in memory before flushing them at the defined frequency. 9 | 10 | This client library was inspired by the one embedded in the [Bit.ly NSQ](https://github.com/bitly/nsq/blob/master/util/statsd_client.go) project, and extended to support some extra custom events used at DataSift. 11 | 12 | ## Installation 13 | 14 | go get github.com/quipo/statsd 15 | 16 | ## Supported event types 17 | 18 | * Increment - Count occurrences per second/minute of a specific event 19 | * Decrement - Count occurrences per second/minute of a specific event 20 | * Timing - To track a duration event 21 | * Gauge - Gauges are a constant data type. They are not subject to averaging, and they don’t change unless you change them. That is, once you set a gauge value, it will be a flat line on the graph until you change it again 22 | * Absolute - Absolute-valued metric (not averaged/aggregated) 23 | * Total - Continously increasing value, e.g. read operations since boot 24 | 25 | 26 | ## Sample usage 27 | 28 | ```go 29 | package main 30 | 31 | import ( 32 | "log" 33 | "os" 34 | "time" 35 | 36 | "github.com/quipo/statsd" 37 | ) 38 | 39 | func main() { 40 | // init 41 | prefix := "myproject." 42 | statsdclient := statsd.NewStatsdClient("localhost:8125", prefix) 43 | err := statsdclient.CreateSocket() 44 | if nil != err { 45 | log.Println(err) 46 | os.Exit(1) 47 | } 48 | interval := time.Second * 2 // aggregate stats and flush every 2 seconds 49 | stats := statsd.NewStatsdBuffer(interval, statsdclient) 50 | defer stats.Close() 51 | 52 | // not buffered: send immediately 53 | statsdclient.Incr("mymetric", 4) 54 | 55 | // buffered: aggregate in memory before flushing 56 | stats.Incr("mymetric", 1) 57 | stats.Incr("mymetric", 3) 58 | stats.Incr("mymetric", 1) 59 | stats.Incr("mymetric", 1) 60 | } 61 | ``` 62 | 63 | The string "%HOST%" in the metric name will automatically be replaced with the hostname of the server the event is sent from. 64 | 65 | 66 | ## Author 67 | 68 | Lorenzo Alberton 69 | 70 | * Web: [http://alberton.info](http://alberton.info) 71 | * Twitter: [@lorenzoalberton](https://twitter.com/lorenzoalberton) 72 | * Linkedin: [/in/lorenzoalberton](https://www.linkedin.com/in/lorenzoalberton) 73 | 74 | 75 | ## Copyright 76 | 77 | See [LICENSE](LICENSE) document 78 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/bufferedclient.go: -------------------------------------------------------------------------------- 1 | package statsd 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "time" 7 | 8 | "github.com/quipo/statsd/event" 9 | ) 10 | 11 | // request to close the buffered statsd collector 12 | type closeRequest struct { 13 | reply chan error 14 | } 15 | 16 | // StatsdBuffer is a client library to aggregate events in memory before 17 | // flushing aggregates to StatsD, useful if the frequency of events is extremely high 18 | // and sampling is not desirable 19 | type StatsdBuffer struct { 20 | statsd *StatsdClient 21 | flushInterval time.Duration 22 | eventChannel chan event.Event 23 | events map[string]event.Event 24 | closeChannel chan closeRequest 25 | Logger Logger 26 | Verbose bool 27 | } 28 | 29 | // NewStatsdBuffer Factory 30 | func NewStatsdBuffer(interval time.Duration, client *StatsdClient) *StatsdBuffer { 31 | sb := &StatsdBuffer{ 32 | flushInterval: interval, 33 | statsd: client, 34 | eventChannel: make(chan event.Event, 100), 35 | events: make(map[string]event.Event, 0), 36 | closeChannel: make(chan closeRequest, 0), 37 | Logger: log.New(os.Stdout, "[BufferedStatsdClient] ", log.Ldate|log.Ltime), 38 | Verbose: true, 39 | } 40 | go sb.collector() 41 | return sb 42 | } 43 | 44 | // CreateSocket creates a UDP connection to a StatsD server 45 | func (sb *StatsdBuffer) CreateSocket() error { 46 | return sb.statsd.CreateSocket() 47 | } 48 | 49 | // CreateTCPSocket creates a TCP connection to a StatsD server 50 | func (sb *StatsdBuffer) CreateTCPSocket() error { 51 | return sb.statsd.CreateTCPSocket() 52 | } 53 | 54 | // Incr - Increment a counter metric. Often used to note a particular event 55 | func (sb *StatsdBuffer) Incr(stat string, count int64) error { 56 | if 0 != count { 57 | sb.eventChannel <- &event.Increment{Name: stat, Value: count} 58 | } 59 | return nil 60 | } 61 | 62 | // Decr - Decrement a counter metric. Often used to note a particular event 63 | func (sb *StatsdBuffer) Decr(stat string, count int64) error { 64 | if 0 != count { 65 | sb.eventChannel <- &event.Increment{Name: stat, Value: -count} 66 | } 67 | return nil 68 | } 69 | 70 | // Timing - Track a duration event 71 | func (sb *StatsdBuffer) Timing(stat string, delta int64) error { 72 | sb.eventChannel <- event.NewTiming(stat, delta) 73 | return nil 74 | } 75 | 76 | // PrecisionTiming - Track a duration event 77 | // the time delta has to be a duration 78 | func (sb *StatsdBuffer) PrecisionTiming(stat string, delta time.Duration) error { 79 | sb.eventChannel <- event.NewPrecisionTiming(stat, delta) 80 | return nil 81 | } 82 | 83 | // Gauge - Gauges are a constant data type. They are not subject to averaging, 84 | // and they don’t change unless you change them. That is, once you set a gauge value, 85 | // it will be a flat line on the graph until you change it again 86 | func (sb *StatsdBuffer) Gauge(stat string, value int64) error { 87 | sb.eventChannel <- &event.Gauge{Name: stat, Value: value} 88 | return nil 89 | } 90 | 91 | // GaugeDelta records a delta from the previous value (as int64) 92 | func (sb *StatsdBuffer) GaugeDelta(stat string, value int64) error { 93 | sb.eventChannel <- &event.GaugeDelta{Name: stat, Value: value} 94 | return nil 95 | } 96 | 97 | // FGauge is a Gauge working with float64 values 98 | func (sb *StatsdBuffer) FGauge(stat string, value float64) error { 99 | sb.eventChannel <- &event.FGauge{Name: stat, Value: value} 100 | return nil 101 | } 102 | 103 | // FGaugeDelta records a delta from the previous value (as float64) 104 | func (sb *StatsdBuffer) FGaugeDelta(stat string, value float64) error { 105 | sb.eventChannel <- &event.FGaugeDelta{Name: stat, Value: value} 106 | return nil 107 | } 108 | 109 | // Absolute - Send absolute-valued metric (not averaged/aggregated) 110 | func (sb *StatsdBuffer) Absolute(stat string, value int64) error { 111 | sb.eventChannel <- &event.Absolute{Name: stat, Values: []int64{value}} 112 | return nil 113 | } 114 | 115 | // FAbsolute - Send absolute-valued metric (not averaged/aggregated) 116 | func (sb *StatsdBuffer) FAbsolute(stat string, value float64) error { 117 | sb.eventChannel <- &event.FAbsolute{Name: stat, Values: []float64{value}} 118 | return nil 119 | } 120 | 121 | // Total - Send a metric that is continously increasing, e.g. read operations since boot 122 | func (sb *StatsdBuffer) Total(stat string, value int64) error { 123 | sb.eventChannel <- &event.Total{Name: stat, Value: value} 124 | return nil 125 | } 126 | 127 | // avoid too many allocations by memoizing the "type|key" pair for an event 128 | // @see https://gobyexample.com/closures 129 | func initMemoisedKeyMap() func(typ string, key string) string { 130 | m := make(map[string]map[string]string) 131 | return func(typ string, key string) string { 132 | if _, ok := m[typ]; !ok { 133 | m[typ] = make(map[string]string) 134 | } 135 | if k, ok := m[typ][key]; !ok { 136 | m[typ][key] = typ + "|" + key 137 | return m[typ][key] 138 | } else { 139 | return k // memoized value 140 | } 141 | } 142 | } 143 | 144 | // handle flushes and updates in one single thread (instead of locking the events map) 145 | func (sb *StatsdBuffer) collector() { 146 | // on a panic event, flush all the pending stats before panicking 147 | defer func(sb *StatsdBuffer) { 148 | if r := recover(); r != nil { 149 | sb.Logger.Println("Caught panic, flushing stats before throwing the panic again") 150 | sb.flush() 151 | panic(r) 152 | } 153 | }(sb) 154 | 155 | keyFor := initMemoisedKeyMap() // avoid allocations (https://gobyexample.com/closures) 156 | 157 | ticker := time.NewTicker(sb.flushInterval) 158 | 159 | for { 160 | select { 161 | case <-ticker.C: 162 | //sb.Logger.Println("Flushing stats") 163 | sb.flush() 164 | case e := <-sb.eventChannel: 165 | //sb.Logger.Println("Received ", e.String()) 166 | // issue #28: unable to use Incr and PrecisionTiming with the same key (also fixed #27) 167 | k := keyFor(e.TypeString(), e.Key()) // avoid allocations 168 | if e2, ok := sb.events[k]; ok { 169 | //sb.Logger.Println("Updating existing event") 170 | e2.Update(e) 171 | sb.events[k] = e2 172 | } else { 173 | //sb.Logger.Println("Adding new event") 174 | sb.events[k] = e 175 | } 176 | case c := <-sb.closeChannel: 177 | if sb.Verbose { 178 | sb.Logger.Println("Asked to terminate. Flushing stats before returning.") 179 | } 180 | c.reply <- sb.flush() 181 | return 182 | } 183 | } 184 | } 185 | 186 | // Close sends a close event to the collector asking to stop & flush pending stats 187 | // and closes the statsd client 188 | func (sb *StatsdBuffer) Close() (err error) { 189 | // 1. send a close event to the collector 190 | req := closeRequest{reply: make(chan error, 0)} 191 | sb.closeChannel <- req 192 | // 2. wait for the collector to drain the queue and respond 193 | err = <-req.reply 194 | // 3. close the statsd client 195 | err2 := sb.statsd.Close() 196 | if err != nil { 197 | return err 198 | } 199 | return err2 200 | } 201 | 202 | // send the events to StatsD and reset them. 203 | // This function is NOT thread-safe, so it must only be invoked synchronously 204 | // from within the collector() goroutine 205 | func (sb *StatsdBuffer) flush() (err error) { 206 | n := len(sb.events) 207 | if n == 0 { 208 | return nil 209 | } 210 | if err := sb.statsd.SendEvents(sb.events); err != nil { 211 | sb.Logger.Println(err) 212 | return err 213 | } 214 | sb.events = make(map[string]event.Event) 215 | 216 | return nil 217 | } 218 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/absolute.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // Absolute is a metric that is not averaged/aggregated. 6 | // We keep each value distinct and then we flush them all individually. 7 | type Absolute struct { 8 | Name string 9 | Values []int64 10 | } 11 | 12 | // Update the event with metrics coming from a new one of the same type and with the same key 13 | func (e *Absolute) Update(e2 Event) error { 14 | if e.Type() != e2.Type() { 15 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 16 | } 17 | e.Values = append(e.Values, e2.Payload().([]int64)...) 18 | return nil 19 | } 20 | 21 | // Payload returns the aggregated value for this event 22 | func (e Absolute) Payload() interface{} { 23 | return e.Values 24 | } 25 | 26 | // Stats returns an array of StatsD events as they travel over UDP 27 | func (e Absolute) Stats() []string { 28 | ret := make([]string, 0, len(e.Values)) 29 | for _, v := range e.Values { 30 | ret = append(ret, fmt.Sprintf("%s:%d|a", e.Name, v)) 31 | } 32 | return ret 33 | } 34 | 35 | // Key returns the name of this metric 36 | func (e Absolute) Key() string { 37 | return e.Name 38 | } 39 | 40 | // SetKey sets the name of this metric 41 | func (e *Absolute) SetKey(key string) { 42 | e.Name = key 43 | } 44 | 45 | // Type returns an integer identifier for this type of metric 46 | func (e Absolute) Type() int { 47 | return EventAbsolute 48 | } 49 | 50 | // TypeString returns a name for this type of metric 51 | func (e Absolute) TypeString() string { 52 | return "Absolute" 53 | } 54 | 55 | // String returns a debug-friendly representation of this metric 56 | func (e Absolute) String() string { 57 | return fmt.Sprintf("{Type: %s, Key: %s, Values: %v}", e.TypeString(), e.Name, e.Values) 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/fabsolute.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // FAbsolute is a metric that is not averaged/aggregated. 6 | // We keep each value distinct and then we flush them all individually. 7 | type FAbsolute struct { 8 | Name string 9 | Values []float64 10 | } 11 | 12 | // Update the event with metrics coming from a new one of the same type and with the same key 13 | func (e *FAbsolute) Update(e2 Event) error { 14 | if e.Type() != e2.Type() { 15 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 16 | } 17 | e.Values = append(e.Values, e2.Payload().([]float64)...) 18 | return nil 19 | } 20 | 21 | // Payload returns the aggregated value for this event 22 | func (e FAbsolute) Payload() interface{} { 23 | return e.Values 24 | } 25 | 26 | // Stats returns an array of StatsD events as they travel over UDP 27 | func (e FAbsolute) Stats() []string { 28 | ret := make([]string, 0, len(e.Values)) 29 | for _, v := range e.Values { 30 | ret = append(ret, fmt.Sprintf("%s:%g|a", e.Name, v)) 31 | } 32 | return ret 33 | } 34 | 35 | // Key returns the name of this metric 36 | func (e FAbsolute) Key() string { 37 | return e.Name 38 | } 39 | 40 | // SetKey sets the name of this metric 41 | func (e *FAbsolute) SetKey(key string) { 42 | e.Name = key 43 | } 44 | 45 | // Type returns an integer identifier for this type of metric 46 | func (e FAbsolute) Type() int { 47 | return EventFAbsolute 48 | } 49 | 50 | // TypeString returns a name for this type of metric 51 | func (e FAbsolute) TypeString() string { 52 | return "FAbsolute" 53 | } 54 | 55 | // String returns a debug-friendly representation of this metric 56 | func (e FAbsolute) String() string { 57 | return fmt.Sprintf("{Type: %s, Key: %s, Values: %v}", e.TypeString(), e.Name, e.Values) 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/fgauge.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // FGauge - Gauges are a constant data type. They are not subject to averaging, 6 | // and they don’t change unless you change them. That is, once you set a gauge value, 7 | // it will be a flat line on the graph until you change it again 8 | type FGauge struct { 9 | Name string 10 | Value float64 11 | } 12 | 13 | // Update the event with metrics coming from a new one of the same type and with the same key 14 | func (e *FGauge) Update(e2 Event) error { 15 | if e.Type() != e2.Type() { 16 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 17 | } 18 | e.Value += e2.Payload().(float64) 19 | return nil 20 | } 21 | 22 | // Payload returns the aggregated value for this event 23 | func (e FGauge) Payload() interface{} { 24 | return e.Value 25 | } 26 | 27 | // Stats returns an array of StatsD events as they travel over UDP 28 | func (e FGauge) Stats() []string { 29 | if e.Value < 0 { 30 | // because a leading '+' or '-' in the value of a gauge denotes a delta, to send 31 | // a negative gauge value we first set the gauge absolutely to 0, then send the 32 | // negative value as a delta from 0 (that's just how the spec works :-) 33 | return []string{ 34 | fmt.Sprintf("%s:%d|g", e.Name, 0), 35 | fmt.Sprintf("%s:%g|g", e.Name, e.Value), 36 | } 37 | } 38 | return []string{fmt.Sprintf("%s:%g|g", e.Name, e.Value)} 39 | } 40 | 41 | // Key returns the name of this metric 42 | func (e FGauge) Key() string { 43 | return e.Name 44 | } 45 | 46 | // SetKey sets the name of this metric 47 | func (e *FGauge) SetKey(key string) { 48 | e.Name = key 49 | } 50 | 51 | // Type returns an integer identifier for this type of metric 52 | func (e FGauge) Type() int { 53 | return EventFGauge 54 | } 55 | 56 | // TypeString returns a name for this type of metric 57 | func (e FGauge) TypeString() string { 58 | return "FGauge" 59 | } 60 | 61 | // String returns a debug-friendly representation of this metric 62 | func (e FGauge) String() string { 63 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %g}", e.TypeString(), e.Name, e.Value) 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/fgaugedelta.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // FGaugeDelta - Gauges are a constant data type. They are not subject to averaging, 6 | // and they don’t change unless you change them. That is, once you set a gauge value, 7 | // it will be a flat line on the graph until you change it again 8 | type FGaugeDelta struct { 9 | Name string 10 | Value float64 11 | } 12 | 13 | // Update the event with metrics coming from a new one of the same type and with the same key 14 | func (e *FGaugeDelta) Update(e2 Event) error { 15 | if e.Type() != e2.Type() { 16 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 17 | } 18 | e.Value += e2.Payload().(float64) 19 | return nil 20 | } 21 | 22 | // Payload returns the aggregated value for this event 23 | func (e FGaugeDelta) Payload() interface{} { 24 | return e.Value 25 | } 26 | 27 | // Stats returns an array of StatsD events as they travel over UDP 28 | func (e FGaugeDelta) Stats() []string { 29 | if e.Value < 0 { 30 | // because a leading '+' or '-' in the value of a gauge denotes a delta, to send 31 | // a negative gauge value we first set the gauge absolutely to 0, then send the 32 | // negative value as a delta from 0 (that's just how the spec works :-) 33 | return []string{ 34 | fmt.Sprintf("%s:%d|g", e.Name, 0), 35 | fmt.Sprintf("%s:%g|g", e.Name, e.Value), 36 | } 37 | } 38 | return []string{fmt.Sprintf("%s:%g|g", e.Name, e.Value)} 39 | } 40 | 41 | // Key returns the name of this metric 42 | func (e FGaugeDelta) Key() string { 43 | return e.Name 44 | } 45 | 46 | // SetKey sets the name of this metric 47 | func (e *FGaugeDelta) SetKey(key string) { 48 | e.Name = key 49 | } 50 | 51 | // Type returns an integer identifier for this type of metric 52 | func (e FGaugeDelta) Type() int { 53 | return EventFGaugeDelta 54 | } 55 | 56 | // TypeString returns a name for this type of metric 57 | func (e FGaugeDelta) TypeString() string { 58 | return "FGaugeDelta" 59 | } 60 | 61 | // String returns a debug-friendly representation of this metric 62 | func (e FGaugeDelta) String() string { 63 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %g}", e.TypeString(), e.Name, e.Value) 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/gauge.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // Gauge - Gauges are a constant data type. They are not subject to averaging, 6 | // and they don’t change unless you change them. That is, once you set a gauge value, 7 | // it will be a flat line on the graph until you change it again 8 | type Gauge struct { 9 | Name string 10 | Value int64 11 | } 12 | 13 | // Update the event with metrics coming from a new one of the same type and with the same key 14 | func (e *Gauge) Update(e2 Event) error { 15 | if e.Type() != e2.Type() { 16 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 17 | } 18 | e.Value = e2.Payload().(int64) 19 | return nil 20 | } 21 | 22 | // Payload returns the aggregated value for this event 23 | func (e Gauge) Payload() interface{} { 24 | return e.Value 25 | } 26 | 27 | // Stats returns an array of StatsD events as they travel over UDP 28 | func (e Gauge) Stats() []string { 29 | if e.Value < 0 { 30 | // because a leading '+' or '-' in the value of a gauge denotes a delta, to send 31 | // a negative gauge value we first set the gauge absolutely to 0, then send the 32 | // negative value as a delta from 0 (that's just how the spec works :-) 33 | return []string{ 34 | fmt.Sprintf("%s:%d|g", e.Name, 0), 35 | fmt.Sprintf("%s:%d|g", e.Name, e.Value), 36 | } 37 | } 38 | return []string{fmt.Sprintf("%s:%d|g", e.Name, e.Value)} 39 | } 40 | 41 | // Key returns the name of this metric 42 | func (e Gauge) Key() string { 43 | return e.Name 44 | } 45 | 46 | // SetKey sets the name of this metric 47 | func (e *Gauge) SetKey(key string) { 48 | e.Name = key 49 | } 50 | 51 | // Type returns an integer identifier for this type of metric 52 | func (e Gauge) Type() int { 53 | return EventGauge 54 | } 55 | 56 | // TypeString returns a name for this type of metric 57 | func (e Gauge) TypeString() string { 58 | return "Gauge" 59 | } 60 | 61 | // String returns a debug-friendly representation of this metric 62 | func (e Gauge) String() string { 63 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %d}", e.TypeString(), e.Name, e.Value) 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/gaugedelta.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // GaugeDelta - Gauges are a constant data type. They are not subject to averaging, 6 | // and they don’t change unless you change them. That is, once you set a gauge value, 7 | // it will be a flat line on the graph until you change it again 8 | type GaugeDelta struct { 9 | Name string 10 | Value int64 11 | } 12 | 13 | // Update the event with metrics coming from a new one of the same type and with the same key 14 | func (e *GaugeDelta) Update(e2 Event) error { 15 | if e.Type() != e2.Type() { 16 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 17 | } 18 | e.Value += e2.Payload().(int64) 19 | return nil 20 | } 21 | 22 | // Payload returns the aggregated value for this event 23 | func (e GaugeDelta) Payload() interface{} { 24 | return e.Value 25 | } 26 | 27 | // Stats returns an array of StatsD events as they travel over UDP 28 | func (e GaugeDelta) Stats() []string { 29 | if e.Value < 0 { 30 | // because a leading '+' or '-' in the value of a gauge denotes a delta, to send 31 | // a negative gauge value we first set the gauge absolutely to 0, then send the 32 | // negative value as a delta from 0 (that's just how the spec works :-) 33 | return []string{ 34 | fmt.Sprintf("%s:%d|g", e.Name, 0), 35 | fmt.Sprintf("%s:%d|g", e.Name, e.Value), 36 | } 37 | } 38 | return []string{fmt.Sprintf("%s:+%d|g", e.Name, e.Value)} 39 | } 40 | 41 | // Key returns the name of this metric 42 | func (e GaugeDelta) Key() string { 43 | return e.Name 44 | } 45 | 46 | // SetKey sets the name of this metric 47 | func (e *GaugeDelta) SetKey(key string) { 48 | e.Name = key 49 | } 50 | 51 | // Type returns an integer identifier for this type of metric 52 | func (e GaugeDelta) Type() int { 53 | return EventGaugeDelta 54 | } 55 | 56 | // TypeString returns a name for this type of metric 57 | func (e GaugeDelta) TypeString() string { 58 | return "GaugeDelta" 59 | } 60 | 61 | // String returns a debug-friendly representation of this metric 62 | func (e GaugeDelta) String() string { 63 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %d}", e.TypeString(), e.Name, e.Value) 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/increment.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // Increment represents a metric whose value is averaged over a minute 6 | type Increment struct { 7 | Name string 8 | Value int64 9 | } 10 | 11 | // Update the event with metrics coming from a new one of the same type and with the same key 12 | func (e *Increment) Update(e2 Event) error { 13 | if e.Type() != e2.Type() { 14 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 15 | } 16 | e.Value += e2.Payload().(int64) 17 | return nil 18 | } 19 | 20 | // Payload returns the aggregated value for this event 21 | func (e Increment) Payload() interface{} { 22 | return e.Value 23 | } 24 | 25 | // Stats returns an array of StatsD events as they travel over UDP 26 | func (e Increment) Stats() []string { 27 | return []string{fmt.Sprintf("%s:%d|c", e.Name, e.Value)} 28 | } 29 | 30 | // Key returns the name of this metric 31 | func (e Increment) Key() string { 32 | return e.Name 33 | } 34 | 35 | // SetKey sets the name of this metric 36 | func (e *Increment) SetKey(key string) { 37 | e.Name = key 38 | } 39 | 40 | // Type returns an integer identifier for this type of metric 41 | func (e Increment) Type() int { 42 | return EventIncr 43 | } 44 | 45 | // TypeString returns a name for this type of metric 46 | func (e Increment) TypeString() string { 47 | return "Increment" 48 | } 49 | 50 | // String returns a debug-friendly representation of this metric 51 | func (e Increment) String() string { 52 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %d}", e.TypeString(), e.Name, e.Value) 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/interface.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | // constant event type identifiers 4 | const ( 5 | EventIncr = iota 6 | EventTiming 7 | EventAbsolute 8 | EventTotal 9 | EventGauge 10 | EventGaugeDelta 11 | EventFGauge 12 | EventFGaugeDelta 13 | EventFAbsolute 14 | EventPrecisionTiming 15 | ) 16 | 17 | // Event is an interface to a generic StatsD event, used by the buffered client collator 18 | type Event interface { 19 | Stats() []string 20 | Type() int 21 | TypeString() string 22 | Payload() interface{} 23 | Update(e2 Event) error 24 | String() string 25 | Key() string 26 | SetKey(string) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/precisiontiming.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // PrecisionTiming keeps min/max/avg information about a timer over a certain interval 9 | type PrecisionTiming struct { 10 | Name string 11 | Min time.Duration 12 | Max time.Duration 13 | Value time.Duration 14 | Count int64 15 | } 16 | 17 | // NewPrecisionTiming is a factory for a Timing event, setting the Count to 1 to prevent div_by_0 errors 18 | func NewPrecisionTiming(k string, delta time.Duration) *PrecisionTiming { 19 | return &PrecisionTiming{Name: k, Min: delta, Max: delta, Value: delta, Count: 1} 20 | } 21 | 22 | // Update the event with metrics coming from a new one of the same type and with the same key 23 | func (e *PrecisionTiming) Update(e2 Event) error { 24 | if e.Type() != e2.Type() { 25 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 26 | } 27 | p := e2.Payload().(PrecisionTiming) 28 | e.Count += p.Count 29 | e.Value += p.Value 30 | e.Min = time.Duration(minInt64(int64(e.Min), int64(p.Min))) 31 | e.Max = time.Duration(maxInt64(int64(e.Max), int64(p.Min))) 32 | return nil 33 | } 34 | 35 | // Payload returns the aggregated value for this event 36 | func (e PrecisionTiming) Payload() interface{} { 37 | return e 38 | } 39 | 40 | // Stats returns an array of StatsD events as they travel over UDP 41 | func (e PrecisionTiming) Stats() []string { 42 | return []string{ 43 | fmt.Sprintf("%s.count:%d|c", e.Name, e.Count), 44 | fmt.Sprintf("%s.avg:%.6f|ms", e.Name, float64(int64(e.Value)/e.Count)/1000000), // make sure e.Count != 0 45 | fmt.Sprintf("%s.min:%.6f|ms", e.Name, e.durationToMs(e.Min)), 46 | fmt.Sprintf("%s.max:%.6f|ms", e.Name, e.durationToMs(e.Max)), 47 | } 48 | } 49 | 50 | // durationToMs converts time.Duration into the corresponding value in milliseconds 51 | func (e PrecisionTiming) durationToMs(x time.Duration) float64 { 52 | return float64(x) / float64(time.Millisecond) 53 | } 54 | 55 | // Key returns the name of this metric 56 | func (e PrecisionTiming) Key() string { 57 | return e.Name 58 | } 59 | 60 | // SetKey sets the name of this metric 61 | func (e *PrecisionTiming) SetKey(key string) { 62 | e.Name = key 63 | } 64 | 65 | // Type returns an integer identifier for this type of metric 66 | func (e PrecisionTiming) Type() int { 67 | return EventPrecisionTiming 68 | } 69 | 70 | // TypeString returns a name for this type of metric 71 | func (e PrecisionTiming) TypeString() string { 72 | return "PrecisionTiming" 73 | } 74 | 75 | // String returns a debug-friendly representation of this metric 76 | func (e PrecisionTiming) String() string { 77 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %+v}", e.TypeString(), e.Name, e.Payload()) 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/timing.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // Timing keeps min/max/avg information about a timer over a certain interval 6 | type Timing struct { 7 | Name string 8 | Min int64 9 | Max int64 10 | Value int64 11 | Count int64 12 | } 13 | 14 | // NewTiming is a factory for a Timing event, setting the Count to 1 to prevent div_by_0 errors 15 | func NewTiming(k string, delta int64) *Timing { 16 | return &Timing{Name: k, Min: delta, Max: delta, Value: delta, Count: 1} 17 | } 18 | 19 | // Update the event with metrics coming from a new one of the same type and with the same key 20 | func (e *Timing) Update(e2 Event) error { 21 | if e.Type() != e2.Type() { 22 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 23 | } 24 | p := e2.Payload().(map[string]int64) 25 | e.Count += p["cnt"] 26 | e.Value += p["val"] 27 | e.Min = minInt64(e.Min, p["min"]) 28 | e.Max = maxInt64(e.Max, p["max"]) 29 | return nil 30 | } 31 | 32 | // Payload returns the aggregated value for this event 33 | func (e Timing) Payload() interface{} { 34 | return map[string]int64{ 35 | "min": e.Min, 36 | "max": e.Max, 37 | "val": e.Value, 38 | "cnt": e.Count, 39 | } 40 | } 41 | 42 | // Stats returns an array of StatsD events as they travel over UDP 43 | func (e Timing) Stats() []string { 44 | return []string{ 45 | fmt.Sprintf("%s.count:%d|c", e.Name, e.Count), 46 | fmt.Sprintf("%s.avg:%d|ms", e.Name, int64(e.Value/e.Count)), // make sure e.Count != 0 47 | fmt.Sprintf("%s.min:%d|ms", e.Name, e.Min), 48 | fmt.Sprintf("%s.max:%d|ms", e.Name, e.Max), 49 | } 50 | } 51 | 52 | // Key returns the name of this metric 53 | func (e Timing) Key() string { 54 | return e.Name 55 | } 56 | 57 | // SetKey sets the name of this metric 58 | func (e *Timing) SetKey(key string) { 59 | e.Name = key 60 | } 61 | 62 | // Type returns an integer identifier for this type of metric 63 | func (e Timing) Type() int { 64 | return EventTiming 65 | } 66 | 67 | // TypeString returns a name for this type of metric 68 | func (e Timing) TypeString() string { 69 | return "Timing" 70 | } 71 | 72 | // String returns a debug-friendly representation of this metric 73 | func (e Timing) String() string { 74 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %+v}", e.TypeString(), e.Name, e.Payload()) 75 | } 76 | 77 | func minInt64(v1, v2 int64) int64 { 78 | if v1 <= v2 { 79 | return v1 80 | } 81 | return v2 82 | } 83 | func maxInt64(v1, v2 int64) int64 { 84 | if v1 >= v2 { 85 | return v1 86 | } 87 | return v2 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/event/total.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "fmt" 4 | 5 | // Total represents a metric that is continously increasing, e.g. read operations since boot 6 | type Total struct { 7 | Name string 8 | Value int64 9 | } 10 | 11 | // Update the event with metrics coming from a new one of the same type and with the same key 12 | func (e *Total) Update(e2 Event) error { 13 | if e.Type() != e2.Type() { 14 | return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String()) 15 | } 16 | e.Value += e2.Payload().(int64) 17 | return nil 18 | } 19 | 20 | // Payload returns the aggregated value for this event 21 | func (e Total) Payload() interface{} { 22 | return e.Value 23 | } 24 | 25 | // Stats returns an array of StatsD events as they travel over UDP 26 | func (e Total) Stats() []string { 27 | return []string{fmt.Sprintf("%s:%d|t", e.Name, e.Value)} 28 | } 29 | 30 | // Key returns the name of this metric 31 | func (e Total) Key() string { 32 | return e.Name 33 | } 34 | 35 | // SetKey sets the name of this metric 36 | func (e *Total) SetKey(key string) { 37 | e.Name = key 38 | } 39 | 40 | // Type returns an integer identifier for this type of metric 41 | func (e Total) Type() int { 42 | return EventTotal 43 | } 44 | 45 | // TypeString returns a name for this type of metric 46 | func (e Total) TypeString() string { 47 | return "Total" 48 | } 49 | 50 | // String returns a debug-friendly representation of this metric 51 | func (e Total) String() string { 52 | return fmt.Sprintf("{Type: %s, Key: %s, Value: %d}", e.TypeString(), e.Name, e.Value) 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/interface.go: -------------------------------------------------------------------------------- 1 | package statsd 2 | 3 | import "time" 4 | 5 | // Statsd is an interface to a StatsD client (buffered/unbuffered) 6 | type Statsd interface { 7 | CreateSocket() error 8 | CreateTCPSocket() error 9 | Close() error 10 | Incr(stat string, count int64) error 11 | Decr(stat string, count int64) error 12 | Timing(stat string, delta int64) error 13 | PrecisionTiming(stat string, delta time.Duration) error 14 | Gauge(stat string, value int64) error 15 | GaugeDelta(stat string, value int64) error 16 | Absolute(stat string, value int64) error 17 | Total(stat string, value int64) error 18 | 19 | FGauge(stat string, value float64) error 20 | FGaugeDelta(stat string, value float64) error 21 | FAbsolute(stat string, value float64) error 22 | } 23 | -------------------------------------------------------------------------------- /vendor/github.com/quipo/statsd/noopclient.go: -------------------------------------------------------------------------------- 1 | package statsd 2 | 3 | //@author https://github.com/wyndhblb/statsd 4 | 5 | import ( 6 | "time" 7 | ) 8 | 9 | // NoopClient implements a "no-op" statsd in case there is no statsd server 10 | type NoopClient struct{} 11 | 12 | // CreateSocket does nothing 13 | func (s NoopClient) CreateSocket() error { 14 | return nil 15 | } 16 | 17 | // CreateTCPSocket does nothing 18 | func (s NoopClient) CreateTCPSocket() error { 19 | return nil 20 | } 21 | 22 | // Close does nothing 23 | func (s NoopClient) Close() error { 24 | return nil 25 | } 26 | 27 | // Incr does nothing 28 | func (s NoopClient) Incr(stat string, count int64) error { 29 | return nil 30 | } 31 | 32 | // Decr does nothing 33 | func (s NoopClient) Decr(stat string, count int64) error { 34 | return nil 35 | } 36 | 37 | // Timing does nothing 38 | func (s NoopClient) Timing(stat string, count int64) error { 39 | return nil 40 | } 41 | 42 | // PrecisionTiming does nothing 43 | func (s NoopClient) PrecisionTiming(stat string, delta time.Duration) error { 44 | return nil 45 | } 46 | 47 | // Gauge does nothing 48 | func (s NoopClient) Gauge(stat string, value int64) error { 49 | return nil 50 | } 51 | 52 | // GaugeDelta does nothing 53 | func (s NoopClient) GaugeDelta(stat string, value int64) error { 54 | return nil 55 | } 56 | 57 | // Absolute does nothing 58 | func (s NoopClient) Absolute(stat string, value int64) error { 59 | return nil 60 | } 61 | 62 | // Total does nothing 63 | func (s NoopClient) Total(stat string, value int64) error { 64 | return nil 65 | } 66 | 67 | // FGauge does nothing 68 | func (s NoopClient) FGauge(stat string, value float64) error { 69 | return nil 70 | } 71 | 72 | // FGaugeDelta does nothing 73 | func (s NoopClient) FGaugeDelta(stat string, value float64) error { 74 | return nil 75 | } 76 | 77 | // FAbsolute does nothing 78 | func (s NoopClient) FAbsolute(stat string, value float64) error { 79 | return nil 80 | } 81 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | install: go get -t -v ./... 3 | go: 1.2 4 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/args.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import "fmt" 4 | 5 | type argGroup struct { 6 | args []*ArgClause 7 | } 8 | 9 | func newArgGroup() *argGroup { 10 | return &argGroup{} 11 | } 12 | 13 | func (a *argGroup) have() bool { 14 | return len(a.args) > 0 15 | } 16 | 17 | func (a *argGroup) Arg(name, help string) *ArgClause { 18 | arg := newArg(name, help) 19 | a.args = append(a.args, arg) 20 | return arg 21 | } 22 | 23 | func (a *argGroup) init() error { 24 | required := 0 25 | seen := map[string]struct{}{} 26 | previousArgMustBeLast := false 27 | for i, arg := range a.args { 28 | if previousArgMustBeLast { 29 | return fmt.Errorf("Args() can't be followed by another argument '%s'", arg.name) 30 | } 31 | if arg.consumesRemainder() { 32 | previousArgMustBeLast = true 33 | } 34 | if _, ok := seen[arg.name]; ok { 35 | return fmt.Errorf("duplicate argument '%s'", arg.name) 36 | } 37 | seen[arg.name] = struct{}{} 38 | if arg.required && required != i { 39 | return fmt.Errorf("required arguments found after non-required") 40 | } 41 | if arg.required { 42 | required++ 43 | } 44 | if err := arg.init(); err != nil { 45 | return err 46 | } 47 | } 48 | return nil 49 | } 50 | 51 | type ArgClause struct { 52 | parserMixin 53 | name string 54 | help string 55 | defaultValue string 56 | required bool 57 | action Action 58 | preAction Action 59 | } 60 | 61 | func newArg(name, help string) *ArgClause { 62 | a := &ArgClause{ 63 | name: name, 64 | help: help, 65 | } 66 | return a 67 | } 68 | 69 | func (a *ArgClause) consumesRemainder() bool { 70 | if r, ok := a.value.(remainderArg); ok { 71 | return r.IsCumulative() 72 | } 73 | return false 74 | } 75 | 76 | // Required arguments must be input by the user. They can not have a Default() value provided. 77 | func (a *ArgClause) Required() *ArgClause { 78 | a.required = true 79 | return a 80 | } 81 | 82 | // Default value for this argument. It *must* be parseable by the value of the argument. 83 | func (a *ArgClause) Default(value string) *ArgClause { 84 | a.defaultValue = value 85 | return a 86 | } 87 | 88 | func (a *ArgClause) Action(action Action) *ArgClause { 89 | a.action = action 90 | return a 91 | } 92 | 93 | func (a *ArgClause) PreAction(action Action) *ArgClause { 94 | a.preAction = action 95 | return a 96 | } 97 | 98 | func (a *ArgClause) init() error { 99 | if a.required && a.defaultValue != "" { 100 | return fmt.Errorf("required argument '%s' with unusable default value", a.name) 101 | } 102 | if a.value == nil { 103 | return fmt.Errorf("no parser defined for arg '%s'", a.name) 104 | } 105 | return nil 106 | } 107 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/cmd.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type cmdGroup struct { 9 | app *Application 10 | parent *CmdClause 11 | commands map[string]*CmdClause 12 | commandOrder []*CmdClause 13 | } 14 | 15 | func newCmdGroup(app *Application) *cmdGroup { 16 | return &cmdGroup{ 17 | app: app, 18 | commands: make(map[string]*CmdClause), 19 | } 20 | } 21 | 22 | func (c *cmdGroup) flattenedCommands() (out []*CmdClause) { 23 | for _, cmd := range c.commandOrder { 24 | if len(cmd.commands) == 0 { 25 | out = append(out, cmd) 26 | } 27 | out = append(out, cmd.flattenedCommands()...) 28 | } 29 | return 30 | } 31 | 32 | func (c *cmdGroup) addCommand(name, help string) *CmdClause { 33 | cmd := newCommand(c.app, name, help) 34 | c.commands[name] = cmd 35 | c.commandOrder = append(c.commandOrder, cmd) 36 | return cmd 37 | } 38 | 39 | func (c *cmdGroup) init() error { 40 | seen := map[string]bool{} 41 | for _, cmd := range c.commandOrder { 42 | if seen[cmd.name] { 43 | return fmt.Errorf("duplicate command '%s'", cmd.name) 44 | } 45 | seen[cmd.name] = true 46 | if err := cmd.init(); err != nil { 47 | return err 48 | } 49 | } 50 | return nil 51 | } 52 | func (c *cmdGroup) have() bool { 53 | return len(c.commands) > 0 54 | } 55 | 56 | type CmdClauseValidator func(*CmdClause) error 57 | 58 | // A CmdClause is a single top-level command. It encapsulates a set of flags 59 | // and either subcommands or positional arguments. 60 | type CmdClause struct { 61 | *flagGroup 62 | *argGroup 63 | *cmdGroup 64 | app *Application 65 | name string 66 | help string 67 | action Action 68 | preAction Action 69 | validator CmdClauseValidator 70 | } 71 | 72 | func newCommand(app *Application, name, help string) *CmdClause { 73 | c := &CmdClause{ 74 | flagGroup: newFlagGroup(), 75 | argGroup: newArgGroup(), 76 | cmdGroup: newCmdGroup(app), 77 | app: app, 78 | name: name, 79 | help: help, 80 | } 81 | return c 82 | } 83 | 84 | // Validate sets a validation function to run when parsing. 85 | func (c *CmdClause) Validate(validator CmdClauseValidator) *CmdClause { 86 | c.validator = validator 87 | return c 88 | } 89 | 90 | func (c *CmdClause) FullCommand() string { 91 | out := []string{c.name} 92 | for p := c.parent; p != nil; p = p.parent { 93 | out = append([]string{p.name}, out...) 94 | } 95 | return strings.Join(out, " ") 96 | } 97 | 98 | // Command adds a new sub-command. 99 | func (c *CmdClause) Command(name, help string) *CmdClause { 100 | cmd := c.addCommand(name, help) 101 | cmd.parent = c 102 | return cmd 103 | } 104 | 105 | func (c *CmdClause) Action(action Action) *CmdClause { 106 | c.action = action 107 | return c 108 | } 109 | 110 | func (c *CmdClause) PreAction(action Action) *CmdClause { 111 | c.preAction = action 112 | return c 113 | } 114 | 115 | func (c *CmdClause) init() error { 116 | if err := c.flagGroup.init(); err != nil { 117 | return err 118 | } 119 | if c.argGroup.have() && c.cmdGroup.have() { 120 | return fmt.Errorf("can't mix Arg()s with Command()s") 121 | } 122 | if err := c.argGroup.init(); err != nil { 123 | return err 124 | } 125 | if err := c.cmdGroup.init(); err != nil { 126 | return err 127 | } 128 | return nil 129 | } 130 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/doc.go: -------------------------------------------------------------------------------- 1 | // Package kingpin provides command line interfaces like this: 2 | // 3 | // $ chat 4 | // usage: chat [] [] [ ...] 5 | // 6 | // Flags: 7 | // --debug enable debug mode 8 | // --help Show help. 9 | // --server=127.0.0.1 server address 10 | // 11 | // Commands: 12 | // help 13 | // Show help for a command. 14 | // 15 | // post [] 16 | // Post a message to a channel. 17 | // 18 | // register 19 | // Register a new user. 20 | // 21 | // $ chat help post 22 | // usage: chat [] post [] [] 23 | // 24 | // Post a message to a channel. 25 | // 26 | // Flags: 27 | // --image=IMAGE image to post 28 | // 29 | // Args: 30 | // channel to post to 31 | // [] text to post 32 | // $ chat post --image=~/Downloads/owls.jpg pics 33 | // 34 | // From code like this: 35 | // 36 | // package main 37 | // 38 | // import "gopkg.in/alecthomas/kingpin.v1" 39 | // 40 | // var ( 41 | // debug = kingpin.Flag("debug", "enable debug mode").Default("false").Bool() 42 | // serverIP = kingpin.Flag("server", "server address").Default("127.0.0.1").IP() 43 | // 44 | // register = kingpin.Command("register", "Register a new user.") 45 | // registerNick = register.Arg("nick", "nickname for user").Required().String() 46 | // registerName = register.Arg("name", "name of user").Required().String() 47 | // 48 | // post = kingpin.Command("post", "Post a message to a channel.") 49 | // postImage = post.Flag("image", "image to post").ExistingFile() 50 | // postChannel = post.Arg("channel", "channel to post to").Required().String() 51 | // postText = post.Arg("text", "text to post").String() 52 | // ) 53 | // 54 | // func main() { 55 | // switch kingpin.Parse() { 56 | // // Register user 57 | // case "register": 58 | // println(*registerNick) 59 | // 60 | // // Post message 61 | // case "post": 62 | // if *postImage != nil { 63 | // } 64 | // if *postText != "" { 65 | // } 66 | // } 67 | // } 68 | package kingpin 69 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/flags.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | ) 8 | 9 | type flagGroup struct { 10 | short map[string]*FlagClause 11 | long map[string]*FlagClause 12 | flagOrder []*FlagClause 13 | } 14 | 15 | func newFlagGroup() *flagGroup { 16 | return &flagGroup{ 17 | short: make(map[string]*FlagClause), 18 | long: make(map[string]*FlagClause), 19 | } 20 | } 21 | 22 | func (f *flagGroup) merge(o *flagGroup) { 23 | for _, flag := range o.flagOrder { 24 | if flag.shorthand != 0 { 25 | f.short[string(flag.shorthand)] = flag 26 | } 27 | f.long[flag.name] = flag 28 | f.flagOrder = append(f.flagOrder, flag) 29 | } 30 | } 31 | 32 | // Flag defines a new flag with the given long name and help. 33 | func (f *flagGroup) Flag(name, help string) *FlagClause { 34 | flag := newFlag(name, help) 35 | f.long[name] = flag 36 | f.flagOrder = append(f.flagOrder, flag) 37 | return flag 38 | } 39 | 40 | func (f *flagGroup) init() error { 41 | for _, flag := range f.long { 42 | if err := flag.init(); err != nil { 43 | return err 44 | } 45 | if flag.shorthand != 0 { 46 | f.short[string(flag.shorthand)] = flag 47 | } 48 | } 49 | return nil 50 | } 51 | 52 | func (f *flagGroup) parse(context *ParseContext) error { 53 | var token *Token 54 | 55 | loop: 56 | for { 57 | token = context.Peek() 58 | switch token.Type { 59 | case TokenEOL: 60 | break loop 61 | 62 | case TokenLong, TokenShort: 63 | flagToken := token 64 | defaultValue := "" 65 | var flag *FlagClause 66 | var ok bool 67 | invert := false 68 | 69 | name := token.Value 70 | if token.Type == TokenLong { 71 | if strings.HasPrefix(name, "no-") { 72 | name = name[3:] 73 | invert = true 74 | } 75 | flag, ok = f.long[name] 76 | if !ok { 77 | return fmt.Errorf("unknown long flag '%s'", flagToken) 78 | } 79 | } else { 80 | flag, ok = f.short[name] 81 | if !ok { 82 | return fmt.Errorf("unknown short flag '%s'", flagToken) 83 | } 84 | } 85 | 86 | context.Next() 87 | 88 | fb, ok := flag.value.(boolFlag) 89 | if ok && fb.IsBoolFlag() { 90 | if invert { 91 | defaultValue = "false" 92 | } else { 93 | defaultValue = "true" 94 | } 95 | } else { 96 | if invert { 97 | return fmt.Errorf("unknown long flag '%s'", flagToken) 98 | } 99 | token = context.Peek() 100 | if token.Type != TokenArg { 101 | return fmt.Errorf("expected argument for flag '%s'", flagToken) 102 | } 103 | context.Next() 104 | defaultValue = token.Value 105 | } 106 | 107 | context.matchedFlag(flag, defaultValue) 108 | 109 | default: 110 | break loop 111 | } 112 | } 113 | return nil 114 | } 115 | 116 | func (f *flagGroup) visibleFlags() int { 117 | count := 0 118 | for _, flag := range f.long { 119 | if !flag.hidden { 120 | count++ 121 | } 122 | } 123 | return count 124 | } 125 | 126 | // FlagClause is a fluid interface used to build flags. 127 | type FlagClause struct { 128 | parserMixin 129 | name string 130 | shorthand byte 131 | help string 132 | envar string 133 | defaultValue string 134 | placeholder string 135 | action Action 136 | preAction Action 137 | hidden bool 138 | } 139 | 140 | func newFlag(name, help string) *FlagClause { 141 | f := &FlagClause{ 142 | name: name, 143 | help: help, 144 | } 145 | return f 146 | } 147 | 148 | func (f *FlagClause) needsValue() bool { 149 | return f.required && f.defaultValue == "" 150 | } 151 | 152 | func (f *FlagClause) formatPlaceHolder() string { 153 | if f.placeholder != "" { 154 | return f.placeholder 155 | } 156 | if f.defaultValue != "" { 157 | if _, ok := f.value.(*stringValue); ok { 158 | return fmt.Sprintf("%q", f.defaultValue) 159 | } 160 | return f.defaultValue 161 | } 162 | return strings.ToUpper(f.name) 163 | } 164 | 165 | func (f *FlagClause) init() error { 166 | if f.required && f.defaultValue != "" { 167 | return fmt.Errorf("required flag '--%s' with default value that will never be used", f.name) 168 | } 169 | if f.value == nil { 170 | return fmt.Errorf("no type defined for --%s (eg. .String())", f.name) 171 | } 172 | if f.envar != "" { 173 | if v := os.Getenv(f.envar); v != "" { 174 | f.defaultValue = v 175 | } 176 | } 177 | return nil 178 | } 179 | 180 | // Dispatch to the given function after the flag is parsed and validated. 181 | func (f *FlagClause) Action(action Action) *FlagClause { 182 | f.action = action 183 | return f 184 | } 185 | 186 | func (f *FlagClause) PreAction(action Action) *FlagClause { 187 | f.preAction = action 188 | return f 189 | } 190 | 191 | // Default value for this flag. It *must* be parseable by the value of the flag. 192 | func (f *FlagClause) Default(value string) *FlagClause { 193 | f.defaultValue = value 194 | return f 195 | } 196 | 197 | // OverrideDefaultFromEnvar overrides the default value for a flag from an 198 | // environment variable, if available. 199 | func (f *FlagClause) OverrideDefaultFromEnvar(envar string) *FlagClause { 200 | f.envar = envar 201 | return f 202 | } 203 | 204 | // PlaceHolder sets the place-holder string used for flag values in the help. The 205 | // default behaviour is to use the value provided by Default() if provided, 206 | // then fall back on the capitalized flag name. 207 | func (f *FlagClause) PlaceHolder(placeholder string) *FlagClause { 208 | f.placeholder = placeholder 209 | return f 210 | } 211 | 212 | // Hidden hides a flag from usage but still allows it to be used. 213 | func (f *FlagClause) Hidden() *FlagClause { 214 | f.hidden = true 215 | return f 216 | } 217 | 218 | // Required makes the flag required. You can not provide a Default() value to a Required() flag. 219 | func (f *FlagClause) Required() *FlagClause { 220 | f.required = true 221 | return f 222 | } 223 | 224 | // Short sets the short flag name. 225 | func (f *FlagClause) Short(name byte) *FlagClause { 226 | f.shorthand = name 227 | return f 228 | } 229 | 230 | // Bool makes this flag a boolean flag. 231 | func (f *FlagClause) Bool() (target *bool) { 232 | target = new(bool) 233 | f.SetValue(newBoolValue(target)) 234 | return 235 | } 236 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/global.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | ) 7 | 8 | var ( 9 | // CommandLine is the default Kingpin parser. 10 | CommandLine = New(filepath.Base(os.Args[0]), "") 11 | ) 12 | 13 | // Command adds a new command to the default parser. 14 | func Command(name, help string) *CmdClause { 15 | return CommandLine.Command(name, help) 16 | } 17 | 18 | // Flag adds a new flag to the default parser. 19 | func Flag(name, help string) *FlagClause { 20 | return CommandLine.Flag(name, help) 21 | } 22 | 23 | // Arg adds a new argument to the top-level of the default parser. 24 | func Arg(name, help string) *ArgClause { 25 | return CommandLine.Arg(name, help) 26 | } 27 | 28 | // Parse and return the selected command. Will call the termination handler if 29 | // an error is encountered. 30 | func Parse() string { 31 | selected := MustParse(CommandLine.Parse(os.Args[1:])) 32 | if selected == "" && CommandLine.cmdGroup.have() { 33 | Usage() 34 | CommandLine.terminate(0) 35 | } 36 | return selected 37 | } 38 | 39 | // Errorf prints an error message to stderr. 40 | func Errorf(format string, args ...interface{}) { 41 | CommandLine.Errorf(format, args...) 42 | } 43 | 44 | // Fatalf prints an error message to stderr and exits. 45 | func Fatalf(format string, args ...interface{}) { 46 | CommandLine.Fatalf(format, args...) 47 | } 48 | 49 | // FatalIfError prints an error and exits if err is not nil. The error is printed 50 | // with the given prefix. 51 | func FatalIfError(err error, format string, args ...interface{}) { 52 | CommandLine.FatalIfError(err, format, args...) 53 | } 54 | 55 | // FatalUsage prints an error message followed by usage information, then 56 | // exits with a non-zero status. 57 | func FatalUsage(format string, args ...interface{}) { 58 | CommandLine.FatalUsage(format, args...) 59 | } 60 | 61 | // FatalUsageContext writes a printf formatted error message to stderr, then 62 | // usage information for the given ParseContext, before exiting. 63 | func FatalUsageContext(context *ParseContext, format string, args ...interface{}) { 64 | CommandLine.FatalUsageContext(context, format, args...) 65 | } 66 | 67 | // Usage prints usage to stderr. 68 | func Usage() { 69 | CommandLine.Usage(os.Args[1:]) 70 | } 71 | 72 | // Set global usage template to use (defaults to DefaultUsageTemplate). 73 | func UsageTemplate(template string) *Application { 74 | return CommandLine.UsageTemplate(template) 75 | } 76 | 77 | // MustParse can be used with app.Parse(args) to exit with an error if parsing fails. 78 | func MustParse(command string, err error) string { 79 | if err != nil { 80 | Fatalf("%s, try --help", err) 81 | } 82 | return command 83 | } 84 | 85 | // Version adds a flag for displaying the application version number. 86 | func Version(version string) *Application { 87 | return CommandLine.Version(version) 88 | } 89 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth.go: -------------------------------------------------------------------------------- 1 | // +build !linux,!freebsd,!darwin,!dragonfly,!netbsd,!openbsd 2 | 3 | package kingpin 4 | 5 | import "io" 6 | 7 | func guessWidth(w io.Writer) int { 8 | return 80 9 | } 10 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth_unix.go: -------------------------------------------------------------------------------- 1 | // +build linux freebsd darwin dragonfly netbsd openbsd 2 | 3 | package kingpin 4 | 5 | import ( 6 | "io" 7 | "os" 8 | "strconv" 9 | "syscall" 10 | "unsafe" 11 | ) 12 | 13 | func guessWidth(w io.Writer) int { 14 | // check if COLUMNS env is set to comply with 15 | // http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap08.html 16 | colsStr := os.Getenv("COLUMNS") 17 | if colsStr != "" { 18 | if cols, err := strconv.Atoi(colsStr); err == nil { 19 | return cols 20 | } 21 | } 22 | 23 | if t, ok := w.(*os.File); ok { 24 | fd := t.Fd() 25 | var dimensions [4]uint16 26 | 27 | if _, _, err := syscall.Syscall6( 28 | syscall.SYS_IOCTL, 29 | uintptr(fd), 30 | uintptr(syscall.TIOCGWINSZ), 31 | uintptr(unsafe.Pointer(&dimensions)), 32 | 0, 0, 0, 33 | ); err == 0 { 34 | return int(dimensions[1]) 35 | } 36 | } 37 | return 80 38 | } 39 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/model.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | // Data model for Kingpin command-line structure. 10 | 11 | type FlagGroupModel struct { 12 | Flags []*FlagModel 13 | } 14 | 15 | func (f *FlagGroupModel) FlagSummary() string { 16 | out := []string{} 17 | count := 0 18 | for _, flag := range f.Flags { 19 | if flag.Name != "help" { 20 | count++ 21 | } 22 | if flag.Required { 23 | if flag.IsBoolFlag() { 24 | out = append(out, fmt.Sprintf("--[no-]%s", flag.Name)) 25 | } else { 26 | out = append(out, fmt.Sprintf("--%s=%s", flag.Name, flag.FormatPlaceHolder())) 27 | } 28 | } 29 | } 30 | if count != len(out) { 31 | out = append(out, "[]") 32 | } 33 | return strings.Join(out, " ") 34 | } 35 | 36 | type FlagModel struct { 37 | Name string 38 | Help string 39 | Short rune 40 | Default string 41 | Envar string 42 | PlaceHolder string 43 | Required bool 44 | Hidden bool 45 | Value Value 46 | } 47 | 48 | func (f *FlagModel) String() string { 49 | return f.Value.String() 50 | } 51 | 52 | func (f *FlagModel) IsBoolFlag() bool { 53 | if fl, ok := f.Value.(boolFlag); ok { 54 | return fl.IsBoolFlag() 55 | } 56 | return false 57 | } 58 | 59 | func (f *FlagModel) FormatPlaceHolder() string { 60 | if f.PlaceHolder != "" { 61 | return f.PlaceHolder 62 | } 63 | if f.Default != "" { 64 | if _, ok := f.Value.(*stringValue); ok { 65 | return strconv.Quote(f.Default) 66 | } 67 | return f.Default 68 | } 69 | return strings.ToUpper(f.Name) 70 | } 71 | 72 | type ArgGroupModel struct { 73 | Args []*ArgModel 74 | } 75 | 76 | func (a *ArgGroupModel) ArgSummary() string { 77 | depth := 0 78 | out := []string{} 79 | for _, arg := range a.Args { 80 | h := "<" + arg.Name + ">" 81 | if !arg.Required { 82 | h = "[" + h 83 | depth++ 84 | } 85 | out = append(out, h) 86 | } 87 | out[len(out)-1] = out[len(out)-1] + strings.Repeat("]", depth) 88 | return strings.Join(out, " ") 89 | } 90 | 91 | type ArgModel struct { 92 | Name string 93 | Help string 94 | Default string 95 | Required bool 96 | Value Value 97 | } 98 | 99 | func (a *ArgModel) String() string { 100 | return a.Value.String() 101 | } 102 | 103 | type CmdGroupModel struct { 104 | Commands []*CmdModel 105 | } 106 | 107 | func (c *CmdGroupModel) FlattenedCommands() (out []*CmdModel) { 108 | for _, cmd := range c.Commands { 109 | if len(cmd.Commands) == 0 { 110 | out = append(out, cmd) 111 | } 112 | out = append(out, cmd.FlattenedCommands()...) 113 | } 114 | return 115 | } 116 | 117 | type CmdModel struct { 118 | Name string 119 | Help string 120 | FullCommand string 121 | Depth int 122 | *FlagGroupModel 123 | *ArgGroupModel 124 | *CmdGroupModel 125 | } 126 | 127 | func (c *CmdModel) String() string { 128 | return c.FullCommand 129 | } 130 | 131 | type ApplicationModel struct { 132 | Name string 133 | Help string 134 | Version string 135 | Author string 136 | *ArgGroupModel 137 | *CmdGroupModel 138 | *FlagGroupModel 139 | } 140 | 141 | func (a *Application) Model() *ApplicationModel { 142 | return &ApplicationModel{ 143 | Name: a.Name, 144 | Help: a.Help, 145 | Version: a.version, 146 | Author: a.author, 147 | FlagGroupModel: a.flagGroup.Model(), 148 | ArgGroupModel: a.argGroup.Model(), 149 | CmdGroupModel: a.cmdGroup.Model(), 150 | } 151 | } 152 | 153 | func (a *argGroup) Model() *ArgGroupModel { 154 | m := &ArgGroupModel{} 155 | for _, arg := range a.args { 156 | m.Args = append(m.Args, arg.Model()) 157 | } 158 | return m 159 | } 160 | 161 | func (a *ArgClause) Model() *ArgModel { 162 | return &ArgModel{ 163 | Name: a.name, 164 | Help: a.help, 165 | Default: a.defaultValue, 166 | Required: a.required, 167 | Value: a.value, 168 | } 169 | } 170 | 171 | func (f *flagGroup) Model() *FlagGroupModel { 172 | m := &FlagGroupModel{} 173 | for _, fl := range f.flagOrder { 174 | m.Flags = append(m.Flags, fl.Model()) 175 | } 176 | return m 177 | } 178 | 179 | func (f *FlagClause) Model() *FlagModel { 180 | return &FlagModel{ 181 | Name: f.name, 182 | Help: f.help, 183 | Short: rune(f.shorthand), 184 | Default: f.defaultValue, 185 | Envar: f.envar, 186 | PlaceHolder: f.placeholder, 187 | Required: f.required, 188 | Hidden: f.hidden, 189 | Value: f.value, 190 | } 191 | } 192 | 193 | func (c *cmdGroup) Model() *CmdGroupModel { 194 | m := &CmdGroupModel{} 195 | for _, cm := range c.commandOrder { 196 | m.Commands = append(m.Commands, cm.Model()) 197 | } 198 | return m 199 | } 200 | 201 | func (c *CmdClause) Model() *CmdModel { 202 | depth := 0 203 | for i := c; i != nil; i = i.parent { 204 | depth++ 205 | } 206 | return &CmdModel{ 207 | Name: c.name, 208 | Help: c.help, 209 | Depth: depth, 210 | FullCommand: c.FullCommand(), 211 | FlagGroupModel: c.flagGroup.Model(), 212 | ArgGroupModel: c.argGroup.Model(), 213 | CmdGroupModel: c.cmdGroup.Model(), 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/repeated.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "net" 5 | "time" 6 | ) 7 | 8 | // This file is autogenerated by "go generate .". Do not modify. 9 | 10 | // Strings accumulates string values into a slice. 11 | func (p *parserMixin) Strings() (target *[]string) { 12 | target = new([]string) 13 | p.StringsVar(target) 14 | return 15 | } 16 | 17 | func (p *parserMixin) StringsVar(target *[]string) { 18 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newStringValue(v.(*string)) })) 19 | } 20 | 21 | // Uint64List accumulates uint64 values into a slice. 22 | func (p *parserMixin) Uint64List() (target *[]uint64) { 23 | target = new([]uint64) 24 | p.Uint64ListVar(target) 25 | return 26 | } 27 | 28 | func (p *parserMixin) Uint64ListVar(target *[]uint64) { 29 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newUint64Value(v.(*uint64)) })) 30 | } 31 | 32 | // Int64List accumulates int64 values into a slice. 33 | func (p *parserMixin) Int64List() (target *[]int64) { 34 | target = new([]int64) 35 | p.Int64ListVar(target) 36 | return 37 | } 38 | 39 | func (p *parserMixin) Int64ListVar(target *[]int64) { 40 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newInt64Value(v.(*int64)) })) 41 | } 42 | 43 | // DurationList accumulates time.Duration values into a slice. 44 | func (p *parserMixin) DurationList() (target *[]time.Duration) { 45 | target = new([]time.Duration) 46 | p.DurationListVar(target) 47 | return 48 | } 49 | 50 | func (p *parserMixin) DurationListVar(target *[]time.Duration) { 51 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newDurationValue(v.(*time.Duration)) })) 52 | } 53 | 54 | // IPList accumulates net.IP values into a slice. 55 | func (p *parserMixin) IPList() (target *[]net.IP) { 56 | target = new([]net.IP) 57 | p.IPListVar(target) 58 | return 59 | } 60 | 61 | func (p *parserMixin) IPListVar(target *[]net.IP) { 62 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newIPValue(v.(*net.IP)) })) 63 | } 64 | 65 | // TCPList accumulates *net.TCPAddr values into a slice. 66 | func (p *parserMixin) TCPList() (target *[]*net.TCPAddr) { 67 | target = new([]*net.TCPAddr) 68 | p.TCPListVar(target) 69 | return 70 | } 71 | 72 | func (p *parserMixin) TCPListVar(target *[]*net.TCPAddr) { 73 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newTCPAddrValue(v.(**net.TCPAddr)) })) 74 | } 75 | 76 | // ExistingFiles accumulates string values into a slice. 77 | func (p *parserMixin) ExistingFiles() (target *[]string) { 78 | target = new([]string) 79 | p.ExistingFilesVar(target) 80 | return 81 | } 82 | 83 | func (p *parserMixin) ExistingFilesVar(target *[]string) { 84 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newExistingFileValue(v.(*string)) })) 85 | } 86 | 87 | // ExistingDirs accumulates string values into a slice. 88 | func (p *parserMixin) ExistingDirs() (target *[]string) { 89 | target = new([]string) 90 | p.ExistingDirsVar(target) 91 | return 92 | } 93 | 94 | func (p *parserMixin) ExistingDirsVar(target *[]string) { 95 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newExistingDirValue(v.(*string)) })) 96 | } 97 | 98 | // ExistingFilesOrDirs accumulates string values into a slice. 99 | func (p *parserMixin) ExistingFilesOrDirs() (target *[]string) { 100 | target = new([]string) 101 | p.ExistingFilesOrDirsVar(target) 102 | return 103 | } 104 | 105 | func (p *parserMixin) ExistingFilesOrDirsVar(target *[]string) { 106 | p.SetValue(newAccumulator(target, func(v interface{}) Value { return newExistingFileOrDirValue(v.(*string)) })) 107 | } 108 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/repeated.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name": "String", "type": "string", "plural": "Strings"}, 3 | {"name": "Uint64", "type": "uint64"}, 4 | {"name": "Int64", "type": "int64"}, 5 | {"name": "Duration", "type": "time.Duration"}, 6 | {"name": "IP", "type": "net.IP"}, 7 | {"name": "TCPAddr", "Type": "*net.TCPAddr", "plural": "TCPList"}, 8 | {"name": "ExistingFile", "Type": "string", "plural": "ExistingFiles"}, 9 | {"name": "ExistingDir", "Type": "string", "plural": "ExistingDirs"}, 10 | {"name": "ExistingFileOrDir", "Type": "string", "plural": "ExistingFilesOrDirs"} 11 | ] 12 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/templates.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | // Default usage template. 4 | var DefaultUsageTemplate = `{{define "FormatCommand"}}\ 5 | {{if .FlagSummary}} {{.FlagSummary}}{{end}}\ 6 | {{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\ 7 | {{end}}\ 8 | 9 | {{define "FormatCommands"}}\ 10 | {{range .FlattenedCommands}}\ 11 | {{.FullCommand}}{{template "FormatCommand" .}} 12 | {{.Help|Wrap 4}} 13 | {{end}}\ 14 | {{end}}\ 15 | 16 | {{define "FormatUsage"}}\ 17 | {{template "FormatCommand" .}}{{if .Commands}} [ ...]{{end}} 18 | {{if .Help}} 19 | {{.Help|Wrap 0}}\ 20 | {{end}}\ 21 | 22 | {{end}}\ 23 | 24 | {{if .Context.SelectedCommand}}\ 25 | usage: {{.App.Name}} {{.Context.SelectedCommand}}{{template "FormatUsage" .Context.SelectedCommand}} 26 | {{else}}\ 27 | usage: {{.App.Name}}{{template "FormatUsage" .App}} 28 | {{end}}\ 29 | {{if .Context.Flags}}\ 30 | Flags: 31 | {{.Context.Flags|FlagsToTwoColumns|FormatTwoColumns}} 32 | {{end}}\ 33 | {{if .Context.Args}}\ 34 | Args: 35 | {{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}} 36 | {{end}}\ 37 | {{if .Context.SelectedCommand}}\ 38 | Subcommands: 39 | {{if .Context.SelectedCommand.Commands}}\ 40 | {{template "FormatCommands" .Context.SelectedCommand}} 41 | {{end}}\ 42 | {{else if .App.Commands}}\ 43 | Commands: 44 | {{template "FormatCommands" .App}} 45 | {{end}}\ 46 | ` 47 | 48 | // Usage template with compactly formatted commands. 49 | var CompactUsageTemplate = `{{define "FormatCommand"}}\ 50 | {{if .FlagSummary}} {{.FlagSummary}}{{end}}\ 51 | {{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\ 52 | {{end}}\ 53 | 54 | {{define "FormatCommandList"}}\ 55 | {{range .}}\ 56 | {{.Depth|Indent}}{{.Name}}{{template "FormatCommand" .}} 57 | {{template "FormatCommandList" .Commands}}\ 58 | {{end}}\ 59 | {{end}}\ 60 | 61 | {{define "FormatUsage"}}\ 62 | {{template "FormatCommand" .}}{{if .Commands}} [ ...]{{end}} 63 | {{if .Help}} 64 | {{.Help|Wrap 0}}\ 65 | {{end}}\ 66 | 67 | {{end}}\ 68 | 69 | {{if .Context.SelectedCommand}}\ 70 | usage: {{.App.Name}} {{.Context.SelectedCommand}}{{template "FormatUsage" .Context.SelectedCommand}} 71 | {{else}}\ 72 | usage: {{.App.Name}}{{template "FormatUsage" .App}} 73 | {{end}}\ 74 | {{if .Context.Flags}}\ 75 | Flags: 76 | {{.Context.Flags|FlagsToTwoColumns|FormatTwoColumns}} 77 | {{end}}\ 78 | {{if .Context.Args}}\ 79 | Args: 80 | {{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}} 81 | {{end}}\ 82 | {{if .Context.SelectedCommand}}\ 83 | {{if .Context.SelectedCommand.Commands}}\ 84 | Commands: 85 | {{.Context.SelectedCommand}} 86 | {{template "FormatCommandList" .Context.SelectedCommand.Commands}} 87 | {{end}}\ 88 | {{else if .App.Commands}}\ 89 | Commands: 90 | {{template "FormatCommandList" .App.Commands}} 91 | {{end}}\ 92 | ` 93 | 94 | var ManPageTemplate = `{{define "FormatFlags"}}\ 95 | {{range .Flags}}\ 96 | {{if not .Hidden}}\ 97 | .TP 98 | \fB{{if .Short}}-{{.Short|Char}}, {{end}}--{{.Name}}{{if not .IsBoolFlag}}={{.FormatPlaceHolder}}{{end}}\\fR 99 | {{.Help}} 100 | {{end}}\ 101 | {{end}}\ 102 | {{end}}\ 103 | 104 | {{define "FormatCommand"}}\ 105 | {{if .FlagSummary}} {{.FlagSummary}}{{end}}\ 106 | {{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\ 107 | {{end}}\ 108 | 109 | {{define "FormatCommands"}}\ 110 | {{range .FlattenedCommands}}\ 111 | .SS 112 | \fB{{.FullCommand}}{{template "FormatCommand" .}}\\fR 113 | .PP 114 | {{.Help}} 115 | {{template "FormatFlags" .}}\ 116 | {{end}}\ 117 | {{end}}\ 118 | 119 | {{define "FormatUsage"}}\ 120 | {{template "FormatCommand" .}}{{if .Commands}} [ ...]{{end}}\\fR 121 | {{end}}\ 122 | 123 | .TH {{.App.Name}} 1 {{.App.Version}} "{{.App.Author}}" 124 | .SH "NAME" 125 | {{.App.Name}} 126 | .SH "SYNOPSIS" 127 | .TP 128 | \fB{{.App.Name}}{{template "FormatUsage" .App}} 129 | .SH "DESCRIPTION" 130 | {{.App.Help}} 131 | .SH "OPTIONS" 132 | {{template "FormatFlags" .App}}\ 133 | {{if .App.Commands}}\ 134 | .SH "COMMANDS" 135 | {{template "FormatCommands" .App}}\ 136 | {{end}}\ 137 | ` 138 | 139 | // Default usage template. 140 | var LongHelpTemplate = `{{define "FormatCommand"}}\ 141 | {{if .FlagSummary}} {{.FlagSummary}}{{end}}\ 142 | {{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\ 143 | {{end}}\ 144 | 145 | {{define "FormatCommands"}}\ 146 | {{range .FlattenedCommands}}\ 147 | {{.FullCommand}}{{template "FormatCommand" .}} 148 | {{.Help|Wrap 4}} 149 | {{with .Flags|FlagsToTwoColumns}}{{FormatTwoColumnsWithIndent . 4 2}}{{end}} 150 | {{end}}\ 151 | {{end}}\ 152 | 153 | {{define "FormatUsage"}}\ 154 | {{template "FormatCommand" .}}{{if .Commands}} [ ...]{{end}} 155 | {{if .Help}} 156 | {{.Help|Wrap 0}}\ 157 | {{end}}\ 158 | 159 | {{end}}\ 160 | 161 | usage: {{.App.Name}}{{template "FormatUsage" .App}} 162 | {{if .Context.Flags}}\ 163 | Flags: 164 | {{.Context.Flags|FlagsToTwoColumns|FormatTwoColumns}} 165 | {{end}}\ 166 | {{if .Context.Args}}\ 167 | Args: 168 | {{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}} 169 | {{end}}\ 170 | {{if .App.Commands}}\ 171 | Commands: 172 | {{template "FormatCommands" .App}} 173 | {{end}}\ 174 | ` 175 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/usage.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "go/doc" 7 | "io" 8 | "strings" 9 | 10 | "github.com/alecthomas/template" 11 | ) 12 | 13 | var ( 14 | preIndent = " " 15 | ) 16 | 17 | func formatTwoColumns(w io.Writer, indent, padding, width int, rows [][2]string) { 18 | // Find size of first column. 19 | s := 0 20 | for _, row := range rows { 21 | if c := len(row[0]); c > s && c < 20 { 22 | s = c 23 | } 24 | } 25 | 26 | indentStr := strings.Repeat(" ", indent) 27 | offsetStr := strings.Repeat(" ", s+padding) 28 | 29 | for _, row := range rows { 30 | buf := bytes.NewBuffer(nil) 31 | doc.ToText(buf, row[1], "", preIndent, width-s-padding-indent) 32 | lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n") 33 | fmt.Fprintf(w, "%s%-*s%*s", indentStr, s, row[0], padding, "") 34 | if len(row[0]) >= 20 { 35 | fmt.Fprintf(w, "\n%s%s", indentStr, offsetStr) 36 | } 37 | fmt.Fprintf(w, "%s\n", lines[0]) 38 | for _, line := range lines[1:] { 39 | fmt.Fprintf(w, "%s%s%s\n", indentStr, offsetStr, line) 40 | } 41 | } 42 | } 43 | 44 | // Usage writes application usage to w. It parses args to determine 45 | // appropriate help context, such as which command to show help for. 46 | func (a *Application) Usage(args []string) { 47 | context, err := a.ParseContext(args) 48 | a.FatalIfError(err, "") 49 | if err := a.UsageForContextWithTemplate(context, 2, a.usageTemplate); err != nil { 50 | panic(err) 51 | } 52 | } 53 | 54 | func formatAppUsage(app *ApplicationModel) string { 55 | s := []string{app.Name} 56 | if len(app.Flags) > 0 { 57 | s = append(s, app.FlagSummary()) 58 | } 59 | if len(app.Args) > 0 { 60 | s = append(s, app.ArgSummary()) 61 | } 62 | return strings.Join(s, " ") 63 | } 64 | 65 | func formatCmdUsage(app *ApplicationModel, cmd *CmdModel) string { 66 | s := []string{app.Name, cmd.String()} 67 | if len(app.Flags) > 0 { 68 | s = append(s, app.FlagSummary()) 69 | } 70 | if len(app.Args) > 0 { 71 | s = append(s, app.ArgSummary()) 72 | } 73 | return strings.Join(s, " ") 74 | } 75 | 76 | func formatFlag(flag *FlagModel) string { 77 | flagString := "" 78 | if flag.Short != 0 { 79 | flagString += fmt.Sprintf("-%c, ", flag.Short) 80 | } 81 | flagString += fmt.Sprintf("--%s", flag.Name) 82 | if !flag.IsBoolFlag() { 83 | flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder()) 84 | } 85 | return flagString 86 | } 87 | 88 | type templateParseContext struct { 89 | SelectedCommand *CmdModel 90 | *FlagGroupModel 91 | *ArgGroupModel 92 | } 93 | 94 | type templateContext struct { 95 | App *ApplicationModel 96 | Width int 97 | Context *templateParseContext 98 | } 99 | 100 | // UsageForContext displays usage information from a ParseContext (obtained from 101 | // Application.ParseContext() or Action(f) callbacks). 102 | func (a *Application) UsageForContext(context *ParseContext) error { 103 | return a.UsageForContextWithTemplate(context, 2, a.usageTemplate) 104 | } 105 | 106 | // UsageForContextWithTemplate is the base usage function. You generally don't need to use this. 107 | func (a *Application) UsageForContextWithTemplate(context *ParseContext, indent int, tmpl string) error { 108 | width := guessWidth(a.writer) 109 | funcs := template.FuncMap{ 110 | "Indent": func(level int) string { 111 | return strings.Repeat(" ", level*indent) 112 | }, 113 | "Wrap": func(indent int, s string) string { 114 | buf := bytes.NewBuffer(nil) 115 | indentText := strings.Repeat(" ", indent) 116 | doc.ToText(buf, s, indentText, indentText, width) 117 | return buf.String() 118 | }, 119 | "FormatFlag": formatFlag, 120 | "FlagsToTwoColumns": func(f []*FlagModel) [][2]string { 121 | rows := [][2]string{} 122 | for _, flag := range f { 123 | if !flag.Hidden { 124 | rows = append(rows, [2]string{formatFlag(flag), flag.Help}) 125 | } 126 | } 127 | return rows 128 | }, 129 | "ArgsToTwoColumns": func(a []*ArgModel) [][2]string { 130 | rows := [][2]string{} 131 | for _, arg := range a { 132 | s := "<" + arg.Name + ">" 133 | if !arg.Required { 134 | s = "[" + s + "]" 135 | } 136 | rows = append(rows, [2]string{s, arg.Help}) 137 | } 138 | return rows 139 | }, 140 | "FormatTwoColumns": func(rows [][2]string) string { 141 | buf := bytes.NewBuffer(nil) 142 | formatTwoColumns(buf, indent, indent, width, rows) 143 | return buf.String() 144 | }, 145 | "FormatTwoColumnsWithIndent": func(rows [][2]string, indent, padding int) string { 146 | buf := bytes.NewBuffer(nil) 147 | formatTwoColumns(buf, indent, padding, width, rows) 148 | return buf.String() 149 | }, 150 | "FormatAppUsage": formatAppUsage, 151 | "FormatCommandUsage": formatCmdUsage, 152 | "IsCumulative": func(value Value) bool { 153 | _, ok := value.(remainderArg) 154 | return ok 155 | }, 156 | "Char": func(c rune) string { 157 | return string(c) 158 | }, 159 | } 160 | t, err := template.New("usage").Funcs(funcs).Parse(tmpl) 161 | if err != nil { 162 | return err 163 | } 164 | var selectedCommand *CmdModel 165 | if context.SelectedCommand != nil { 166 | selectedCommand = context.SelectedCommand.Model() 167 | } 168 | ctx := templateContext{ 169 | App: a.Model(), 170 | Width: width, 171 | Context: &templateParseContext{ 172 | SelectedCommand: selectedCommand, 173 | FlagGroupModel: context.flags.Model(), 174 | ArgGroupModel: context.arguments.Model(), 175 | }, 176 | } 177 | return t.Execute(a.writer, ctx) 178 | } 179 | --------------------------------------------------------------------------------