├── Dockerfile ├── Godeps ├── Godeps.json └── Readme ├── README.md ├── apiserver ├── cache.go ├── cache_test.go ├── defacer.go ├── defacer_test.go ├── http.go ├── internal │ ├── assets.go │ ├── assets │ │ ├── deface.png │ │ ├── face.jpg │ │ └── haarcascade_frontalface_alt.xml │ ├── bindata.go │ ├── face.go │ ├── face_test.go │ ├── hc.go │ └── hc_test.go ├── math.go ├── metrics.go ├── proxy.go ├── resizer.go └── resizer_test.go ├── main.go └── vendor └── github.com ├── beorn7 └── perks │ └── quantile │ ├── exampledata.txt │ └── stream.go ├── golang └── protobuf │ ├── LICENSE │ └── proto │ ├── Makefile │ ├── clone.go │ ├── decode.go │ ├── encode.go │ ├── equal.go │ ├── extensions.go │ ├── lib.go │ ├── message_set.go │ ├── pointer_reflect.go │ ├── pointer_unsafe.go │ ├── properties.go │ ├── proto3_proto │ ├── proto3.pb.go │ └── proto3.proto │ ├── text.go │ └── text_parser.go ├── lazywei └── go-opencv │ ├── LICENSE │ └── opencv │ ├── cluster.go │ ├── cv.go │ ├── cvaux.go │ ├── cxcore.go │ ├── cxtype.go │ ├── doc.go │ ├── goimage.go │ ├── highgui.go │ ├── imgproc.go │ ├── opencv.c │ ├── opencv.go │ └── opencv.h ├── matttproud └── golang_protobuf_extensions │ ├── LICENSE │ ├── NOTICE │ └── pbutil │ ├── decode.go │ ├── doc.go │ └── encode.go ├── nfnt └── resize │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── converter.go │ ├── filters.go │ ├── nearest.go │ ├── resize.go │ ├── thumbnail.go │ └── ycc.go └── prometheus ├── client_golang ├── LICENSE ├── NOTICE └── prometheus │ ├── .gitignore │ ├── README.md │ ├── collector.go │ ├── counter.go │ ├── desc.go │ ├── doc.go │ ├── expvar.go │ ├── gauge.go │ ├── go_collector.go │ ├── histogram.go │ ├── http.go │ ├── metric.go │ ├── process_collector.go │ ├── push.go │ ├── registry.go │ ├── summary.go │ ├── untyped.go │ ├── value.go │ └── vec.go ├── client_model ├── LICENSE ├── NOTICE ├── go │ └── metrics.pb.go └── ruby │ └── LICENSE ├── common ├── LICENSE ├── NOTICE ├── expfmt │ ├── decode.go │ ├── encode.go │ ├── expfmt.go │ ├── fuzz.go │ ├── fuzz │ │ └── corpus │ │ │ ├── from_test_parse_0 │ │ │ ├── from_test_parse_1 │ │ │ ├── from_test_parse_2 │ │ │ ├── from_test_parse_3 │ │ │ ├── from_test_parse_4 │ │ │ ├── from_test_parse_error_0 │ │ │ ├── from_test_parse_error_1 │ │ │ ├── from_test_parse_error_10 │ │ │ ├── from_test_parse_error_11 │ │ │ ├── from_test_parse_error_12 │ │ │ ├── from_test_parse_error_13 │ │ │ ├── from_test_parse_error_14 │ │ │ ├── from_test_parse_error_15 │ │ │ ├── from_test_parse_error_16 │ │ │ ├── from_test_parse_error_17 │ │ │ ├── from_test_parse_error_18 │ │ │ ├── from_test_parse_error_19 │ │ │ ├── from_test_parse_error_2 │ │ │ ├── from_test_parse_error_3 │ │ │ ├── from_test_parse_error_4 │ │ │ ├── from_test_parse_error_5 │ │ │ ├── from_test_parse_error_6 │ │ │ ├── from_test_parse_error_7 │ │ │ ├── from_test_parse_error_8 │ │ │ ├── from_test_parse_error_9 │ │ │ └── minimal │ ├── json_decode.go │ ├── text_create.go │ └── text_parse.go ├── internal │ └── bitbucket.org │ │ └── ww │ │ └── goautoneg │ │ ├── README.txt │ │ └── autoneg.go └── model │ ├── alert.go │ ├── fingerprinting.go │ ├── labels.go │ ├── labelset.go │ ├── metric.go │ ├── model.go │ ├── signature.go │ ├── silence.go │ ├── time.go │ └── value.go └── procfs ├── .travis.yml ├── AUTHORS.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── NOTICE ├── README.md ├── doc.go ├── fixtures ├── 584 │ └── stat ├── 26231 │ ├── cmdline │ ├── comm │ ├── exe │ ├── fd │ │ ├── 0 │ │ ├── 1 │ │ ├── 2 │ │ ├── 3 │ │ └── 10 │ ├── io │ ├── limits │ └── stat ├── 26232 │ ├── cmdline │ ├── comm │ ├── fd │ │ ├── 0 │ │ ├── 1 │ │ ├── 2 │ │ ├── 3 │ │ └── 4 │ ├── limits │ └── stat ├── mdstat ├── net │ ├── ip_vs │ └── ip_vs_stats ├── self ├── stat └── symlinktargets │ ├── README │ ├── abc │ ├── def │ ├── ghi │ ├── uvw │ └── xyz ├── fs.go ├── ipvs.go ├── mdstat.go ├── proc.go ├── proc_io.go ├── proc_limits.go ├── proc_stat.go └── stat.go /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.5 2 | 3 | ADD . /go/src/github.com/fiorix/defacer 4 | WORKDIR /go/src/github.com/fiorix/defacer 5 | 6 | RUN \ 7 | echo deb http://httpredir.debian.org/debian jessie main > /etc/apt/sources.list ; \ 8 | echo deb http://httpredir.debian.org/debian jessie-updates main >> /etc/apt/sources.list ; \ 9 | echo deb http://security.debian.org/ jessie/updates main >> /etc/apt/sources.list ; \ 10 | apt-get update ; \ 11 | apt-get install -y \ 12 | build-essential \ 13 | libopencv-calib3d2.4 \ 14 | libopencv-contrib2.4 \ 15 | libopencv-core2.4 \ 16 | libopencv-dev \ 17 | libopencv-imgproc2.4 \ 18 | libopencv-ocl2.4 \ 19 | libopencv-stitching2.4 \ 20 | libopencv-superres2.4 \ 21 | libopencv-ts2.4 \ 22 | libopencv-videostab2.4 ; \ 23 | GO15VENDOREXPERIMENT=1 go install ; \ 24 | apt-get autoremove -y --purge \ 25 | '.*-dev$' \ 26 | binutils \ 27 | build-essential \ 28 | cpp \ 29 | g++ \ 30 | gcc \ 31 | gcc-4.8-base \ 32 | i965-va-driver \ 33 | libopencv-dev \ 34 | make \ 35 | perl \ 36 | python \ 37 | va-driver-all \ 38 | vdpau-va-driver ; \ 39 | apt-get clean ; \ 40 | rm -rf /var/lib/apt/lists/* ; \ 41 | rm -rf /usr/share/doc/* ; \ 42 | rm -rf /usr/share/man/* ; \ 43 | rm -rf /usr/share/locale/* ; \ 44 | rm -rf /usr/local/go 45 | 46 | ENTRYPOINT ["/go/bin/defacer"] 47 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/fiorix/defacer", 3 | "GoVersion": "go1.5.1", 4 | "Deps": [ 5 | { 6 | "ImportPath": "github.com/beorn7/perks/quantile", 7 | "Rev": "b965b613227fddccbfffe13eae360ed3fa822f8d" 8 | }, 9 | { 10 | "ImportPath": "github.com/golang/protobuf/proto", 11 | "Rev": "fb5d8f484732ab045605ecc5ab388726a554a5eb" 12 | }, 13 | { 14 | "ImportPath": "github.com/lazywei/go-opencv/opencv", 15 | "Rev": "60747d253e80b66cfbc5480ef8a9dcd02030215b" 16 | }, 17 | { 18 | "ImportPath": "github.com/matttproud/golang_protobuf_extensions/pbutil", 19 | "Rev": "d0c3fe89de86839aecf2e0579c40ba3bb336a453" 20 | }, 21 | { 22 | "ImportPath": "github.com/nfnt/resize", 23 | "Rev": "dc93e1b98c579d90ee2fa15c1fd6dac34f6e7899" 24 | }, 25 | { 26 | "ImportPath": "github.com/prometheus/client_golang/prometheus", 27 | "Comment": "0.7.0-53-g449ccef", 28 | "Rev": "449ccefff16c8e2b7229f6be1921ba22f62461fe" 29 | }, 30 | { 31 | "ImportPath": "github.com/prometheus/client_model/go", 32 | "Comment": "model-0.0.2-12-gfa8ad6f", 33 | "Rev": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6" 34 | }, 35 | { 36 | "ImportPath": "github.com/prometheus/common/expfmt", 37 | "Rev": "4fdc91a58c9d3696b982e8a680f4997403132d44" 38 | }, 39 | { 40 | "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", 41 | "Rev": "4fdc91a58c9d3696b982e8a680f4997403132d44" 42 | }, 43 | { 44 | "ImportPath": "github.com/prometheus/common/model", 45 | "Rev": "4fdc91a58c9d3696b982e8a680f4997403132d44" 46 | }, 47 | { 48 | "ImportPath": "github.com/prometheus/procfs", 49 | "Rev": "406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8" 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /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 | # meow 2 | 3 | Run: 4 | 5 | ```bash 6 | docker run -p 8080:8080 -d fiorix/defacer 7 | curl localhost:8080/api/v1/deface?url=http://bit.ly/1gBahPH > faces.jpg 8 | curl localhost:8080/api/v1/metrics | grep deface 9 | ``` 10 | -------------------------------------------------------------------------------- /apiserver/cache.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "image" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | // imageCache holds resized overlay images indexed by their width and height. 10 | type imageCache struct { 11 | sync.Mutex 12 | m map[image.Point]*imageCacheItem 13 | once sync.Once 14 | } 15 | 16 | type imageCacheItem struct { 17 | Time time.Time 18 | Image image.Image 19 | } 20 | 21 | var defaultImageCache = &imageCache{ 22 | m: make(map[image.Point]*imageCacheItem), 23 | } 24 | 25 | func (ic *imageCache) Get(size *image.Point) image.Image { 26 | ic.once.Do(func() { go ic.flush() }) 27 | ic.Lock() 28 | defer ic.Unlock() 29 | item := ic.m[*size] 30 | if item == nil { 31 | defacerImageCacheMissSum.Inc() 32 | return nil 33 | } 34 | item.Time = time.Now() 35 | defacerImageCacheHitsSum.Inc() 36 | return item.Image 37 | } 38 | 39 | func (ic *imageCache) Set(size *image.Point, m image.Image) { 40 | ic.Lock() 41 | ic.m[*size] = &imageCacheItem{Time: time.Now(), Image: m} 42 | ic.Unlock() 43 | defacerImageCacheItemsCount.Inc() 44 | } 45 | 46 | // flush runs every 5s to evict items that are inactive for up to 5min. 47 | func (ic *imageCache) flush() { 48 | for range time.Tick(5 * time.Second) { 49 | ic.Lock() 50 | for k, v := range ic.m { 51 | if time.Since(v.Time) > 5*time.Minute { 52 | delete(ic.m, k) 53 | defacerImageCacheItemsCount.Dec() 54 | } 55 | } 56 | ic.Unlock() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /apiserver/cache_test.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "image" 5 | "testing" 6 | 7 | "github.com/fiorix/defacer/apiserver/internal" 8 | ) 9 | 10 | func TestImageCache(t *testing.T) { 11 | overlay, err := internal.DefaultDefaceImage() 12 | if err != nil { 13 | t.Fatal(err) 14 | } 15 | size := image.Point{10, 20} 16 | m := defaultImageCache.Get(&size) 17 | if m != nil { 18 | t.Fatal("unexpected image from cache") 19 | } 20 | defaultImageCache.Set(&size, overlay) 21 | m = defaultImageCache.Get(&size) 22 | if m != overlay { 23 | t.Fatal("image missing from cache") 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apiserver/defacer.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "errors" 5 | "image" 6 | "image/draw" 7 | "io" 8 | "runtime" 9 | "sync" 10 | 11 | "github.com/lazywei/go-opencv/opencv" 12 | 13 | "github.com/fiorix/defacer/apiserver/internal" 14 | ) 15 | 16 | // A Defacer can scan and deface people's faces in images. 17 | type Defacer interface { 18 | // Deface reads binary image bytes from a given reader 19 | // and returns a defaced version of the image. 20 | Deface(io.Reader) (image.Image, error) 21 | } 22 | 23 | // NewDefacer creates and initializes a new Defacer. 24 | func NewDefacer(resizer ImageResizer) (Defacer, error) { 25 | hc, err := internal.DefaultHaarCascade() 26 | if err != nil { 27 | return nil, err 28 | } 29 | df := &defacer{ 30 | Resizer: resizer, 31 | HaarCascade: hc, 32 | } 33 | return df, nil 34 | } 35 | 36 | type defacer struct { 37 | sync.Mutex 38 | Resizer ImageResizer 39 | HaarCascade *opencv.HaarCascade 40 | } 41 | 42 | // Deface implements the Defacer interface. 43 | func (df *defacer) Deface(r io.Reader) (image.Image, error) { 44 | img, faces, err := df.scan(r) 45 | if err != nil { 46 | return nil, err 47 | } 48 | b := img.Bounds() 49 | dst := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) 50 | draw.Draw(dst, dst.Bounds(), image.Transparent, image.ZP, draw.Src) 51 | draw.DrawMask(dst, dst.Bounds(), img, b.Min, img, b.Min, draw.Over) 52 | switch len(faces) { 53 | case 0: // nothing to do 54 | case 1: 55 | df.draw(nil, nil, dst, faces[0]) 56 | default: 57 | mu, wg := &sync.Mutex{}, &sync.WaitGroup{} 58 | for _, rect := range faces { 59 | wg.Add(1) 60 | go df.draw(mu, wg, dst, rect) 61 | } 62 | wg.Wait() 63 | } 64 | return dst, nil 65 | } 66 | 67 | // scan reads binary image data from the given reader and scans for 68 | // faces, returning a slice of rectangles where faces were detected. 69 | func (df *defacer) scan(src io.Reader) (m image.Image, r []image.Rectangle, err error) { 70 | img, _, err := image.Decode(src) 71 | if err != nil { 72 | return nil, nil, err 73 | } 74 | df.Lock() 75 | defer df.Unlock() 76 | cvimg := opencv.FromImage(img) 77 | if cvimg == nil { 78 | return nil, nil, errors.New("failed to load source image") 79 | } 80 | faces := df.HaarCascade.DetectObjects(cvimg) 81 | if faces == nil { 82 | return img, []image.Rectangle{}, nil 83 | } 84 | fr := make([]image.Rectangle, len(faces)) 85 | for i, rect := range faces { 86 | x, y, w, h := rect.X(), rect.Y(), rect.Width(), rect.Height() 87 | fr[i] = image.Rectangle{ 88 | image.Point{ 89 | roundDown(x), 90 | roundDown(y), 91 | }, 92 | image.Point{ 93 | roundUp(x + w), 94 | roundUp(y + h), 95 | }, 96 | } 97 | } 98 | return img, fr, nil 99 | } 100 | 101 | // draw blends the deface image onto dst, of the size of the given rectangle. 102 | func (df *defacer) draw(mu *sync.Mutex, wg *sync.WaitGroup, dst draw.Image, r image.Rectangle) { 103 | size := image.Point{r.Max.X - r.Min.X, r.Max.Y - r.Min.Y} 104 | img := df.Resizer.Resize(size) 105 | b := img.Bounds() 106 | if mu != nil { 107 | mu.Lock() 108 | defer mu.Unlock() 109 | } 110 | draw.DrawMask(dst, r, img, b.Min, img, b.Min, draw.Over) 111 | if wg != nil { 112 | wg.Done() 113 | } 114 | defacerImageDefaceSum.Inc() 115 | } 116 | 117 | type defacerPool struct { 118 | Inbox chan *defacerReq 119 | Resizer ImageResizer 120 | } 121 | 122 | type defacerReq struct { 123 | Reader io.Reader 124 | Resp chan *defacerResp 125 | } 126 | 127 | type defacerResp struct { 128 | Image image.Image 129 | Error error 130 | } 131 | 132 | // NewDefacerPool creates a pool of Defacers. 133 | func NewDefacerPool(resizer ImageResizer, workers uint) (Defacer, error) { 134 | dp := &defacerPool{ 135 | Inbox: make(chan *defacerReq, workers), 136 | Resizer: resizer, 137 | } 138 | i := uint(0) 139 | wg := &sync.WaitGroup{} 140 | errc := make(chan error, 1) 141 | defer close(errc) 142 | for ; i < workers; i++ { 143 | wg.Add(1) 144 | go dp.run(wg, errc) 145 | } 146 | wg.Wait() 147 | select { 148 | case err := <-errc: 149 | close(dp.Inbox) 150 | return nil, err 151 | default: 152 | return dp, nil 153 | } 154 | } 155 | 156 | func (dp *defacerPool) Deface(r io.Reader) (image.Image, error) { 157 | req := &defacerReq{ 158 | Reader: r, 159 | Resp: make(chan *defacerResp), 160 | } 161 | defer close(req.Resp) 162 | dp.Inbox <- req 163 | resp := <-req.Resp 164 | return resp.Image, resp.Error 165 | } 166 | 167 | func (dp *defacerPool) run(wg *sync.WaitGroup, errc chan error) { 168 | runtime.LockOSThread() 169 | df, err := NewDefacer(dp.Resizer) 170 | if err != nil { 171 | select { 172 | case errc <- err: 173 | default: 174 | } 175 | wg.Done() 176 | return 177 | } 178 | wg.Done() 179 | for req := range dp.Inbox { 180 | img, err := df.Deface(req.Reader) 181 | req.Resp <- &defacerResp{ 182 | Image: img, 183 | Error: err, 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /apiserver/defacer_test.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/fiorix/defacer/apiserver/internal" 8 | ) 9 | 10 | func TestDefacer(t *testing.T) { 11 | overlay, err := internal.DefaultDefaceImage() 12 | if err != nil { 13 | t.Fatal(err) 14 | } 15 | df, err := NewDefacer(NewImageResizer(overlay)) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | src, err := internal.DefaultFaceBytes() 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | _, err = df.Deface(bytes.NewBuffer(src)) 24 | if err != nil { 25 | t.Fatal(err) 26 | } 27 | } 28 | 29 | func TestDefacerPool(t *testing.T) { 30 | overlay, err := internal.DefaultDefaceImage() 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | df, err := NewDefacerPool(NewImageResizer(overlay), 1) 35 | if err != nil { 36 | t.Fatal(err) 37 | } 38 | src, err := internal.DefaultFaceBytes() 39 | if err != nil { 40 | t.Fatal(err) 41 | } 42 | _, err = df.Deface(bytes.NewBuffer(src)) 43 | if err != nil { 44 | t.Fatal(err) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /apiserver/http.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "image" 5 | "net/http" 6 | "os" 7 | "path" 8 | 9 | "github.com/prometheus/client_golang/prometheus" 10 | 11 | "github.com/fiorix/defacer/apiserver/internal" 12 | ) 13 | 14 | // Handler provides the defacer HTTP API. The zero value of Handler 15 | // is a valid Handler. 16 | type Handler struct { 17 | Prefix string // default: "/" 18 | ImageFile string // default: internal deface image 19 | Workers uint // default: 100 20 | Client *http.Client 21 | } 22 | 23 | // Register registers the defacer API handlers to the given ServeMux. 24 | // 25 | // Endpoints: {prefix}/v1/metrics end {prefix}/v1/deface. 26 | func (h *Handler) Register(mux *http.ServeMux) error { 27 | if h.Prefix == "" { 28 | h.Prefix = "/" 29 | } 30 | if h.Workers == 0 { 31 | h.Workers = 100 32 | } 33 | if h.Client == nil { 34 | h.Client = &http.Client{} 35 | } 36 | df, err := h.newDefacer() 37 | if err != nil { 38 | return err 39 | } 40 | p := path.Clean(path.Join(h.Prefix, "v1")) 41 | mux.Handle(p+"/metrics", prometheus.Handler()) 42 | proxy := DefacerProxy(df, h.Client, nil) 43 | mux.Handle(p+"/deface", prometheus.InstrumentHandler("deface", proxy)) 44 | return nil 45 | } 46 | 47 | // newDefacer creates a defacer pool based on the handler's configuration. 48 | // If ImageFile is empty, we load the default internal deface image. 49 | func (h *Handler) newDefacer() (Defacer, error) { 50 | var err error 51 | var overlay image.Image 52 | switch h.ImageFile { 53 | case "": 54 | overlay, err = internal.DefaultDefaceImage() 55 | if err != nil { 56 | return nil, err 57 | } 58 | default: 59 | f, err := os.Open(h.ImageFile) 60 | if err != nil { 61 | return nil, err 62 | } 63 | defer f.Close() 64 | overlay, _, err = image.Decode(f) 65 | if err != nil { 66 | return nil, err 67 | } 68 | } 69 | return NewDefacerPool(NewImageResizer(overlay), h.Workers) 70 | } 71 | -------------------------------------------------------------------------------- /apiserver/internal/assets.go: -------------------------------------------------------------------------------- 1 | //go:generate go-bindata -pkg=internal ./assets 2 | 3 | package internal 4 | 5 | import ( 6 | "errors" 7 | "io/ioutil" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/lazywei/go-opencv/opencv" 12 | ) 13 | 14 | func tempDir() string { 15 | if v := os.Getenv("TMPDIR"); v != "" { 16 | return v 17 | } 18 | return "/tmp" 19 | } 20 | 21 | func restoreAsset(name string) (*os.File, error) { 22 | b, err := Asset(filepath.Join("assets", name)) 23 | if err != nil { 24 | return nil, err 25 | } 26 | f, err := ioutil.TempFile(tempDir(), "cvdata") 27 | if err != nil { 28 | return nil, err 29 | } 30 | f.Write(b) 31 | f.Seek(0, 0) 32 | return f, nil 33 | } 34 | 35 | func imageAsset(name string) (*opencv.IplImage, error) { 36 | b, err := Asset(filepath.Join("assets", name)) 37 | if err != nil { 38 | return nil, err 39 | } 40 | img := opencv.DecodeImageMem(b) 41 | if img == nil { 42 | return nil, errors.New("failed to load image asset") 43 | } 44 | return img, nil 45 | } 46 | -------------------------------------------------------------------------------- /apiserver/internal/assets/deface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/apiserver/internal/assets/deface.png -------------------------------------------------------------------------------- /apiserver/internal/assets/face.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/apiserver/internal/assets/face.jpg -------------------------------------------------------------------------------- /apiserver/internal/face.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "bytes" 5 | "image" 6 | "image/png" 7 | "path/filepath" 8 | 9 | "github.com/lazywei/go-opencv/opencv" 10 | ) 11 | 12 | func DefaultFace() (*opencv.IplImage, error) { 13 | return imageAsset("face.jpg") 14 | } 15 | 16 | func DefaultFaceBytes() ([]byte, error) { 17 | return Asset(filepath.Join("assets", "face.jpg")) 18 | } 19 | 20 | func DefaultDeface() (*opencv.IplImage, error) { 21 | return imageAsset("deface.png") 22 | } 23 | 24 | func DefaultDefaceBytes() ([]byte, error) { 25 | return Asset(filepath.Join("assets", "deface.png")) 26 | } 27 | 28 | func DefaultDefaceImage() (image.Image, error) { 29 | b, err := DefaultDefaceBytes() 30 | if err != nil { 31 | return nil, err 32 | } 33 | return png.Decode(bytes.NewBuffer(b)) 34 | } 35 | -------------------------------------------------------------------------------- /apiserver/internal/face_test.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import "testing" 4 | 5 | func TestDefaultFace(t *testing.T) { 6 | _, err := DefaultFace() 7 | if err != nil { 8 | t.Fatal(err) 9 | } 10 | } 11 | 12 | func TestDefaultFaceBytes(t *testing.T) { 13 | _, err := DefaultFaceBytes() 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | } 18 | 19 | func TestDefaultDeface(t *testing.T) { 20 | _, err := DefaultDeface() 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | } 25 | 26 | func TestDefaultDefaceBytes(t *testing.T) { 27 | _, err := DefaultDefaceBytes() 28 | if err != nil { 29 | t.Fatal(err) 30 | } 31 | } 32 | 33 | func TestDefaultDefaceImage(t *testing.T) { 34 | _, err := DefaultDefaceImage() 35 | if err != nil { 36 | t.Fatal(err) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /apiserver/internal/hc.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "errors" 5 | "os" 6 | 7 | "github.com/lazywei/go-opencv/opencv" 8 | ) 9 | 10 | func DefaultHaarCascade() (*opencv.HaarCascade, error) { 11 | f, err := restoreAsset("haarcascade_frontalface_alt.xml") 12 | if err != nil { 13 | return nil, err 14 | } 15 | defer f.Close() 16 | defer os.Remove(f.Name()) 17 | hc := opencv.LoadHaarClassifierCascade(f.Name()) 18 | if hc == nil { 19 | return nil, errors.New("failed to load haar cascade") 20 | } 21 | return hc, nil 22 | } 23 | -------------------------------------------------------------------------------- /apiserver/internal/hc_test.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import "testing" 4 | 5 | func TestDefaultHaarCascade(t *testing.T) { 6 | _, err := DefaultHaarCascade() 7 | if err != nil { 8 | t.Fatal(err) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apiserver/math.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | func roundUp(v int) int { 4 | return 10 * ((v + 9) / 10) 5 | } 6 | 7 | func roundDown(v int) int { 8 | return 10 * (v / 10) 9 | } 10 | -------------------------------------------------------------------------------- /apiserver/metrics.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import "github.com/prometheus/client_golang/prometheus" 4 | 5 | var defacerImageDefaceSum = prometheus.NewCounter( 6 | prometheus.CounterOpts{ 7 | Name: "defacer_image_deface_sum", 8 | Help: "Total defaces", 9 | }, 10 | ) 11 | 12 | var defacerImageCacheHitsSum = prometheus.NewCounter( 13 | prometheus.CounterOpts{ 14 | Name: "defacer_image_cache_hits_sum", 15 | Help: "Total cache hits", 16 | }, 17 | ) 18 | 19 | var defacerImageCacheMissSum = prometheus.NewCounter( 20 | prometheus.CounterOpts{ 21 | Name: "defacer_image_cache_miss_sum", 22 | Help: "Total cache miss", 23 | }, 24 | ) 25 | 26 | var defacerImageCacheItemsCount = prometheus.NewGauge( 27 | prometheus.GaugeOpts{ 28 | Name: "defacer_image_cache_items_count", 29 | Help: "Total items cached", 30 | }, 31 | ) 32 | 33 | var defacerImageResizeCoalesceSum = prometheus.NewCounter( 34 | prometheus.CounterOpts{ 35 | Name: "defacer_image_resize_coalesce_sum", 36 | Help: "Total coalesced image resizes", 37 | }, 38 | ) 39 | 40 | func init() { 41 | prometheus.MustRegister(defacerImageDefaceSum) 42 | prometheus.MustRegister(defacerImageCacheHitsSum) 43 | prometheus.MustRegister(defacerImageCacheMissSum) 44 | prometheus.MustRegister(defacerImageCacheItemsCount) 45 | prometheus.MustRegister(defacerImageResizeCoalesceSum) 46 | } 47 | -------------------------------------------------------------------------------- /apiserver/proxy.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "errors" 5 | "image" 6 | "image/gif" 7 | "image/jpeg" 8 | "image/png" 9 | "io" 10 | "log" 11 | "net/http" 12 | ) 13 | 14 | // encoderFunc is an adapter function for image encoders. 15 | type encoderFunc func(w io.Writer, m image.Image) error 16 | 17 | // proxy is the defacer http proxy. 18 | type proxy struct { 19 | Defacer Defacer 20 | Client *http.Client 21 | ErrorLog *log.Logger 22 | } 23 | 24 | // DefacerProxy does magic. 25 | func DefacerProxy(df Defacer, cli *http.Client, logger *log.Logger) http.Handler { 26 | return &proxy{ 27 | Defacer: df, 28 | Client: cli, 29 | ErrorLog: logger, 30 | } 31 | } 32 | 33 | // ServeHTTP implements the http.Handler interface. 34 | func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { 35 | if r.Method != "GET" { 36 | w.Header().Set("Allow", "GET") 37 | http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 38 | return 39 | } 40 | status, err := p.handler(w, r) 41 | if err != nil { 42 | http.Error(w, err.Error(), status) 43 | return 44 | } 45 | } 46 | 47 | // Hop-by-hop headers. These are removed when sent to the backend. 48 | // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html 49 | // 50 | // Copied from net/http/httputil. 51 | var hopHeaders = []string{ 52 | "Connection", 53 | "Keep-Alive", 54 | "Proxy-Authenticate", 55 | "Proxy-Authorization", 56 | "Te", // canonicalized version of "TE" 57 | "Trailers", 58 | "Transfer-Encoding", 59 | "Upgrade", 60 | } 61 | 62 | func (p *proxy) handler(w http.ResponseWriter, r *http.Request) (int, error) { 63 | url := r.FormValue("url") 64 | if url == "" { 65 | return http.StatusBadRequest, errors.New("Missing `url` param") 66 | } 67 | resp, err := p.req(url, r) 68 | if err != nil { 69 | return http.StatusServiceUnavailable, err 70 | } 71 | defer resp.Body.Close() 72 | // clear response headers 73 | resp.Header.Del("Content-Length") 74 | for _, hdr := range hopHeaders { 75 | resp.Header.Del(hdr) 76 | } 77 | // copy response headers 78 | for k, v := range resp.Header { 79 | w.Header()[k] = v 80 | } 81 | var enc encoderFunc 82 | switch resp.Header.Get("Content-Type") { 83 | case "image/gif": 84 | enc = func(w io.Writer, m image.Image) error { 85 | return gif.Encode(w, m, nil) 86 | } 87 | case "image/jpeg": 88 | enc = func(w io.Writer, m image.Image) error { 89 | return jpeg.Encode(w, m, nil) 90 | } 91 | case "image/png": 92 | enc = png.Encode 93 | default: 94 | io.Copy(w, resp.Body) 95 | return 0, nil 96 | } 97 | img, err := p.Defacer.Deface(resp.Body) 98 | if err != nil { 99 | return http.StatusInternalServerError, err 100 | } 101 | enc(w, img) 102 | return 0, nil 103 | } 104 | 105 | func (p *proxy) req(url string, r *http.Request) (*http.Response, error) { 106 | req, err := http.NewRequest(r.Method, url, nil) 107 | if err != nil { 108 | p.logf("failed to create request to %q: %v", url, err) 109 | return nil, err 110 | } 111 | req.Header.Set("User-Agent", r.Header.Get("User-Agent")) 112 | resp, err := p.Client.Do(req) 113 | if err != nil { 114 | p.logf("failed to exec request to %q: %v", url, err) 115 | return nil, err 116 | } 117 | return resp, nil 118 | } 119 | 120 | func (p *proxy) logf(format string, args ...interface{}) { 121 | if p.ErrorLog != nil { 122 | p.ErrorLog.Printf(format, args...) 123 | } else { 124 | log.Printf(format, args...) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /apiserver/resizer.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "image" 5 | "time" 6 | 7 | "github.com/nfnt/resize" 8 | ) 9 | 10 | // ImageResizer is an object that can resize images to a given size. 11 | type ImageResizer interface { 12 | Resize(size image.Point) image.Image 13 | } 14 | 15 | // NewImageResizer stores the given image and returns an ImageResizer 16 | // that can return different sizes of the stored image. 17 | func NewImageResizer(m image.Image) ImageResizer { 18 | ir := &imageResizer{ 19 | Image: m, 20 | Inbox: make(chan *imageResizerReq, 1000), 21 | } 22 | go ir.coalesce() 23 | return ir 24 | } 25 | 26 | type imageResizerReq struct { 27 | Size image.Point 28 | Resp chan image.Image 29 | } 30 | 31 | type imageResizer struct { 32 | Image image.Image 33 | Inbox chan *imageResizerReq 34 | } 35 | 36 | func (ir *imageResizer) Resize(size image.Point) image.Image { 37 | req := &imageResizerReq{ 38 | Size: size, 39 | Resp: make(chan image.Image), 40 | } 41 | defer close(req.Resp) 42 | ir.Inbox <- req 43 | return <-req.Resp 44 | } 45 | 46 | type imageResizerBatch map[image.Point][]chan image.Image 47 | 48 | func (ir *imageResizer) coalesce() { 49 | backoff := 10 * time.Millisecond 50 | batch := make(imageResizerBatch) 51 | for { 52 | select { 53 | case req := <-ir.Inbox: 54 | batch[req.Size] = append(batch[req.Size], req.Resp) 55 | backoff = 10 * time.Millisecond 56 | case <-time.After(backoff): 57 | if len(batch) == 0 { 58 | backoff *= backoff 59 | break 60 | } 61 | ir.dispatch(batch) 62 | batch = make(imageResizerBatch) 63 | } 64 | } 65 | } 66 | 67 | func (ir *imageResizer) dispatch(batch imageResizerBatch) { 68 | for size, resp := range batch { 69 | go ir.resize(size, resp) 70 | } 71 | batch = nil 72 | } 73 | 74 | func (ir *imageResizer) resize(size image.Point, callers []chan image.Image) { 75 | img := defaultImageCache.Get(&size) 76 | if img == nil { 77 | img = resize.Resize( 78 | uint(size.X), 79 | uint(size.Y), 80 | ir.Image, 81 | resize.Bicubic, 82 | ) 83 | defaultImageCache.Set(&size, img) 84 | } 85 | for n, resp := range callers { 86 | resp <- img 87 | if n > 0 { 88 | defacerImageResizeCoalesceSum.Inc() 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /apiserver/resizer_test.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "image" 5 | "testing" 6 | 7 | "github.com/fiorix/defacer/apiserver/internal" 8 | ) 9 | 10 | func TestImageResizer(t *testing.T) { 11 | overlay, err := internal.DefaultDefaceImage() 12 | if err != nil { 13 | t.Fatal(err) 14 | } 15 | ir := NewImageResizer(overlay) 16 | im := ir.Resize(image.Point{101, 102}) 17 | size := im.Bounds().Max 18 | if size.X != 101 || size.Y != 102 { 19 | t.Fatal("unexpected size:", size) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/fiorix/defacer/apiserver" 10 | ) 11 | 12 | func main() { 13 | httpAddr := flag.String("http", ":8080", "[ip]:port to listen on for HTTP") 14 | apiPrefix := flag.String("api-prefix", "/api", "prefix for API handlers") 15 | timeout := flag.Duration("timeout", 60*time.Second, "timeout for downloading images") 16 | nworkers := flag.Uint("workers", 50, "number of defacer workers") 17 | defaceImage := flag.String("overlay-image", "", "overlay image for the defacer") 18 | flag.Parse() 19 | handler := &apiserver.Handler{ 20 | Prefix: *apiPrefix, 21 | Workers: *nworkers, 22 | ImageFile: *defaceImage, 23 | Client: &http.Client{Timeout: *timeout}, 24 | } 25 | log.Println("Starting workers, please wait...") 26 | if err := handler.Register(http.DefaultServeMux); err != nil { 27 | log.Fatal(err) 28 | } 29 | srv := &http.Server{ 30 | Addr: *httpAddr, 31 | Handler: http.DefaultServeMux, 32 | ReadTimeout: 60 * time.Second, 33 | WriteTimeout: 60 * time.Second, 34 | } 35 | log.Println("Starting HTTP server on", *httpAddr) 36 | log.Fatal(srv.ListenAndServe()) 37 | } 38 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/LICENSE: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /vendor/github.com/golang/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 --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto 43 | make 44 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: proto3_proto/proto3.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package proto3_proto is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | proto3_proto/proto3.proto 10 | 11 | It has these top-level messages: 12 | Message 13 | Nested 14 | MessageWithMap 15 | */ 16 | package proto3_proto 17 | 18 | import proto "github.com/golang/protobuf/proto" 19 | import testdata "github.com/golang/protobuf/proto/testdata" 20 | 21 | // Reference imports to suppress errors if they are not otherwise used. 22 | var _ = proto.Marshal 23 | 24 | type Message_Humour int32 25 | 26 | const ( 27 | Message_UNKNOWN Message_Humour = 0 28 | Message_PUNS Message_Humour = 1 29 | Message_SLAPSTICK Message_Humour = 2 30 | Message_BILL_BAILEY Message_Humour = 3 31 | ) 32 | 33 | var Message_Humour_name = map[int32]string{ 34 | 0: "UNKNOWN", 35 | 1: "PUNS", 36 | 2: "SLAPSTICK", 37 | 3: "BILL_BAILEY", 38 | } 39 | var Message_Humour_value = map[string]int32{ 40 | "UNKNOWN": 0, 41 | "PUNS": 1, 42 | "SLAPSTICK": 2, 43 | "BILL_BAILEY": 3, 44 | } 45 | 46 | func (x Message_Humour) String() string { 47 | return proto.EnumName(Message_Humour_name, int32(x)) 48 | } 49 | 50 | type Message struct { 51 | Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` 52 | Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"` 53 | HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"` 54 | Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` 55 | ResultCount int64 `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"` 56 | TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"` 57 | Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"` 58 | Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"` 59 | Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"` 60 | Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` 61 | Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"` 62 | Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` 63 | } 64 | 65 | func (m *Message) Reset() { *m = Message{} } 66 | func (m *Message) String() string { return proto.CompactTextString(m) } 67 | func (*Message) ProtoMessage() {} 68 | 69 | func (m *Message) GetNested() *Nested { 70 | if m != nil { 71 | return m.Nested 72 | } 73 | return nil 74 | } 75 | 76 | func (m *Message) GetTerrain() map[string]*Nested { 77 | if m != nil { 78 | return m.Terrain 79 | } 80 | return nil 81 | } 82 | 83 | func (m *Message) GetProto2Field() *testdata.SubDefaults { 84 | if m != nil { 85 | return m.Proto2Field 86 | } 87 | return nil 88 | } 89 | 90 | func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults { 91 | if m != nil { 92 | return m.Proto2Value 93 | } 94 | return nil 95 | } 96 | 97 | type Nested struct { 98 | Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"` 99 | } 100 | 101 | func (m *Nested) Reset() { *m = Nested{} } 102 | func (m *Nested) String() string { return proto.CompactTextString(m) } 103 | func (*Nested) ProtoMessage() {} 104 | 105 | type MessageWithMap struct { 106 | ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` 107 | } 108 | 109 | func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } 110 | func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } 111 | func (*MessageWithMap) ProtoMessage() {} 112 | 113 | func (m *MessageWithMap) GetByteMapping() map[bool][]byte { 114 | if m != nil { 115 | return m.ByteMapping 116 | } 117 | return nil 118 | } 119 | 120 | func init() { 121 | proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value) 122 | } 123 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.proto: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2014 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 | syntax = "proto3"; 33 | 34 | import "testdata/test.proto"; 35 | 36 | package proto3_proto; 37 | 38 | message Message { 39 | enum Humour { 40 | UNKNOWN = 0; 41 | PUNS = 1; 42 | SLAPSTICK = 2; 43 | BILL_BAILEY = 3; 44 | } 45 | 46 | string name = 1; 47 | Humour hilarity = 2; 48 | uint32 height_in_cm = 3; 49 | bytes data = 4; 50 | int64 result_count = 7; 51 | bool true_scotsman = 8; 52 | float score = 9; 53 | 54 | repeated uint64 key = 5; 55 | Nested nested = 6; 56 | 57 | map terrain = 10; 58 | testdata.SubDefaults proto2_field = 11; 59 | map proto2_value = 13; 60 | } 61 | 62 | message Nested { 63 | string bunny = 1; 64 | } 65 | 66 | message MessageWithMap { 67 | map byte_mapping = 1; 68 | } 69 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2012 The go-opencv 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 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/cluster.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 . 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 opencv 6 | 7 | //#include "opencv.h" 8 | //#cgo linux pkg-config: opencv 9 | //#cgo darwin pkg-config: opencv 10 | //#cgo freebsd pkg-config: opencv 11 | //#cgo windows LDFLAGS: -lopencv_core242.dll -lopencv_imgproc242.dll -lopencv_photo242.dll -lopencv_highgui242.dll -lstdc++ 12 | import "C" 13 | import "unsafe" 14 | 15 | const ( 16 | /* Select random initial centers in each attempt. */ 17 | KMEANS_RANDOM_CENTERS = 0 18 | 19 | /* Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007]. */ 20 | KMEANS_PP_CENTERS = 2 21 | ) 22 | 23 | /* 24 | KMeans finds centers of k clusters in data and groups input samples around 25 | the clusters. It returns a matrix that stores the cluster indices for every 26 | sample, and a matrix that stores the cluster centers. 27 | */ 28 | func KMeans(data *Mat, k int, termcrit TermCriteria, attempts int, rng RNG, flags int) (labels, centers *Mat) { 29 | var compactness C.double 30 | 31 | labels = CreateMat(data.Rows(), 1, CV_32S) 32 | centers = CreateMat(k, 1, data.Type()) 33 | 34 | C.cvKMeans2( 35 | unsafe.Pointer(data), 36 | C.int(k), 37 | unsafe.Pointer(labels), 38 | (C.CvTermCriteria)(termcrit), 39 | C.int(attempts), 40 | (*C.CvRNG)(&rng), 41 | C.int(flags), 42 | unsafe.Pointer(centers), 43 | &compactness) 44 | 45 | return labels, centers 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/cv.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 . 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 opencv 6 | 7 | //#include "opencv.h" 8 | //#cgo linux pkg-config: opencv 9 | //#cgo darwin pkg-config: opencv 10 | //#cgo freebsd pkg-config: opencv 11 | //#cgo windows LDFLAGS: -lopencv_core242.dll -lopencv_imgproc242.dll -lopencv_photo242.dll -lopencv_highgui242.dll -lstdc++ 12 | import "C" 13 | import ( 14 | //"errors" 15 | "unsafe" 16 | ) 17 | 18 | func init() { 19 | } 20 | 21 | const ( 22 | CV_BGR2GRAY = C.CV_BGR2GRAY 23 | CV_BGR2BGRA = C.CV_BGR2BGRA 24 | CV_RGBA2BGRA = C.CV_RGBA2BGRA 25 | 26 | CV_BLUR_NO_SCALE = C.CV_BLUR_NO_SCALE 27 | CV_BLUR = C.CV_BLUR 28 | CV_GAUSSIAN = C.CV_GAUSSIAN 29 | CV_MEDIAN = C.CV_MEDIAN 30 | CV_BILATERAL = C.CV_BILATERAL 31 | 32 | CV_8U = C.CV_8U 33 | CV_8S = C.CV_8S 34 | CV_16U = C.CV_16U 35 | CV_16S = C.CV_16S 36 | CV_32S = C.CV_32S 37 | CV_32F = C.CV_32F 38 | CV_64F = C.CV_64F 39 | ) 40 | 41 | /* Smoothes array (removes noise) */ 42 | func Smooth(src, dst *IplImage, smoothtype, 43 | param1, param2 int, param3, param4 float64) { 44 | C.cvSmooth(unsafe.Pointer(src), unsafe.Pointer(dst), C.int(smoothtype), 45 | C.int(param1), C.int(param2), C.double(param3), C.double(param4), 46 | ) 47 | } 48 | 49 | //CVAPI(void) cvSmooth( const CvArr* src, CvArr* dst, 50 | // int smoothtype CV_DEFAULT(CV_GAUSSIAN), 51 | // int param1 CV_DEFAULT(3), 52 | // int param2 CV_DEFAULT(0), 53 | // double param3 CV_DEFAULT(0), 54 | // double param4 CV_DEFAULT(0)); 55 | 56 | /* 57 | ConvertScale converts one image to another with optional linear transformation. 58 | */ 59 | func ConvertScale(a, b *IplImage, scale, shift float64) { 60 | C.cvConvertScale(unsafe.Pointer(a), unsafe.Pointer(b), C.double(scale), C.double(shift)) 61 | } 62 | 63 | //CVAPI(void) cvConvertScale( const CvArr* src, 64 | // CvArr* dst, 65 | // double scale CV_DEFAULT(1), 66 | // double shift CV_DEFAULT(0) ); 67 | 68 | /* Converts input array pixels from one color space to another */ 69 | func CvtColor(src, dst *IplImage, code int) { 70 | C.cvCvtColor(unsafe.Pointer(src), unsafe.Pointer(dst), C.int(code)) 71 | } 72 | 73 | //CVAPI(void) cvCvtColor( const CvArr* src, CvArr* dst, int code ); 74 | 75 | /* Runs canny edge detector */ 76 | func Canny(image, edges *IplImage, threshold1, threshold2 float64, aperture_size int) { 77 | C.cvCanny(unsafe.Pointer(image), unsafe.Pointer(edges), 78 | C.double(threshold1), C.double(threshold2), 79 | C.int(aperture_size), 80 | ) 81 | } 82 | 83 | //CVAPI(void) cvCanny( const CvArr* image, CvArr* edges, double threshold1, 84 | // double threshold2, int aperture_size CV_DEFAULT(3) ); 85 | 86 | /* Calculates the first, second, third, or mixed image derivatives using an 87 | * extended Sobel operator. */ 88 | func Sobel(src, dst *IplImage, xorder, yorder, aperture_size int) { 89 | C.cvSobel(unsafe.Pointer(src), unsafe.Pointer(dst), 90 | C.int(xorder), C.int(yorder), 91 | C.int(aperture_size), 92 | ) 93 | } 94 | 95 | // C: void cvSobel(const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 ) 96 | 97 | const ( 98 | CV_INPAINT_NS = C.CV_INPAINT_NS 99 | CV_INPAINT_TELEA = C.CV_INPAINT_TELEA 100 | ) 101 | 102 | /* Inpaints the selected region in the image */ 103 | func Inpaint(src, inpaint_mask, dst *IplImage, inpaintRange float64, flags int) { 104 | C.cvInpaint( 105 | unsafe.Pointer(src), 106 | unsafe.Pointer(inpaint_mask), 107 | unsafe.Pointer(dst), 108 | C.double(inpaintRange), 109 | C.int(flags), 110 | ) 111 | } 112 | 113 | //CVAPI(void) cvInpaint( const CvArr* src, const CvArr* inpaint_mask, 114 | // CvArr* dst, double inpaintRange, int flags ); 115 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/cvaux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 . 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 opencv 6 | 7 | //#include "opencv.h" 8 | //#cgo linux pkg-config: opencv 9 | //#cgo darwin pkg-config: opencv 10 | //#cgo freebsd pkg-config: opencv 11 | //#cgo windows LDFLAGS: -lopencv_core242.dll -lopencv_imgproc242.dll -lopencv_photo242.dll -lopencv_highgui242.dll -lstdc++ 12 | import "C" 13 | import ( 14 | "unsafe" 15 | ) 16 | 17 | /****************************************************************************************\ 18 | * Eigen objects * 19 | \****************************************************************************************/ 20 | 21 | /****************************************************************************************\ 22 | * 1D/2D HMM * 23 | \****************************************************************************************/ 24 | 25 | /*********************************** Embedded HMMs *************************************/ 26 | 27 | /****************************************************************************************\ 28 | * A few functions from old stereo gesture recognition demosions * 29 | \****************************************************************************************/ 30 | 31 | /****************************************************************************************\ 32 | * Additional operations on Subdivisions * 33 | \****************************************************************************************/ 34 | 35 | /****************************************************************************************\ 36 | * More operations on sequences * 37 | \****************************************************************************************/ 38 | 39 | /*******************************Stereo correspondence*************************************/ 40 | 41 | /*****************************************************************************************/ 42 | /************ Epiline functions *******************/ 43 | 44 | /****************************************************************************************\ 45 | * Contour Morphing * 46 | \****************************************************************************************/ 47 | 48 | /****************************************************************************************\ 49 | * Texture Descriptors * 50 | \****************************************************************************************/ 51 | 52 | /****************************************************************************************\ 53 | * Face eyes&mouth tracking * 54 | \****************************************************************************************/ 55 | type HaarCascade struct { 56 | cascade *C.CvHaarClassifierCascade 57 | } 58 | 59 | func LoadHaarClassifierCascade(haar string) *HaarCascade { 60 | haarCascade := new(HaarCascade) 61 | haarCascade.cascade = C.cvLoadHaarClassifierCascade(C.CString(haar), C.cvSize(1, 1)) 62 | return haarCascade 63 | } 64 | 65 | func (this *HaarCascade) DetectObjects(image *IplImage) []*Rect { 66 | storage := C.cvCreateMemStorage(0) 67 | seq := C.cvHaarDetectObjects(unsafe.Pointer(image), this.cascade, storage, 1.1, 3, C.CV_HAAR_DO_CANNY_PRUNING, C.cvSize(0, 0), C.cvSize(0, 0)) 68 | var faces []*Rect 69 | for i := 0; i < (int)(seq.total); i++ { 70 | rect := (*Rect)((*_Ctype_CvRect)(unsafe.Pointer(C.cvGetSeqElem(seq, C.int(i))))) 71 | faces = append(faces, rect) 72 | } 73 | 74 | storage_c := (*C.CvMemStorage)(storage) 75 | C.cvReleaseMemStorage(&storage_c) 76 | 77 | return faces 78 | } 79 | 80 | func (this *HaarCascade) Release() { 81 | cascade_c := (*C.CvHaarClassifierCascade)(this.cascade) 82 | C.cvReleaseHaarClassifierCascade(&cascade_c) 83 | } 84 | 85 | /****************************************************************************************\ 86 | * 3D Tracker * 87 | \****************************************************************************************/ 88 | 89 | /****************************************************************************************\ 90 | * Skeletons and Linear-Contour Models * 91 | \****************************************************************************************/ 92 | 93 | /****************************************************************************************\ 94 | * Background/foreground segmentation * 95 | \****************************************************************************************/ 96 | 97 | /****************************************************************************************\ 98 | * Calibration engine * 99 | \****************************************************************************************/ 100 | 101 | /*****************************************************************************\ 102 | * --- END --- * 103 | \*****************************************************************************/ 104 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 . 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 | // Bindings for Intel's OpenCV computer vision library. 6 | package opencv 7 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/goimage.go: -------------------------------------------------------------------------------- 1 | package opencv 2 | 3 | import ( 4 | "image" 5 | "image/color" 6 | "unsafe" 7 | ) 8 | 9 | /* DecodeImageMem decodes an image from an in memory byte buffer. */ 10 | func DecodeImageMem(data []byte) *IplImage { 11 | buf := CreateMatHeader(1, len(data), CV_8U) 12 | buf.SetData(unsafe.Pointer(&data[0]), CV_AUTOSTEP) 13 | defer buf.Release() 14 | 15 | return DecodeImage(unsafe.Pointer(buf), CV_LOAD_IMAGE_UNCHANGED) 16 | } 17 | 18 | /* FromImage converts a go image.Image to an opencv.IplImage. */ 19 | func FromImage(img image.Image) *IplImage { 20 | b := img.Bounds() 21 | model := color.RGBAModel 22 | dst := CreateImage( 23 | b.Max.X-b.Min.X, 24 | b.Max.Y-b.Min.Y, 25 | IPL_DEPTH_8U, 4) 26 | 27 | for y := b.Min.Y; y < b.Max.Y; y++ { 28 | for x := b.Min.X; x < b.Max.X; x++ { 29 | px := img.At(x, y) 30 | c := model.Convert(px).(color.RGBA) 31 | 32 | value := NewScalar(float64(c.B), float64(c.G), float64(c.R), float64(c.A)) 33 | dst.Set2D(x-b.Min.X, y-b.Min.Y, value) 34 | } 35 | } 36 | 37 | return dst 38 | } 39 | 40 | /* FromImageUnsafe create an opencv.IplImage that shares the buffer with the 41 | go image.RGBA image. All changes made from opencv might affect go! */ 42 | func FromImageUnsafe(img *image.RGBA) *IplImage { 43 | b := img.Bounds() 44 | buf := CreateImageHeader( 45 | b.Max.X-b.Min.X, 46 | b.Max.Y-b.Min.Y, 47 | IPL_DEPTH_8U, 4) 48 | dst := CreateImage( 49 | b.Max.X-b.Min.X, 50 | b.Max.Y-b.Min.Y, 51 | IPL_DEPTH_8U, 4) 52 | 53 | buf.SetData(unsafe.Pointer(&img.Pix[0]), CV_AUTOSTEP) 54 | CvtColor(buf, dst, CV_RGBA2BGRA) 55 | buf.Release() 56 | 57 | return dst 58 | } 59 | 60 | /* ToImage converts a opencv.IplImage to an go image.Image */ 61 | func (img *IplImage) ToImage() image.Image { 62 | out := image.NewNRGBA(image.Rect(0, 0, img.Width(), img.Height())) 63 | if img.Depth() != IPL_DEPTH_8U { 64 | return nil // TODO return error 65 | } 66 | 67 | for y := 0; y < img.Height(); y++ { 68 | for x := 0; x < img.Width(); x++ { 69 | s := img.Get2D(x, y).Val() 70 | 71 | b, g, r := s[0], s[1], s[2] 72 | 73 | c := color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(255)} 74 | out.Set(x, y, c) 75 | } 76 | } 77 | 78 | return out 79 | } 80 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/imgproc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 . 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 opencv 6 | 7 | //#include "opencv.h" 8 | //#cgo linux pkg-config: opencv 9 | //#cgo darwin pkg-config: opencv 10 | //#cgo freebsd pkg-config: opencv 11 | //#cgo windows LDFLAGS: -lopencv_core242.dll -lopencv_imgproc242.dll -lopencv_photo242.dll -lopencv_highgui242.dll -lstdc++ 12 | import "C" 13 | import ( 14 | //"errors" 15 | //"log" 16 | "unsafe" 17 | ) 18 | 19 | const ( 20 | CV_INTER_NN = int(C.CV_INTER_NN) 21 | CV_INTER_LINEAR = int(C.CV_INTER_LINEAR) 22 | CV_INTER_CUBIC = int(C.CV_INTER_CUBIC) 23 | CV_INTER_AREA = int(C.CV_INTER_AREA) 24 | CV_INTER_LANCZOS4 = int(C.CV_INTER_LANCZOS4) 25 | ) 26 | 27 | func Resize(src *IplImage, width, height, interpolation int) *IplImage { 28 | if width == 0 && height == 0 { 29 | panic("Width and Height cannot be 0 at the same time") 30 | } 31 | if width == 0 { 32 | ratio := float64(height) / float64(src.Height()) 33 | width = int(float64(src.Width()) * ratio) 34 | } else if height == 0 { 35 | ratio := float64(width) / float64(src.Width()) 36 | height = int(float64(src.Height()) * ratio) 37 | } 38 | 39 | dst := CreateImage(width, height, src.Depth(), src.Channels()) 40 | C.cvResize(unsafe.Pointer(src), unsafe.Pointer(dst), C.int(interpolation)) 41 | return dst 42 | } 43 | 44 | func Crop(src *IplImage, x, y, width, height int) *IplImage { 45 | r := C.cvRect(C.int(x), C.int(y), C.int(width), C.int(height)) 46 | rect := Rect(r) 47 | 48 | src.SetROI(rect) 49 | dest := CreateImage(width, height, src.Depth(), src.Channels()) 50 | Copy(src, dest, nil) 51 | src.ResetROI() 52 | 53 | return dest 54 | } 55 | 56 | /* Returns a Seq of countours in an image, detected according to the parameters. 57 | Caller must Release() the Seq returned */ 58 | func (image *IplImage) FindContours(mode, method int, offset Point) *Seq { 59 | storage := C.cvCreateMemStorage(0) 60 | header_size := (C.size_t)(unsafe.Sizeof(C.CvContour{})) 61 | var seq *C.CvSeq 62 | C.cvFindContours( 63 | unsafe.Pointer(image), 64 | storage, 65 | &seq, 66 | C.int(header_size), 67 | C.int(mode), 68 | C.int(method), 69 | C.cvPoint(C.int(offset.X), C.int(offset.Y))) 70 | 71 | return (*Seq)(seq) 72 | } 73 | 74 | //cvDrawContours(CvArr* img, CvSeq* contour, CvScalar externalColor, CvScalar holeColor, int maxLevel, int thickness=1, int lineType=8 75 | func DrawContours(image *IplImage, contours *Seq, externalColor, holeColor Scalar, maxLevel, thickness, lineType int, offset Point) { 76 | C.cvDrawContours( 77 | unsafe.Pointer(image), 78 | (*C.CvSeq)(contours), 79 | (C.CvScalar)(externalColor), 80 | (C.CvScalar)(holeColor), 81 | C.int(maxLevel), 82 | C.int(thickness), 83 | C.int(lineType), 84 | C.cvPoint(C.int(offset.X), C.int(offset.Y))) 85 | } 86 | 87 | // CvSeq* cvApproxPoly(const void* src_seq, int header_size, CvMemStorage* storage, int method, double eps, int recursive=0 ) 88 | func ApproxPoly(src *Seq, header_size int, storage *MemStorage, method int, eps float64, recursive int) *Seq { 89 | seq := C.cvApproxPoly( 90 | unsafe.Pointer(src), 91 | C.int(header_size), 92 | (*C.CvMemStorage)(storage), 93 | C.int(method), 94 | C.double(eps), 95 | C.int(recursive)) 96 | return (*Seq)(seq) 97 | } 98 | 99 | // cvArcLength(const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 ) 100 | func ArcLength(curve *Seq, slice Slice, is_closed bool) float64 { 101 | is_closed_int := 0 102 | if is_closed { 103 | is_closed_int = 1 104 | } 105 | return float64(C.cvArcLength(unsafe.Pointer(curve), 106 | (C.CvSlice)(slice), 107 | C.int(is_closed_int))) 108 | } 109 | 110 | func ContourPerimeter(curve *Seq) float64 { 111 | return ArcLength(curve, WholeSeq(), true) 112 | } 113 | 114 | // double cvContourArea(const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ, int oriented=0 ) 115 | func ContourArea(contour *Seq, slice Slice, oriented int) float64 { 116 | return float64(C.cvContourArea( 117 | unsafe.Pointer(contour), 118 | (C.CvSlice)(slice), 119 | C.int(oriented))) 120 | } 121 | 122 | /* points can be either CvSeq* or CvMat* */ 123 | func FitEllipse2(points unsafe.Pointer) Box2D { 124 | box := C.cvFitEllipse2(points) 125 | center := Point2D32f{float32(box.center.x), float32(box.center.y)} 126 | size := Size2D32f{float32(box.size.width), float32(box.size.height)} 127 | angle := float32(box.angle) 128 | return Box2D{center, size, angle} 129 | } 130 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/opencv.c: -------------------------------------------------------------------------------- 1 | // Copyright 2011 . 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 | #include "opencv.h" 6 | #include "_cgo_export.h" 7 | 8 | #include 9 | #include 10 | 11 | //----------------------------------------------------------------------------- 12 | // trackbar 13 | //----------------------------------------------------------------------------- 14 | 15 | // trackbar data 16 | struct TrackbarUserdata { 17 | char* win_name; 18 | char* bar_name; 19 | int value; 20 | }; 21 | static struct TrackbarUserdata *trackbar_list[1000]; 22 | static int trackbar_list_len = 0; 23 | 24 | static void trackbarCallback(int pos, void* userdata) { 25 | struct TrackbarUserdata *arg = (struct TrackbarUserdata*)userdata; 26 | goTrackbarCallback(arg->bar_name, arg->win_name, pos); 27 | } 28 | int GoOpenCV_CreateTrackbar( 29 | char* trackbar_name, char* window_name, 30 | int value, int count 31 | ) { 32 | struct TrackbarUserdata *userdata = malloc(sizeof(*userdata)); 33 | trackbar_list[trackbar_list_len++] = userdata; 34 | 35 | userdata->win_name = (char*)window_name; 36 | userdata->bar_name = (char*)trackbar_name; 37 | userdata->value = value; 38 | 39 | return cvCreateTrackbar2(trackbar_name, window_name, 40 | &(userdata->value), count, 41 | trackbarCallback, userdata 42 | ); 43 | } 44 | void GoOpenCV_DestroyTrackbar(char* trackbar_name, char* window_name) { 45 | int i; 46 | for(i = 0; i < trackbar_list_len; ++i) { 47 | if(strcmp((char*)trackbar_list[i]->win_name, window_name)) continue; 48 | if(strcmp((char*)trackbar_list[i]->bar_name, trackbar_name)) continue; 49 | 50 | free(trackbar_list[i]); 51 | trackbar_list[i] = trackbar_list[--trackbar_list_len]; 52 | break; 53 | } 54 | } 55 | 56 | //----------------------------------------------------------------------------- 57 | // mouse callback 58 | //----------------------------------------------------------------------------- 59 | 60 | static void mouseCallback(int event, int x, int y, int flags, void* param) { 61 | char* name = (char*)param; 62 | goMouseCallback(name, event, x, y, flags); 63 | } 64 | void GoOpenCV_SetMouseCallback(const char* window_name) { 65 | cvSetMouseCallback(window_name, mouseCallback, (void*)window_name); 66 | } 67 | 68 | //----------------------------------------------------------------------------- 69 | 70 | // video writer args 71 | unsigned GoOpenCV_FOURCC_(int c1, int c2, int c3, int c4) { 72 | return (unsigned)CV_FOURCC(c1,c2,c3,c4); 73 | } 74 | 75 | //----------------------------------------------------------------------------- 76 | 77 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/opencv.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 . 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 opencv 6 | 7 | import ( 8 | // "image" 9 | ) 10 | 11 | //----------------------------------------------------------------------------- 12 | // End 13 | //----------------------------------------------------------------------------- 14 | -------------------------------------------------------------------------------- /vendor/github.com/lazywei/go-opencv/opencv/opencv.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 . 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 | // OpenCV Homepage: http://code.opencv.org 6 | 7 | #ifndef _GO_OPENCV_BINDING_H_ 8 | #define _GO_OPENCV_BINDING_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // Trackbar 18 | int GoOpenCV_CreateTrackbar( 19 | char* trackbar_name, char* window_name, 20 | int value, int count 21 | ); 22 | void GoOpenCV_DestroyTrackbar( 23 | char* trackbar_name, char* window_name 24 | ); 25 | 26 | // mouse callback 27 | void GoOpenCV_SetMouseCallback( 28 | const char* window_name 29 | ); 30 | 31 | // video writer args 32 | unsigned GoOpenCV_FOURCC_( 33 | int c1, int c2, int c3, int c4 34 | ); 35 | 36 | #endif // _GO_OPENCV_BINDING_H_ 37 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Matt T. Proud (matt.proud@gmail.com) 2 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Matt T. Proud 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pbutil 16 | 17 | import ( 18 | "encoding/binary" 19 | "errors" 20 | "io" 21 | 22 | "github.com/golang/protobuf/proto" 23 | ) 24 | 25 | var errInvalidVarint = errors.New("invalid varint32 encountered") 26 | 27 | // ReadDelimited decodes a message from the provided length-delimited stream, 28 | // where the length is encoded as 32-bit varint prefix to the message body. 29 | // It returns the total number of bytes read and any applicable error. This is 30 | // roughly equivalent to the companion Java API's 31 | // MessageLite#parseDelimitedFrom. As per the reader contract, this function 32 | // calls r.Read repeatedly as required until exactly one message including its 33 | // prefix is read and decoded (or an error has occurred). The function never 34 | // reads more bytes from the stream than required. The function never returns 35 | // an error if a message has been read and decoded correctly, even if the end 36 | // of the stream has been reached in doing so. In that case, any subsequent 37 | // calls return (0, io.EOF). 38 | func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { 39 | // Per AbstractParser#parsePartialDelimitedFrom with 40 | // CodedInputStream#readRawVarint32. 41 | headerBuf := make([]byte, binary.MaxVarintLen32) 42 | var bytesRead, varIntBytes int 43 | var messageLength uint64 44 | for varIntBytes == 0 { // i.e. no varint has been decoded yet. 45 | if bytesRead >= len(headerBuf) { 46 | return bytesRead, errInvalidVarint 47 | } 48 | // We have to read byte by byte here to avoid reading more bytes 49 | // than required. Each read byte is appended to what we have 50 | // read before. 51 | newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1]) 52 | if newBytesRead == 0 { 53 | if err != nil { 54 | return bytesRead, err 55 | } 56 | // A Reader should not return (0, nil), but if it does, 57 | // it should be treated as no-op (according to the 58 | // Reader contract). So let's go on... 59 | continue 60 | } 61 | bytesRead += newBytesRead 62 | // Now present everything read so far to the varint decoder and 63 | // see if a varint can be decoded already. 64 | messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead]) 65 | } 66 | 67 | messageBuf := make([]byte, messageLength) 68 | newBytesRead, err := io.ReadFull(r, messageBuf) 69 | bytesRead += newBytesRead 70 | if err != nil { 71 | return bytesRead, err 72 | } 73 | 74 | return bytesRead, proto.Unmarshal(messageBuf, m) 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Matt T. Proud 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package pbutil provides record length-delimited Protocol Buffer streaming. 16 | package pbutil 17 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Matt T. Proud 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pbutil 16 | 17 | import ( 18 | "encoding/binary" 19 | "io" 20 | 21 | "github.com/golang/protobuf/proto" 22 | ) 23 | 24 | // WriteDelimited encodes and dumps a message to the provided writer prefixed 25 | // with a 32-bit varint indicating the length of the encoded message, producing 26 | // a length-delimited record stream, which can be used to chain together 27 | // encoded messages of the same type together in a file. It returns the total 28 | // number of bytes written and any applicable error. This is roughly 29 | // equivalent to the companion Java API's MessageLite#writeDelimitedTo. 30 | func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) { 31 | buffer, err := proto.Marshal(m) 32 | if err != nil { 33 | return 0, err 34 | } 35 | 36 | buf := make([]byte, binary.MaxVarintLen32) 37 | encodedLength := binary.PutUvarint(buf, uint64(len(buffer))) 38 | 39 | sync, err := w.Write(buf[:encodedLength]) 40 | if err != nil { 41 | return sync, err 42 | } 43 | 44 | n, err = w.Write(buffer) 45 | return n + sync, err 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/nfnt/resize/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.1 5 | - 1.2 6 | - 1.3 7 | - tip 8 | -------------------------------------------------------------------------------- /vendor/github.com/nfnt/resize/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Jan Schlicht 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose 4 | with or without fee is hereby granted, provided that the above copyright notice 5 | and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 9 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 11 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 12 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 13 | THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /vendor/github.com/nfnt/resize/README.md: -------------------------------------------------------------------------------- 1 | Resize 2 | ====== 3 | 4 | Image resizing for the [Go programming language](http://golang.org) with common interpolation methods. 5 | 6 | [![Build Status](https://travis-ci.org/nfnt/resize.svg)](https://travis-ci.org/nfnt/resize) 7 | 8 | Installation 9 | ------------ 10 | 11 | ```bash 12 | $ go get github.com/nfnt/resize 13 | ``` 14 | 15 | It's that easy! 16 | 17 | Usage 18 | ----- 19 | 20 | This package needs at least Go 1.1. Import package with 21 | 22 | ```go 23 | import "github.com/nfnt/resize" 24 | ``` 25 | 26 | The resize package provides 2 functions: 27 | 28 | * `resize.Resize` creates a scaled image with new dimensions (`width`, `height`) using the interpolation function `interp`. 29 | If either `width` or `height` is set to 0, it will be set to an aspect ratio preserving value. 30 | * `resize.Thumbnail` downscales an image preserving its aspect ratio to the maximum dimensions (`maxWidth`, `maxHeight`). 31 | It will return the original image if original sizes are smaller than the provided dimensions. 32 | 33 | ```go 34 | resize.Resize(width, height uint, img image.Image, interp resize.InterpolationFunction) image.Image 35 | resize.Thumbnail(maxWidth, maxHeight uint, img image.Image, interp resize.InterpolationFunction) image.Image 36 | ``` 37 | 38 | The provided interpolation functions are (from fast to slow execution time) 39 | 40 | - `NearestNeighbor`: [Nearest-neighbor interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) 41 | - `Bilinear`: [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation) 42 | - `Bicubic`: [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) 43 | - `MitchellNetravali`: [Mitchell-Netravali interpolation](http://dl.acm.org/citation.cfm?id=378514) 44 | - `Lanczos2`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2 45 | - `Lanczos3`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3 46 | 47 | Which of these methods gives the best results depends on your use case. 48 | 49 | Sample usage: 50 | 51 | ```go 52 | package main 53 | 54 | import ( 55 | "github.com/nfnt/resize" 56 | "image/jpeg" 57 | "log" 58 | "os" 59 | ) 60 | 61 | func main() { 62 | // open "test.jpg" 63 | file, err := os.Open("test.jpg") 64 | if err != nil { 65 | log.Fatal(err) 66 | } 67 | 68 | // decode jpeg into image.Image 69 | img, err := jpeg.Decode(file) 70 | if err != nil { 71 | log.Fatal(err) 72 | } 73 | file.Close() 74 | 75 | // resize to width 1000 using Lanczos resampling 76 | // and preserve aspect ratio 77 | m := resize.Resize(1000, 0, img, resize.Lanczos3) 78 | 79 | out, err := os.Create("test_resized.jpg") 80 | if err != nil { 81 | log.Fatal(err) 82 | } 83 | defer out.Close() 84 | 85 | // write new image to file 86 | jpeg.Encode(out, m, nil) 87 | } 88 | ``` 89 | 90 | Caveats 91 | ------- 92 | 93 | * Optimized access routines are used for `image.RGBA`, `image.NRGBA`, `image.RGBA64`, `image.NRGBA64`, `image.YCbCr`, `image.Gray`, and `image.Gray16` types. All other image types are accessed in a generic way that will result in slow processing speed. 94 | * JPEG images are stored in `image.YCbCr`. This image format stores data in a way that will decrease processing speed. A resize may be up to 2 times slower than with `image.RGBA`. 95 | 96 | 97 | Downsizing Samples 98 | ------- 99 | 100 | Downsizing is not as simple as it might look like. Images have to be filtered before they are scaled down, otherwise aliasing might occur. 101 | Filtering is highly subjective: Applying too much will blur the whole image, too little will make aliasing become apparent. 102 | Resize tries to provide sane defaults that should suffice in most cases. 103 | 104 | ### Artificial sample 105 | 106 | Original image 107 | ![Rings](http://nfnt.github.com/img/rings_lg_orig.png) 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |

Nearest-Neighbor

Bilinear

Bicubic

Mitchell-Netravali

Lanczos2

Lanczos3
123 | 124 | ### Real-Life sample 125 | 126 | Original image 127 | ![Original](http://nfnt.github.com/img/IMG_3694_720.jpg) 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 |

Nearest-Neighbor

Bilinear

Bicubic

Mitchell-Netravali

Lanczos2

Lanczos3
143 | 144 | 145 | License 146 | ------- 147 | 148 | Copyright (c) 2012 Jan Schlicht 149 | Resize is released under a MIT style license. 150 | -------------------------------------------------------------------------------- /vendor/github.com/nfnt/resize/filters.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012, Jan Schlicht 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose 5 | with or without fee is hereby granted, provided that the above copyright notice 6 | and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 10 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 12 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 13 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 14 | THIS SOFTWARE. 15 | */ 16 | 17 | package resize 18 | 19 | import ( 20 | "math" 21 | ) 22 | 23 | func nearest(in float64) float64 { 24 | if in >= -0.5 && in < 0.5 { 25 | return 1 26 | } 27 | return 0 28 | } 29 | 30 | func linear(in float64) float64 { 31 | in = math.Abs(in) 32 | if in <= 1 { 33 | return 1 - in 34 | } 35 | return 0 36 | } 37 | 38 | func cubic(in float64) float64 { 39 | in = math.Abs(in) 40 | if in <= 1 { 41 | return in*in*(1.5*in-2.5) + 1.0 42 | } 43 | if in <= 2 { 44 | return in*(in*(2.5-0.5*in)-4.0) + 2.0 45 | } 46 | return 0 47 | } 48 | 49 | func mitchellnetravali(in float64) float64 { 50 | in = math.Abs(in) 51 | if in <= 1 { 52 | return (7.0*in*in*in - 12.0*in*in + 5.33333333333) * 0.16666666666 53 | } 54 | if in <= 2 { 55 | return (-2.33333333333*in*in*in + 12.0*in*in - 20.0*in + 10.6666666667) * 0.16666666666 56 | } 57 | return 0 58 | } 59 | 60 | func sinc(x float64) float64 { 61 | x = math.Abs(x) * math.Pi 62 | if x >= 1.220703e-4 { 63 | return math.Sin(x) / x 64 | } 65 | return 1 66 | } 67 | 68 | func lanczos2(in float64) float64 { 69 | if in > -2 && in < 2 { 70 | return sinc(in) * sinc(in*0.5) 71 | } 72 | return 0 73 | } 74 | 75 | func lanczos3(in float64) float64 { 76 | if in > -3 && in < 3 { 77 | return sinc(in) * sinc(in*0.3333333333333333) 78 | } 79 | return 0 80 | } 81 | 82 | // range [-256,256] 83 | func createWeights8(dy, filterLength int, blur, scale float64, kernel func(float64) float64) ([]int16, []int, int) { 84 | filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1)) 85 | filterFactor := math.Min(1./(blur*scale), 1) 86 | 87 | coeffs := make([]int16, dy*filterLength) 88 | start := make([]int, dy) 89 | for y := 0; y < dy; y++ { 90 | interpX := scale*(float64(y)+0.5) - 0.5 91 | start[y] = int(interpX) - filterLength/2 + 1 92 | interpX -= float64(start[y]) 93 | for i := 0; i < filterLength; i++ { 94 | in := (interpX - float64(i)) * filterFactor 95 | coeffs[y*filterLength+i] = int16(kernel(in) * 256) 96 | } 97 | } 98 | 99 | return coeffs, start, filterLength 100 | } 101 | 102 | // range [-65536,65536] 103 | func createWeights16(dy, filterLength int, blur, scale float64, kernel func(float64) float64) ([]int32, []int, int) { 104 | filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1)) 105 | filterFactor := math.Min(1./(blur*scale), 1) 106 | 107 | coeffs := make([]int32, dy*filterLength) 108 | start := make([]int, dy) 109 | for y := 0; y < dy; y++ { 110 | interpX := scale*(float64(y)+0.5) - 0.5 111 | start[y] = int(interpX) - filterLength/2 + 1 112 | interpX -= float64(start[y]) 113 | for i := 0; i < filterLength; i++ { 114 | in := (interpX - float64(i)) * filterFactor 115 | coeffs[y*filterLength+i] = int32(kernel(in) * 65536) 116 | } 117 | } 118 | 119 | return coeffs, start, filterLength 120 | } 121 | 122 | func createWeightsNearest(dy, filterLength int, blur, scale float64) ([]bool, []int, int) { 123 | filterLength = filterLength * int(math.Max(math.Ceil(blur*scale), 1)) 124 | filterFactor := math.Min(1./(blur*scale), 1) 125 | 126 | coeffs := make([]bool, dy*filterLength) 127 | start := make([]int, dy) 128 | for y := 0; y < dy; y++ { 129 | interpX := scale*(float64(y)+0.5) - 0.5 130 | start[y] = int(interpX) - filterLength/2 + 1 131 | interpX -= float64(start[y]) 132 | for i := 0; i < filterLength; i++ { 133 | in := (interpX - float64(i)) * filterFactor 134 | if in >= -0.5 && in < 0.5 { 135 | coeffs[y*filterLength+i] = true 136 | } else { 137 | coeffs[y*filterLength+i] = false 138 | } 139 | } 140 | } 141 | 142 | return coeffs, start, filterLength 143 | } 144 | -------------------------------------------------------------------------------- /vendor/github.com/nfnt/resize/thumbnail.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012, Jan Schlicht 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose 5 | with or without fee is hereby granted, provided that the above copyright notice 6 | and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 10 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 12 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 13 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 14 | THIS SOFTWARE. 15 | */ 16 | 17 | package resize 18 | 19 | import ( 20 | "image" 21 | ) 22 | 23 | // Thumbnail will downscale provided image to max width and height preserving 24 | // original aspect ratio and using the interpolation function interp. 25 | // It will return original image, without processing it, if original sizes 26 | // are already smaller than provided constraints. 27 | func Thumbnail(maxWidth, maxHeight uint, img image.Image, interp InterpolationFunction) image.Image { 28 | origBounds := img.Bounds() 29 | origWidth := uint(origBounds.Dx()) 30 | origHeight := uint(origBounds.Dy()) 31 | newWidth, newHeight := origWidth, origHeight 32 | 33 | // Return original image if it have same or smaller size as constraints 34 | if maxWidth >= origWidth && maxHeight >= origHeight { 35 | return img 36 | } 37 | 38 | // Preserve aspect ratio 39 | if origWidth > maxWidth { 40 | newHeight = uint(origHeight * maxWidth / origWidth) 41 | if newHeight < 1 { 42 | newHeight = 1 43 | } 44 | newWidth = maxWidth 45 | } 46 | 47 | if newHeight > maxHeight { 48 | newWidth = uint(newWidth * maxHeight / newHeight) 49 | if newWidth < 1 { 50 | newWidth = 1 51 | } 52 | newHeight = maxHeight 53 | } 54 | return Resize(newWidth, newHeight, img, interp) 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/NOTICE: -------------------------------------------------------------------------------- 1 | Prometheus instrumentation library for Go applications 2 | Copyright 2012-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | 7 | 8 | The following components are included in this product: 9 | 10 | goautoneg 11 | http://bitbucket.org/ww/goautoneg 12 | Copyright 2011, Open Knowledge Foundation Ltd. 13 | See README.txt for license details. 14 | 15 | perks - a fork of https://github.com/bmizerany/perks 16 | https://github.com/beorn7/perks 17 | Copyright 2013-2015 Blake Mizerany, Björn Rabenstein 18 | See https://github.com/beorn7/perks/blob/master/README.md for license details. 19 | 20 | Go support for Protocol Buffers - Google's data interchange format 21 | http://github.com/golang/protobuf/ 22 | Copyright 2010 The Go Authors 23 | See source code for license details. 24 | 25 | Support for streaming Protocol Buffer messages for the Go language (golang). 26 | https://github.com/matttproud/golang_protobuf_extensions 27 | Copyright 2013 Matt T. Proud 28 | Licensed under the Apache License, Version 2.0 29 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/.gitignore: -------------------------------------------------------------------------------- 1 | command-line-arguments.test 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | This is the [Prometheus](http://www.prometheus.io) telemetric 3 | instrumentation client [Go](http://golang.org) client library. It 4 | enable authors to define process-space metrics for their servers and 5 | expose them through a web service interface for extraction, 6 | aggregation, and a whole slew of other post processing techniques. 7 | 8 | # Installing 9 | $ go get github.com/prometheus/client_golang/prometheus 10 | 11 | # Example 12 | ```go 13 | package main 14 | 15 | import ( 16 | "net/http" 17 | 18 | "github.com/prometheus/client_golang/prometheus" 19 | ) 20 | 21 | var ( 22 | indexed = prometheus.NewCounter(prometheus.CounterOpts{ 23 | Namespace: "my_company", 24 | Subsystem: "indexer", 25 | Name: "documents_indexed", 26 | Help: "The number of documents indexed.", 27 | }) 28 | size = prometheus.NewGauge(prometheus.GaugeOpts{ 29 | Namespace: "my_company", 30 | Subsystem: "storage", 31 | Name: "documents_total_size_bytes", 32 | Help: "The total size of all documents in the storage.", 33 | }) 34 | ) 35 | 36 | func main() { 37 | http.Handle("/metrics", prometheus.Handler()) 38 | 39 | indexed.Inc() 40 | size.Set(5) 41 | 42 | http.ListenAndServe(":8080", nil) 43 | } 44 | 45 | func init() { 46 | prometheus.MustRegister(indexed) 47 | prometheus.MustRegister(size) 48 | } 49 | ``` 50 | 51 | # Documentation 52 | 53 | [![GoDoc](https://godoc.org/github.com/prometheus/client_golang?status.png)](https://godoc.org/github.com/prometheus/client_golang) 54 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/collector.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | // Collector is the interface implemented by anything that can be used by 17 | // Prometheus to collect metrics. A Collector has to be registered for 18 | // collection. See Register, MustRegister, RegisterOrGet, and MustRegisterOrGet. 19 | // 20 | // The stock metrics provided by this package (like Gauge, Counter, Summary) are 21 | // also Collectors (which only ever collect one metric, namely itself). An 22 | // implementer of Collector may, however, collect multiple metrics in a 23 | // coordinated fashion and/or create metrics on the fly. Examples for collectors 24 | // already implemented in this library are the metric vectors (i.e. collection 25 | // of multiple instances of the same Metric but with different label values) 26 | // like GaugeVec or SummaryVec, and the ExpvarCollector. 27 | type Collector interface { 28 | // Describe sends the super-set of all possible descriptors of metrics 29 | // collected by this Collector to the provided channel and returns once 30 | // the last descriptor has been sent. The sent descriptors fulfill the 31 | // consistency and uniqueness requirements described in the Desc 32 | // documentation. (It is valid if one and the same Collector sends 33 | // duplicate descriptors. Those duplicates are simply ignored. However, 34 | // two different Collectors must not send duplicate descriptors.) This 35 | // method idempotently sends the same descriptors throughout the 36 | // lifetime of the Collector. If a Collector encounters an error while 37 | // executing this method, it must send an invalid descriptor (created 38 | // with NewInvalidDesc) to signal the error to the registry. 39 | Describe(chan<- *Desc) 40 | // Collect is called by Prometheus when collecting metrics. The 41 | // implementation sends each collected metric via the provided channel 42 | // and returns once the last metric has been sent. The descriptor of 43 | // each sent metric is one of those returned by Describe. Returned 44 | // metrics that share the same descriptor must differ in their variable 45 | // label values. This method may be called concurrently and must 46 | // therefore be implemented in a concurrency safe way. Blocking occurs 47 | // at the expense of total performance of rendering all registered 48 | // metrics. Ideally, Collector implementations support concurrent 49 | // readers. 50 | Collect(chan<- Metric) 51 | } 52 | 53 | // SelfCollector implements Collector for a single Metric so that that the 54 | // Metric collects itself. Add it as an anonymous field to a struct that 55 | // implements Metric, and call Init with the Metric itself as an argument. 56 | type SelfCollector struct { 57 | self Metric 58 | } 59 | 60 | // Init provides the SelfCollector with a reference to the metric it is supposed 61 | // to collect. It is usually called within the factory function to create a 62 | // metric. See example. 63 | func (c *SelfCollector) Init(self Metric) { 64 | c.self = self 65 | } 66 | 67 | // Describe implements Collector. 68 | func (c *SelfCollector) Describe(ch chan<- *Desc) { 69 | ch <- c.self.Desc() 70 | } 71 | 72 | // Collect implements Collector. 73 | func (c *SelfCollector) Collect(ch chan<- Metric) { 74 | ch <- c.self 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package prometheus provides embeddable metric primitives for servers and 15 | // standardized exposition of telemetry through a web services interface. 16 | // 17 | // All exported functions and methods are safe to be used concurrently unless 18 | // specified otherwise. 19 | // 20 | // To expose metrics registered with the Prometheus registry, an HTTP server 21 | // needs to know about the Prometheus handler. The usual endpoint is "/metrics". 22 | // 23 | // http.Handle("/metrics", prometheus.Handler()) 24 | // 25 | // As a starting point a very basic usage example: 26 | // 27 | // package main 28 | // 29 | // import ( 30 | // "net/http" 31 | // 32 | // "github.com/prometheus/client_golang/prometheus" 33 | // ) 34 | // 35 | // var ( 36 | // cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{ 37 | // Name: "cpu_temperature_celsius", 38 | // Help: "Current temperature of the CPU.", 39 | // }) 40 | // hdFailures = prometheus.NewCounter(prometheus.CounterOpts{ 41 | // Name: "hd_errors_total", 42 | // Help: "Number of hard-disk errors.", 43 | // }) 44 | // ) 45 | // 46 | // func init() { 47 | // prometheus.MustRegister(cpuTemp) 48 | // prometheus.MustRegister(hdFailures) 49 | // } 50 | // 51 | // func main() { 52 | // cpuTemp.Set(65.3) 53 | // hdFailures.Inc() 54 | // 55 | // http.Handle("/metrics", prometheus.Handler()) 56 | // http.ListenAndServe(":8080", nil) 57 | // } 58 | // 59 | // 60 | // This is a complete program that exports two metrics, a Gauge and a Counter. 61 | // It also exports some stats about the HTTP usage of the /metrics 62 | // endpoint. (See the Handler function for more detail.) 63 | // 64 | // Two more advanced metric types are the Summary and Histogram. 65 | // 66 | // In addition to the fundamental metric types Gauge, Counter, Summary, and 67 | // Histogram, a very important part of the Prometheus data model is the 68 | // partitioning of samples along dimensions called labels, which results in 69 | // metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec, 70 | // and HistogramVec. 71 | // 72 | // Those are all the parts needed for basic usage. Detailed documentation and 73 | // examples are provided below. 74 | // 75 | // Everything else this package offers is essentially for "power users" only. A 76 | // few pointers to "power user features": 77 | // 78 | // All the various ...Opts structs have a ConstLabels field for labels that 79 | // never change their value (which is only useful under special circumstances, 80 | // see documentation of the Opts type). 81 | // 82 | // The Untyped metric behaves like a Gauge, but signals the Prometheus server 83 | // not to assume anything about its type. 84 | // 85 | // Functions to fine-tune how the metric registry works: EnableCollectChecks, 86 | // PanicOnCollectError, Register, Unregister, SetMetricFamilyInjectionHook. 87 | // 88 | // For custom metric collection, there are two entry points: Custom Metric 89 | // implementations and custom Collector implementations. A Metric is the 90 | // fundamental unit in the Prometheus data model: a sample at a point in time 91 | // together with its meta-data (like its fully-qualified name and any number of 92 | // pairs of label name and label value) that knows how to marshal itself into a 93 | // data transfer object (aka DTO, implemented as a protocol buffer). A Collector 94 | // gets registered with the Prometheus registry and manages the collection of 95 | // one or more Metrics. Many parts of this package are building blocks for 96 | // Metrics and Collectors. Desc is the metric descriptor, actually used by all 97 | // metrics under the hood, and by Collectors to describe the Metrics to be 98 | // collected, but only to be dealt with by users if they implement their own 99 | // Metrics or Collectors. To create a Desc, the BuildFQName function will come 100 | // in handy. Other useful components for Metric and Collector implementation 101 | // include: LabelPairSorter to sort the DTO version of label pairs, 102 | // NewConstMetric and MustNewConstMetric to create "throw away" Metrics at 103 | // collection time, MetricVec to bundle custom Metrics into a metric vector 104 | // Collector, SelfCollector to make a custom Metric collect itself. 105 | // 106 | // A good example for a custom Collector is the ExpVarCollector included in this 107 | // package, which exports variables exported via the "expvar" package as 108 | // Prometheus metrics. 109 | package prometheus 110 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/expvar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import ( 17 | "encoding/json" 18 | "expvar" 19 | ) 20 | 21 | // ExpvarCollector collects metrics from the expvar interface. It provides a 22 | // quick way to expose numeric values that are already exported via expvar as 23 | // Prometheus metrics. Note that the data models of expvar and Prometheus are 24 | // fundamentally different, and that the ExpvarCollector is inherently 25 | // slow. Thus, the ExpvarCollector is probably great for experiments and 26 | // prototying, but you should seriously consider a more direct implementation of 27 | // Prometheus metrics for monitoring production systems. 28 | // 29 | // Use NewExpvarCollector to create new instances. 30 | type ExpvarCollector struct { 31 | exports map[string]*Desc 32 | } 33 | 34 | // NewExpvarCollector returns a newly allocated ExpvarCollector that still has 35 | // to be registered with the Prometheus registry. 36 | // 37 | // The exports map has the following meaning: 38 | // 39 | // The keys in the map correspond to expvar keys, i.e. for every expvar key you 40 | // want to export as Prometheus metric, you need an entry in the exports 41 | // map. The descriptor mapped to each key describes how to export the expvar 42 | // value. It defines the name and the help string of the Prometheus metric 43 | // proxying the expvar value. The type will always be Untyped. 44 | // 45 | // For descriptors without variable labels, the expvar value must be a number or 46 | // a bool. The number is then directly exported as the Prometheus sample 47 | // value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values 48 | // that are not numbers or bools are silently ignored. 49 | // 50 | // If the descriptor has one variable label, the expvar value must be an expvar 51 | // map. The keys in the expvar map become the various values of the one 52 | // Prometheus label. The values in the expvar map must be numbers or bools again 53 | // as above. 54 | // 55 | // For descriptors with more than one variable label, the expvar must be a 56 | // nested expvar map, i.e. where the values of the topmost map are maps again 57 | // etc. until a depth is reached that corresponds to the number of labels. The 58 | // leaves of that structure must be numbers or bools as above to serve as the 59 | // sample values. 60 | // 61 | // Anything that does not fit into the scheme above is silently ignored. 62 | func NewExpvarCollector(exports map[string]*Desc) *ExpvarCollector { 63 | return &ExpvarCollector{ 64 | exports: exports, 65 | } 66 | } 67 | 68 | // Describe implements Collector. 69 | func (e *ExpvarCollector) Describe(ch chan<- *Desc) { 70 | for _, desc := range e.exports { 71 | ch <- desc 72 | } 73 | } 74 | 75 | // Collect implements Collector. 76 | func (e *ExpvarCollector) Collect(ch chan<- Metric) { 77 | for name, desc := range e.exports { 78 | var m Metric 79 | expVar := expvar.Get(name) 80 | if expVar == nil { 81 | continue 82 | } 83 | var v interface{} 84 | labels := make([]string, len(desc.variableLabels)) 85 | if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil { 86 | ch <- NewInvalidMetric(desc, err) 87 | continue 88 | } 89 | var processValue func(v interface{}, i int) 90 | processValue = func(v interface{}, i int) { 91 | if i >= len(labels) { 92 | copiedLabels := append(make([]string, 0, len(labels)), labels...) 93 | switch v := v.(type) { 94 | case float64: 95 | m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...) 96 | case bool: 97 | if v { 98 | m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...) 99 | } else { 100 | m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...) 101 | } 102 | default: 103 | return 104 | } 105 | ch <- m 106 | return 107 | } 108 | vm, ok := v.(map[string]interface{}) 109 | if !ok { 110 | return 111 | } 112 | for lv, val := range vm { 113 | labels[i] = lv 114 | processValue(val, i+1) 115 | } 116 | } 117 | processValue(v, 0) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/gauge.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import "hash/fnv" 17 | 18 | // Gauge is a Metric that represents a single numerical value that can 19 | // arbitrarily go up and down. 20 | // 21 | // A Gauge is typically used for measured values like temperatures or current 22 | // memory usage, but also "counts" that can go up and down, like the number of 23 | // running goroutines. 24 | // 25 | // To create Gauge instances, use NewGauge. 26 | type Gauge interface { 27 | Metric 28 | Collector 29 | 30 | // Set sets the Gauge to an arbitrary value. 31 | Set(float64) 32 | // Inc increments the Gauge by 1. 33 | Inc() 34 | // Dec decrements the Gauge by 1. 35 | Dec() 36 | // Add adds the given value to the Gauge. (The value can be 37 | // negative, resulting in a decrease of the Gauge.) 38 | Add(float64) 39 | // Sub subtracts the given value from the Gauge. (The value can be 40 | // negative, resulting in an increase of the Gauge.) 41 | Sub(float64) 42 | } 43 | 44 | // GaugeOpts is an alias for Opts. See there for doc comments. 45 | type GaugeOpts Opts 46 | 47 | // NewGauge creates a new Gauge based on the provided GaugeOpts. 48 | func NewGauge(opts GaugeOpts) Gauge { 49 | return newValue(NewDesc( 50 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 51 | opts.Help, 52 | nil, 53 | opts.ConstLabels, 54 | ), GaugeValue, 0) 55 | } 56 | 57 | // GaugeVec is a Collector that bundles a set of Gauges that all share the same 58 | // Desc, but have different values for their variable labels. This is used if 59 | // you want to count the same thing partitioned by various dimensions 60 | // (e.g. number of operations queued, partitioned by user and operation 61 | // type). Create instances with NewGaugeVec. 62 | type GaugeVec struct { 63 | MetricVec 64 | } 65 | 66 | // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and 67 | // partitioned by the given label names. At least one label name must be 68 | // provided. 69 | func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { 70 | desc := NewDesc( 71 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 72 | opts.Help, 73 | labelNames, 74 | opts.ConstLabels, 75 | ) 76 | return &GaugeVec{ 77 | MetricVec: MetricVec{ 78 | children: map[uint64]Metric{}, 79 | desc: desc, 80 | hash: fnv.New64a(), 81 | newMetric: func(lvs ...string) Metric { 82 | return newValue(desc, GaugeValue, 0, lvs...) 83 | }, 84 | }, 85 | } 86 | } 87 | 88 | // GetMetricWithLabelValues replaces the method of the same name in 89 | // MetricVec. The difference is that this method returns a Gauge and not a 90 | // Metric so that no type conversion is required. 91 | func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { 92 | metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) 93 | if metric != nil { 94 | return metric.(Gauge), err 95 | } 96 | return nil, err 97 | } 98 | 99 | // GetMetricWith replaces the method of the same name in MetricVec. The 100 | // difference is that this method returns a Gauge and not a Metric so that no 101 | // type conversion is required. 102 | func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { 103 | metric, err := m.MetricVec.GetMetricWith(labels) 104 | if metric != nil { 105 | return metric.(Gauge), err 106 | } 107 | return nil, err 108 | } 109 | 110 | // WithLabelValues works as GetMetricWithLabelValues, but panics where 111 | // GetMetricWithLabelValues would have returned an error. By not returning an 112 | // error, WithLabelValues allows shortcuts like 113 | // myVec.WithLabelValues("404", "GET").Add(42) 114 | func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge { 115 | return m.MetricVec.WithLabelValues(lvs...).(Gauge) 116 | } 117 | 118 | // With works as GetMetricWith, but panics where GetMetricWithLabels would have 119 | // returned an error. By not returning an error, With allows shortcuts like 120 | // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) 121 | func (m *GaugeVec) With(labels Labels) Gauge { 122 | return m.MetricVec.With(labels).(Gauge) 123 | } 124 | 125 | // GaugeFunc is a Gauge whose value is determined at collect time by calling a 126 | // provided function. 127 | // 128 | // To create GaugeFunc instances, use NewGaugeFunc. 129 | type GaugeFunc interface { 130 | Metric 131 | Collector 132 | } 133 | 134 | // NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The 135 | // value reported is determined by calling the given function from within the 136 | // Write method. Take into account that metric collection may happen 137 | // concurrently. If that results in concurrent calls to Write, like in the case 138 | // where a GaugeFunc is directly registered with Prometheus, the provided 139 | // function must be concurrency-safe. 140 | func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc { 141 | return newValueFunc(NewDesc( 142 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 143 | opts.Help, 144 | nil, 145 | opts.ConstLabels, 146 | ), GaugeValue, function) 147 | } 148 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/process_collector.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import "github.com/prometheus/procfs" 17 | 18 | type processCollector struct { 19 | pid int 20 | collectFn func(chan<- Metric) 21 | pidFn func() (int, error) 22 | cpuTotal Counter 23 | openFDs, maxFDs Gauge 24 | vsize, rss Gauge 25 | startTime Gauge 26 | } 27 | 28 | // NewProcessCollector returns a collector which exports the current state of 29 | // process metrics including cpu, memory and file descriptor usage as well as 30 | // the process start time for the given process id under the given namespace. 31 | func NewProcessCollector(pid int, namespace string) *processCollector { 32 | return NewProcessCollectorPIDFn( 33 | func() (int, error) { return pid, nil }, 34 | namespace, 35 | ) 36 | } 37 | 38 | // NewProcessCollectorPIDFn returns a collector which exports the current state 39 | // of process metrics including cpu, memory and file descriptor usage as well 40 | // as the process start time under the given namespace. The given pidFn is 41 | // called on each collect and is used to determine the process to export 42 | // metrics for. 43 | func NewProcessCollectorPIDFn( 44 | pidFn func() (int, error), 45 | namespace string, 46 | ) *processCollector { 47 | c := processCollector{ 48 | pidFn: pidFn, 49 | collectFn: func(chan<- Metric) {}, 50 | 51 | cpuTotal: NewCounter(CounterOpts{ 52 | Namespace: namespace, 53 | Name: "process_cpu_seconds_total", 54 | Help: "Total user and system CPU time spent in seconds.", 55 | }), 56 | openFDs: NewGauge(GaugeOpts{ 57 | Namespace: namespace, 58 | Name: "process_open_fds", 59 | Help: "Number of open file descriptors.", 60 | }), 61 | maxFDs: NewGauge(GaugeOpts{ 62 | Namespace: namespace, 63 | Name: "process_max_fds", 64 | Help: "Maximum number of open file descriptors.", 65 | }), 66 | vsize: NewGauge(GaugeOpts{ 67 | Namespace: namespace, 68 | Name: "process_virtual_memory_bytes", 69 | Help: "Virtual memory size in bytes.", 70 | }), 71 | rss: NewGauge(GaugeOpts{ 72 | Namespace: namespace, 73 | Name: "process_resident_memory_bytes", 74 | Help: "Resident memory size in bytes.", 75 | }), 76 | startTime: NewGauge(GaugeOpts{ 77 | Namespace: namespace, 78 | Name: "process_start_time_seconds", 79 | Help: "Start time of the process since unix epoch in seconds.", 80 | }), 81 | } 82 | 83 | // Set up process metric collection if supported by the runtime. 84 | if _, err := procfs.NewStat(); err == nil { 85 | c.collectFn = c.processCollect 86 | } 87 | 88 | return &c 89 | } 90 | 91 | // Describe returns all descriptions of the collector. 92 | func (c *processCollector) Describe(ch chan<- *Desc) { 93 | ch <- c.cpuTotal.Desc() 94 | ch <- c.openFDs.Desc() 95 | ch <- c.maxFDs.Desc() 96 | ch <- c.vsize.Desc() 97 | ch <- c.rss.Desc() 98 | ch <- c.startTime.Desc() 99 | } 100 | 101 | // Collect returns the current state of all metrics of the collector. 102 | func (c *processCollector) Collect(ch chan<- Metric) { 103 | c.collectFn(ch) 104 | } 105 | 106 | // TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the 107 | // client allows users to configure the error behavior. 108 | func (c *processCollector) processCollect(ch chan<- Metric) { 109 | pid, err := c.pidFn() 110 | if err != nil { 111 | return 112 | } 113 | 114 | p, err := procfs.NewProc(pid) 115 | if err != nil { 116 | return 117 | } 118 | 119 | if stat, err := p.NewStat(); err == nil { 120 | c.cpuTotal.Set(stat.CPUTime()) 121 | ch <- c.cpuTotal 122 | c.vsize.Set(float64(stat.VirtualMemory())) 123 | ch <- c.vsize 124 | c.rss.Set(float64(stat.ResidentMemory())) 125 | ch <- c.rss 126 | 127 | if startTime, err := stat.StartTime(); err == nil { 128 | c.startTime.Set(startTime) 129 | ch <- c.startTime 130 | } 131 | } 132 | 133 | if fds, err := p.FileDescriptorsLen(); err == nil { 134 | c.openFDs.Set(float64(fds)) 135 | ch <- c.openFDs 136 | } 137 | 138 | if limits, err := p.NewLimits(); err == nil { 139 | c.maxFDs.Set(float64(limits.OpenFiles)) 140 | ch <- c.maxFDs 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/push.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Copyright (c) 2013, The Prometheus Authors 15 | // All rights reserved. 16 | // 17 | // Use of this source code is governed by a BSD-style license that can be found 18 | // in the LICENSE file. 19 | 20 | package prometheus 21 | 22 | // Push triggers a metric collection by the default registry and pushes all 23 | // collected metrics to the Pushgateway specified by addr. See the Pushgateway 24 | // documentation for detailed implications of the job and instance 25 | // parameter. instance can be left empty. You can use just host:port or ip:port 26 | // as url, in which case 'http://' is added automatically. You can also include 27 | // the schema in the URL. However, do not include the '/metrics/jobs/...' part. 28 | // 29 | // Note that all previously pushed metrics with the same job and instance will 30 | // be replaced with the metrics pushed by this call. (It uses HTTP method 'PUT' 31 | // to push to the Pushgateway.) 32 | func Push(job, instance, url string) error { 33 | return defRegistry.Push(job, instance, url, "PUT") 34 | } 35 | 36 | // PushAdd works like Push, but only previously pushed metrics with the same 37 | // name (and the same job and instance) will be replaced. (It uses HTTP method 38 | // 'POST' to push to the Pushgateway.) 39 | func PushAdd(job, instance, url string) error { 40 | return defRegistry.Push(job, instance, url, "POST") 41 | } 42 | 43 | // PushCollectors works like Push, but it does not collect from the default 44 | // registry. Instead, it collects from the provided collectors. It is a 45 | // convenient way to push only a few metrics. 46 | func PushCollectors(job, instance, url string, collectors ...Collector) error { 47 | return pushCollectors(job, instance, url, "PUT", collectors...) 48 | } 49 | 50 | // PushAddCollectors works like PushAdd, but it does not collect from the 51 | // default registry. Instead, it collects from the provided collectors. It is a 52 | // convenient way to push only a few metrics. 53 | func PushAddCollectors(job, instance, url string, collectors ...Collector) error { 54 | return pushCollectors(job, instance, url, "POST", collectors...) 55 | } 56 | 57 | func pushCollectors(job, instance, url, method string, collectors ...Collector) error { 58 | r := newRegistry() 59 | for _, collector := range collectors { 60 | if _, err := r.Register(collector); err != nil { 61 | return err 62 | } 63 | } 64 | return r.Push(job, instance, url, method) 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/untyped.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import "hash/fnv" 17 | 18 | // Untyped is a Metric that represents a single numerical value that can 19 | // arbitrarily go up and down. 20 | // 21 | // An Untyped metric works the same as a Gauge. The only difference is that to 22 | // no type information is implied. 23 | // 24 | // To create Untyped instances, use NewUntyped. 25 | type Untyped interface { 26 | Metric 27 | Collector 28 | 29 | // Set sets the Untyped metric to an arbitrary value. 30 | Set(float64) 31 | // Inc increments the Untyped metric by 1. 32 | Inc() 33 | // Dec decrements the Untyped metric by 1. 34 | Dec() 35 | // Add adds the given value to the Untyped metric. (The value can be 36 | // negative, resulting in a decrease.) 37 | Add(float64) 38 | // Sub subtracts the given value from the Untyped metric. (The value can 39 | // be negative, resulting in an increase.) 40 | Sub(float64) 41 | } 42 | 43 | // UntypedOpts is an alias for Opts. See there for doc comments. 44 | type UntypedOpts Opts 45 | 46 | // NewUntyped creates a new Untyped metric from the provided UntypedOpts. 47 | func NewUntyped(opts UntypedOpts) Untyped { 48 | return newValue(NewDesc( 49 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 50 | opts.Help, 51 | nil, 52 | opts.ConstLabels, 53 | ), UntypedValue, 0) 54 | } 55 | 56 | // UntypedVec is a Collector that bundles a set of Untyped metrics that all 57 | // share the same Desc, but have different values for their variable 58 | // labels. This is used if you want to count the same thing partitioned by 59 | // various dimensions. Create instances with NewUntypedVec. 60 | type UntypedVec struct { 61 | MetricVec 62 | } 63 | 64 | // NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and 65 | // partitioned by the given label names. At least one label name must be 66 | // provided. 67 | func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec { 68 | desc := NewDesc( 69 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 70 | opts.Help, 71 | labelNames, 72 | opts.ConstLabels, 73 | ) 74 | return &UntypedVec{ 75 | MetricVec: MetricVec{ 76 | children: map[uint64]Metric{}, 77 | desc: desc, 78 | hash: fnv.New64a(), 79 | newMetric: func(lvs ...string) Metric { 80 | return newValue(desc, UntypedValue, 0, lvs...) 81 | }, 82 | }, 83 | } 84 | } 85 | 86 | // GetMetricWithLabelValues replaces the method of the same name in 87 | // MetricVec. The difference is that this method returns an Untyped and not a 88 | // Metric so that no type conversion is required. 89 | func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error) { 90 | metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) 91 | if metric != nil { 92 | return metric.(Untyped), err 93 | } 94 | return nil, err 95 | } 96 | 97 | // GetMetricWith replaces the method of the same name in MetricVec. The 98 | // difference is that this method returns an Untyped and not a Metric so that no 99 | // type conversion is required. 100 | func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) { 101 | metric, err := m.MetricVec.GetMetricWith(labels) 102 | if metric != nil { 103 | return metric.(Untyped), err 104 | } 105 | return nil, err 106 | } 107 | 108 | // WithLabelValues works as GetMetricWithLabelValues, but panics where 109 | // GetMetricWithLabelValues would have returned an error. By not returning an 110 | // error, WithLabelValues allows shortcuts like 111 | // myVec.WithLabelValues("404", "GET").Add(42) 112 | func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped { 113 | return m.MetricVec.WithLabelValues(lvs...).(Untyped) 114 | } 115 | 116 | // With works as GetMetricWith, but panics where GetMetricWithLabels would have 117 | // returned an error. By not returning an error, With allows shortcuts like 118 | // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) 119 | func (m *UntypedVec) With(labels Labels) Untyped { 120 | return m.MetricVec.With(labels).(Untyped) 121 | } 122 | 123 | // UntypedFunc is an Untyped whose value is determined at collect time by 124 | // calling a provided function. 125 | // 126 | // To create UntypedFunc instances, use NewUntypedFunc. 127 | type UntypedFunc interface { 128 | Metric 129 | Collector 130 | } 131 | 132 | // NewUntypedFunc creates a new UntypedFunc based on the provided 133 | // UntypedOpts. The value reported is determined by calling the given function 134 | // from within the Write method. Take into account that metric collection may 135 | // happen concurrently. If that results in concurrent calls to Write, like in 136 | // the case where an UntypedFunc is directly registered with Prometheus, the 137 | // provided function must be concurrency-safe. 138 | func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc { 139 | return newValueFunc(NewDesc( 140 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 141 | opts.Help, 142 | nil, 143 | opts.ConstLabels, 144 | ), UntypedValue, function) 145 | } 146 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_model/NOTICE: -------------------------------------------------------------------------------- 1 | Data model artifacts for Prometheus. 2 | Copyright 2012-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/NOTICE: -------------------------------------------------------------------------------- 1 | Common libraries shared by Prometheus Go components. 2 | Copyright 2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/encode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package expfmt 15 | 16 | import ( 17 | "fmt" 18 | "io" 19 | "net/http" 20 | 21 | "github.com/golang/protobuf/proto" 22 | "github.com/matttproud/golang_protobuf_extensions/pbutil" 23 | "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" 24 | 25 | dto "github.com/prometheus/client_model/go" 26 | ) 27 | 28 | // Encoder types encode metric families into an underlying wire protocol. 29 | type Encoder interface { 30 | Encode(*dto.MetricFamily) error 31 | } 32 | 33 | type encoder func(*dto.MetricFamily) error 34 | 35 | func (e encoder) Encode(v *dto.MetricFamily) error { 36 | return e(v) 37 | } 38 | 39 | // Negotiate returns the Content-Type based on the given Accept header. 40 | // If no appropriate accepted type is found, FmtText is returned. 41 | func Negotiate(h http.Header) Format { 42 | for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) { 43 | // Check for protocol buffer 44 | if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { 45 | switch ac.Params["encoding"] { 46 | case "delimited": 47 | return FmtProtoDelim 48 | case "text": 49 | return FmtProtoText 50 | case "compact-text": 51 | return FmtProtoCompact 52 | } 53 | } 54 | // Check for text format. 55 | ver := ac.Params["version"] 56 | if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { 57 | return FmtText 58 | } 59 | } 60 | return FmtText 61 | } 62 | 63 | // NewEncoder returns a new encoder based on content type negotiation. 64 | func NewEncoder(w io.Writer, format Format) Encoder { 65 | switch format { 66 | case FmtProtoDelim: 67 | return encoder(func(v *dto.MetricFamily) error { 68 | _, err := pbutil.WriteDelimited(w, v) 69 | return err 70 | }) 71 | case FmtProtoCompact: 72 | return encoder(func(v *dto.MetricFamily) error { 73 | _, err := fmt.Fprintln(w, v.String()) 74 | return err 75 | }) 76 | case FmtProtoText: 77 | return encoder(func(v *dto.MetricFamily) error { 78 | _, err := fmt.Fprintln(w, proto.MarshalTextString(v)) 79 | return err 80 | }) 81 | case FmtText: 82 | return encoder(func(v *dto.MetricFamily) error { 83 | _, err := MetricFamilyToText(w, v) 84 | return err 85 | }) 86 | } 87 | panic("expfmt.NewEncoder: unknown format") 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/expfmt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // A package for reading and writing Prometheus metrics. 15 | package expfmt 16 | 17 | type Format string 18 | 19 | const ( 20 | TextVersion = "0.0.4" 21 | 22 | ProtoType = `application/vnd.google.protobuf` 23 | ProtoProtocol = `io.prometheus.client.MetricFamily` 24 | ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" 25 | 26 | // The Content-Type values for the different wire protocols. 27 | FmtUnknown Format = `` 28 | FmtText Format = `text/plain; version=` + TextVersion 29 | FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` 30 | FmtProtoText Format = ProtoFmt + ` encoding=text` 31 | FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` 32 | 33 | // fmtJSON2 is hidden as it is deprecated. 34 | fmtJSON2 Format = `application/json; version=0.0.2` 35 | ) 36 | 37 | const ( 38 | hdrContentType = "Content-Type" 39 | hdrAccept = "Accept" 40 | ) 41 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Build only when actually fuzzing 15 | // +build gofuzz 16 | 17 | package expfmt 18 | 19 | import "bytes" 20 | 21 | // Fuzz text metric parser with with github.com/dvyukov/go-fuzz: 22 | // 23 | // go-fuzz-build github.com/prometheus/client_golang/text 24 | // go-fuzz -bin text-fuzz.zip -workdir fuzz 25 | // 26 | // Further input samples should go in the folder fuzz/corpus. 27 | func Fuzz(in []byte) int { 28 | parser := TextParser{} 29 | _, err := parser.TextToMetricFamilies(bytes.NewReader(in)) 30 | 31 | if err != nil { 32 | return 0 33 | } 34 | 35 | return 1 36 | } 37 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_0: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_1: -------------------------------------------------------------------------------- 1 | 2 | minimal_metric 1.234 3 | another_metric -3e3 103948 4 | # Even that: 5 | no_labels{} 3 6 | # HELP line for non-existing metric will be ignored. 7 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_2: -------------------------------------------------------------------------------- 1 | 2 | # A normal comment. 3 | # 4 | # TYPE name counter 5 | name{labelname="val1",basename="basevalue"} NaN 6 | name {labelname="val2",basename="base\"v\\al\nue"} 0.23 1234567890 7 | # HELP name two-line\n doc str\\ing 8 | 9 | # HELP name2 doc str"ing 2 10 | # TYPE name2 gauge 11 | name2{labelname="val2" ,basename = "basevalue2" } +Inf 54321 12 | name2{ labelname = "val1" , }-Inf 13 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_3: -------------------------------------------------------------------------------- 1 | 2 | # TYPE my_summary summary 3 | my_summary{n1="val1",quantile="0.5"} 110 4 | decoy -1 -2 5 | my_summary{n1="val1",quantile="0.9"} 140 1 6 | my_summary_count{n1="val1"} 42 7 | # Latest timestamp wins in case of a summary. 8 | my_summary_sum{n1="val1"} 4711 2 9 | fake_sum{n1="val1"} 2001 10 | # TYPE another_summary summary 11 | another_summary_count{n2="val2",n1="val1"} 20 12 | my_summary_count{n2="val2",n1="val1"} 5 5 13 | another_summary{n1="val1",n2="val2",quantile=".3"} -1.2 14 | my_summary_sum{n1="val2"} 08 15 15 | my_summary{n1="val3", quantile="0.2"} 4711 16 | my_summary{n1="val1",n2="val2",quantile="-12.34",} NaN 17 | # some 18 | # funny comments 19 | # HELP 20 | # HELP 21 | # HELP my_summary 22 | # HELP my_summary 23 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_4: -------------------------------------------------------------------------------- 1 | 2 | # HELP request_duration_microseconds The response latency. 3 | # TYPE request_duration_microseconds histogram 4 | request_duration_microseconds_bucket{le="100"} 123 5 | request_duration_microseconds_bucket{le="120"} 412 6 | request_duration_microseconds_bucket{le="144"} 592 7 | request_duration_microseconds_bucket{le="172.8"} 1524 8 | request_duration_microseconds_bucket{le="+Inf"} 2693 9 | request_duration_microseconds_sum 1.7560473e+06 10 | request_duration_microseconds_count 2693 11 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_0: -------------------------------------------------------------------------------- 1 | bla 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_1: -------------------------------------------------------------------------------- 1 | metric{label="\t"} 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_10: -------------------------------------------------------------------------------- 1 | metric{label="bla"} 3.14 2 3 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_11: -------------------------------------------------------------------------------- 1 | metric{label="bla"} blubb 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_12: -------------------------------------------------------------------------------- 1 | 2 | # HELP metric one 3 | # HELP metric two 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_13: -------------------------------------------------------------------------------- 1 | 2 | # TYPE metric counter 3 | # TYPE metric untyped 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_14: -------------------------------------------------------------------------------- 1 | 2 | metric 4.12 3 | # TYPE metric counter 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_15: -------------------------------------------------------------------------------- 1 | 2 | # TYPE metric bla 3 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_16: -------------------------------------------------------------------------------- 1 | 2 | # TYPE met-ric 3 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_17: -------------------------------------------------------------------------------- 1 | @invalidmetric{label="bla"} 3.14 2 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_18: -------------------------------------------------------------------------------- 1 | {label="bla"} 3.14 2 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_19: -------------------------------------------------------------------------------- 1 | 2 | # TYPE metric histogram 3 | metric_bucket{le="bla"} 3.14 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_2: -------------------------------------------------------------------------------- 1 | 2 | metric{label="new 3 | line"} 3.14 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_3: -------------------------------------------------------------------------------- 1 | metric{@="bla"} 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_4: -------------------------------------------------------------------------------- 1 | metric{__name__="bla"} 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_5: -------------------------------------------------------------------------------- 1 | metric{label+="bla"} 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_6: -------------------------------------------------------------------------------- 1 | metric{label=bla} 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_7: -------------------------------------------------------------------------------- 1 | 2 | # TYPE metric summary 3 | metric{quantile="bla"} 3.14 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_8: -------------------------------------------------------------------------------- 1 | metric{label="bla"+} 3.14 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/from_test_parse_error_9: -------------------------------------------------------------------------------- 1 | metric{label="bla"} 3.14 2.72 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz/corpus/minimal: -------------------------------------------------------------------------------- 1 | m{} 0 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/json_decode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package expfmt 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "io" 20 | "sort" 21 | 22 | "github.com/golang/protobuf/proto" 23 | dto "github.com/prometheus/client_model/go" 24 | 25 | "github.com/prometheus/common/model" 26 | ) 27 | 28 | type json2Decoder struct { 29 | dec *json.Decoder 30 | fams []*dto.MetricFamily 31 | } 32 | 33 | func newJSON2Decoder(r io.Reader) Decoder { 34 | return &json2Decoder{ 35 | dec: json.NewDecoder(r), 36 | } 37 | } 38 | 39 | type histogram002 struct { 40 | Labels model.LabelSet `json:"labels"` 41 | Values map[string]float64 `json:"value"` 42 | } 43 | 44 | type counter002 struct { 45 | Labels model.LabelSet `json:"labels"` 46 | Value float64 `json:"value"` 47 | } 48 | 49 | func protoLabelSet(base, ext model.LabelSet) []*dto.LabelPair { 50 | labels := base.Clone().Merge(ext) 51 | delete(labels, model.MetricNameLabel) 52 | 53 | names := make([]string, 0, len(labels)) 54 | for ln := range labels { 55 | names = append(names, string(ln)) 56 | } 57 | sort.Strings(names) 58 | 59 | pairs := make([]*dto.LabelPair, 0, len(labels)) 60 | 61 | for _, ln := range names { 62 | lv := labels[model.LabelName(ln)] 63 | 64 | pairs = append(pairs, &dto.LabelPair{ 65 | Name: proto.String(ln), 66 | Value: proto.String(string(lv)), 67 | }) 68 | } 69 | 70 | return pairs 71 | } 72 | 73 | func (d *json2Decoder) more() error { 74 | var entities []struct { 75 | BaseLabels model.LabelSet `json:"baseLabels"` 76 | Docstring string `json:"docstring"` 77 | Metric struct { 78 | Type string `json:"type"` 79 | Values json.RawMessage `json:"value"` 80 | } `json:"metric"` 81 | } 82 | 83 | if err := d.dec.Decode(&entities); err != nil { 84 | return err 85 | } 86 | for _, e := range entities { 87 | f := &dto.MetricFamily{ 88 | Name: proto.String(string(e.BaseLabels[model.MetricNameLabel])), 89 | Help: proto.String(e.Docstring), 90 | Type: dto.MetricType_UNTYPED.Enum(), 91 | Metric: []*dto.Metric{}, 92 | } 93 | 94 | d.fams = append(d.fams, f) 95 | 96 | switch e.Metric.Type { 97 | case "counter", "gauge": 98 | var values []counter002 99 | 100 | if err := json.Unmarshal(e.Metric.Values, &values); err != nil { 101 | return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err) 102 | } 103 | 104 | for _, ctr := range values { 105 | f.Metric = append(f.Metric, &dto.Metric{ 106 | Label: protoLabelSet(e.BaseLabels, ctr.Labels), 107 | Untyped: &dto.Untyped{ 108 | Value: proto.Float64(ctr.Value), 109 | }, 110 | }) 111 | } 112 | 113 | case "histogram": 114 | var values []histogram002 115 | 116 | if err := json.Unmarshal(e.Metric.Values, &values); err != nil { 117 | return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err) 118 | } 119 | 120 | for _, hist := range values { 121 | quants := make([]string, 0, len(values)) 122 | for q := range hist.Values { 123 | quants = append(quants, q) 124 | } 125 | 126 | sort.Strings(quants) 127 | 128 | for _, q := range quants { 129 | value := hist.Values[q] 130 | // The correct label is "quantile" but to not break old expressions 131 | // this remains "percentile" 132 | hist.Labels["percentile"] = model.LabelValue(q) 133 | 134 | f.Metric = append(f.Metric, &dto.Metric{ 135 | Label: protoLabelSet(e.BaseLabels, hist.Labels), 136 | Untyped: &dto.Untyped{ 137 | Value: proto.Float64(value), 138 | }, 139 | }) 140 | } 141 | } 142 | 143 | default: 144 | return fmt.Errorf("unknown metric type %q", e.Metric.Type) 145 | } 146 | } 147 | return nil 148 | } 149 | 150 | // Decode implements the Decoder interface. 151 | func (d *json2Decoder) Decode(v *dto.MetricFamily) error { 152 | if len(d.fams) == 0 { 153 | if err := d.more(); err != nil { 154 | return err 155 | } 156 | } 157 | 158 | *v = *d.fams[0] 159 | d.fams = d.fams[1:] 160 | 161 | return nil 162 | } 163 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt: -------------------------------------------------------------------------------- 1 | PACKAGE 2 | 3 | package goautoneg 4 | import "bitbucket.org/ww/goautoneg" 5 | 6 | HTTP Content-Type Autonegotiation. 7 | 8 | The functions in this package implement the behaviour specified in 9 | http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 10 | 11 | Copyright (c) 2011, Open Knowledge Foundation Ltd. 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are 16 | met: 17 | 18 | Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | 21 | Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the 24 | distribution. 25 | 26 | Neither the name of the Open Knowledge Foundation Ltd. nor the 27 | names of its contributors may be used to endorse or promote 28 | products derived from this software without specific prior written 29 | permission. 30 | 31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | 43 | 44 | FUNCTIONS 45 | 46 | func Negotiate(header string, alternatives []string) (content_type string) 47 | Negotiate the most appropriate content_type given the accept header 48 | and a list of alternatives. 49 | 50 | func ParseAccept(header string) (accept []Accept) 51 | Parse an Accept Header string returning a sorted list 52 | of clauses 53 | 54 | 55 | TYPES 56 | 57 | type Accept struct { 58 | Type, SubType string 59 | Q float32 60 | Params map[string]string 61 | } 62 | Structure to represent a clause in an HTTP Accept Header 63 | 64 | 65 | SUBDIRECTORIES 66 | 67 | .hg 68 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go: -------------------------------------------------------------------------------- 1 | /* 2 | HTTP Content-Type Autonegotiation. 3 | 4 | The functions in this package implement the behaviour specified in 5 | http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 6 | 7 | Copyright (c) 2011, Open Knowledge Foundation Ltd. 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are 12 | met: 13 | 14 | Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | Neither the name of the Open Knowledge Foundation Ltd. nor the 23 | names of its contributors may be used to endorse or promote 24 | products derived from this software without specific prior written 25 | permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | 40 | */ 41 | package goautoneg 42 | 43 | import ( 44 | "sort" 45 | "strconv" 46 | "strings" 47 | ) 48 | 49 | // Structure to represent a clause in an HTTP Accept Header 50 | type Accept struct { 51 | Type, SubType string 52 | Q float64 53 | Params map[string]string 54 | } 55 | 56 | // For internal use, so that we can use the sort interface 57 | type accept_slice []Accept 58 | 59 | func (accept accept_slice) Len() int { 60 | slice := []Accept(accept) 61 | return len(slice) 62 | } 63 | 64 | func (accept accept_slice) Less(i, j int) bool { 65 | slice := []Accept(accept) 66 | ai, aj := slice[i], slice[j] 67 | if ai.Q > aj.Q { 68 | return true 69 | } 70 | if ai.Type != "*" && aj.Type == "*" { 71 | return true 72 | } 73 | if ai.SubType != "*" && aj.SubType == "*" { 74 | return true 75 | } 76 | return false 77 | } 78 | 79 | func (accept accept_slice) Swap(i, j int) { 80 | slice := []Accept(accept) 81 | slice[i], slice[j] = slice[j], slice[i] 82 | } 83 | 84 | // Parse an Accept Header string returning a sorted list 85 | // of clauses 86 | func ParseAccept(header string) (accept []Accept) { 87 | parts := strings.Split(header, ",") 88 | accept = make([]Accept, 0, len(parts)) 89 | for _, part := range parts { 90 | part := strings.Trim(part, " ") 91 | 92 | a := Accept{} 93 | a.Params = make(map[string]string) 94 | a.Q = 1.0 95 | 96 | mrp := strings.Split(part, ";") 97 | 98 | media_range := mrp[0] 99 | sp := strings.Split(media_range, "/") 100 | a.Type = strings.Trim(sp[0], " ") 101 | 102 | switch { 103 | case len(sp) == 1 && a.Type == "*": 104 | a.SubType = "*" 105 | case len(sp) == 2: 106 | a.SubType = strings.Trim(sp[1], " ") 107 | default: 108 | continue 109 | } 110 | 111 | if len(mrp) == 1 { 112 | accept = append(accept, a) 113 | continue 114 | } 115 | 116 | for _, param := range mrp[1:] { 117 | sp := strings.SplitN(param, "=", 2) 118 | if len(sp) != 2 { 119 | continue 120 | } 121 | token := strings.Trim(sp[0], " ") 122 | if token == "q" { 123 | a.Q, _ = strconv.ParseFloat(sp[1], 32) 124 | } else { 125 | a.Params[token] = strings.Trim(sp[1], " ") 126 | } 127 | } 128 | 129 | accept = append(accept, a) 130 | } 131 | 132 | slice := accept_slice(accept) 133 | sort.Sort(slice) 134 | 135 | return 136 | } 137 | 138 | // Negotiate the most appropriate content_type given the accept header 139 | // and a list of alternatives. 140 | func Negotiate(header string, alternatives []string) (content_type string) { 141 | asp := make([][]string, 0, len(alternatives)) 142 | for _, ctype := range alternatives { 143 | asp = append(asp, strings.SplitN(ctype, "/", 2)) 144 | } 145 | for _, clause := range ParseAccept(header) { 146 | for i, ctsp := range asp { 147 | if clause.Type == ctsp[0] && clause.SubType == ctsp[1] { 148 | content_type = alternatives[i] 149 | return 150 | } 151 | if clause.Type == ctsp[0] && clause.SubType == "*" { 152 | content_type = alternatives[i] 153 | return 154 | } 155 | if clause.Type == "*" && clause.SubType == "*" { 156 | content_type = alternatives[i] 157 | return 158 | } 159 | } 160 | } 161 | return 162 | } 163 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/alert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "time" 19 | ) 20 | 21 | type AlertStatus string 22 | 23 | const ( 24 | AlertFiring AlertStatus = "firing" 25 | AlertResolved AlertStatus = "resolved" 26 | ) 27 | 28 | // Alert is a generic representation of an alert in the Prometheus eco-system. 29 | type Alert struct { 30 | // Label value pairs for purpose of aggregation, matching, and disposition 31 | // dispatching. This must minimally include an "alertname" label. 32 | Labels LabelSet `json:"labels"` 33 | 34 | // Extra key/value information which does not define alert identity. 35 | Annotations LabelSet `json:"annotations"` 36 | 37 | // The known time range for this alert. Both ends are optional. 38 | StartsAt time.Time `json:"startsAt,omitempty"` 39 | EndsAt time.Time `json:"endsAt,omitempty"` 40 | } 41 | 42 | // Name returns the name of the alert. It is equivalent to the "alertname" label. 43 | func (a *Alert) Name() string { 44 | return string(a.Labels[AlertNameLabel]) 45 | } 46 | 47 | // Fingerprint returns a unique hash for the alert. It is equivalent to 48 | // the fingerprint of the alert's label set. 49 | func (a *Alert) Fingerprint() Fingerprint { 50 | return a.Labels.Fingerprint() 51 | } 52 | 53 | func (a *Alert) String() string { 54 | s := fmt.Sprintf("%s[%s]", a.Name(), a.Fingerprint().String()[:7]) 55 | if a.Resolved() { 56 | return s + "[resolved]" 57 | } 58 | return s + "[active]" 59 | } 60 | 61 | // Resolved returns true iff the activity interval ended in the past. 62 | func (a *Alert) Resolved() bool { 63 | if a.EndsAt.IsZero() { 64 | return false 65 | } 66 | return !a.EndsAt.After(time.Now()) 67 | } 68 | 69 | // Status returns the status of the alert. 70 | func (a *Alert) Status() AlertStatus { 71 | if a.Resolved() { 72 | return AlertResolved 73 | } 74 | return AlertFiring 75 | } 76 | 77 | // Alert is a list of alerts that can be sorted in chronological order. 78 | type Alerts []*Alert 79 | 80 | func (as Alerts) Len() int { return len(as) } 81 | func (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] } 82 | 83 | func (as Alerts) Less(i, j int) bool { 84 | if as[i].StartsAt.Before(as[j].StartsAt) { 85 | return true 86 | } 87 | if as[i].EndsAt.Before(as[j].EndsAt) { 88 | return true 89 | } 90 | return as[i].Fingerprint() < as[j].Fingerprint() 91 | } 92 | 93 | // HasFiring returns true iff one of the alerts is not resolved. 94 | func (as Alerts) HasFiring() bool { 95 | for _, a := range as { 96 | if !a.Resolved() { 97 | return true 98 | } 99 | } 100 | return false 101 | } 102 | 103 | // Status returns StatusFiring iff at least one of the alerts is firing. 104 | func (as Alerts) Status() AlertStatus { 105 | if as.HasFiring() { 106 | return AlertFiring 107 | } 108 | return AlertResolved 109 | } 110 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/fingerprinting.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "strconv" 19 | ) 20 | 21 | // Fingerprint provides a hash-capable representation of a Metric. 22 | // For our purposes, FNV-1A 64-bit is used. 23 | type Fingerprint uint64 24 | 25 | // FingerprintFromString transforms a string representation into a Fingerprint. 26 | func FingerprintFromString(s string) (Fingerprint, error) { 27 | num, err := strconv.ParseUint(s, 16, 64) 28 | return Fingerprint(num), err 29 | } 30 | 31 | // ParseFingerprint parses the input string into a fingerprint. 32 | func ParseFingerprint(s string) (Fingerprint, error) { 33 | num, err := strconv.ParseUint(s, 16, 64) 34 | if err != nil { 35 | return 0, err 36 | } 37 | return Fingerprint(num), nil 38 | } 39 | 40 | func (f Fingerprint) String() string { 41 | return fmt.Sprintf("%016x", uint64(f)) 42 | } 43 | 44 | // Fingerprints represents a collection of Fingerprint subject to a given 45 | // natural sorting scheme. It implements sort.Interface. 46 | type Fingerprints []Fingerprint 47 | 48 | // Len implements sort.Interface. 49 | func (f Fingerprints) Len() int { 50 | return len(f) 51 | } 52 | 53 | // Less implements sort.Interface. 54 | func (f Fingerprints) Less(i, j int) bool { 55 | return f[i] < f[j] 56 | } 57 | 58 | // Swap implements sort.Interface. 59 | func (f Fingerprints) Swap(i, j int) { 60 | f[i], f[j] = f[j], f[i] 61 | } 62 | 63 | // FingerprintSet is a set of Fingerprints. 64 | type FingerprintSet map[Fingerprint]struct{} 65 | 66 | // Equal returns true if both sets contain the same elements (and not more). 67 | func (s FingerprintSet) Equal(o FingerprintSet) bool { 68 | if len(s) != len(o) { 69 | return false 70 | } 71 | 72 | for k := range s { 73 | if _, ok := o[k]; !ok { 74 | return false 75 | } 76 | } 77 | 78 | return true 79 | } 80 | 81 | // Intersection returns the elements contained in both sets. 82 | func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet { 83 | myLength, otherLength := len(s), len(o) 84 | if myLength == 0 || otherLength == 0 { 85 | return FingerprintSet{} 86 | } 87 | 88 | subSet := s 89 | superSet := o 90 | 91 | if otherLength < myLength { 92 | subSet = o 93 | superSet = s 94 | } 95 | 96 | out := FingerprintSet{} 97 | 98 | for k := range subSet { 99 | if _, ok := superSet[k]; ok { 100 | out[k] = struct{}{} 101 | } 102 | } 103 | 104 | return out 105 | } 106 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/labels.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "regexp" 20 | "sort" 21 | "strings" 22 | ) 23 | 24 | const ( 25 | // AlertNameLabel is the name of the label containing the an alert's name. 26 | AlertNameLabel = "alertname" 27 | 28 | // ExportedLabelPrefix is the prefix to prepend to the label names present in 29 | // exported metrics if a label of the same name is added by the server. 30 | ExportedLabelPrefix = "exported_" 31 | 32 | // MetricNameLabel is the label name indicating the metric name of a 33 | // timeseries. 34 | MetricNameLabel = "__name__" 35 | 36 | // SchemeLabel is the name of the label that holds the scheme on which to 37 | // scrape a target. 38 | SchemeLabel = "__scheme__" 39 | 40 | // AddressLabel is the name of the label that holds the address of 41 | // a scrape target. 42 | AddressLabel = "__address__" 43 | 44 | // MetricsPathLabel is the name of the label that holds the path on which to 45 | // scrape a target. 46 | MetricsPathLabel = "__metrics_path__" 47 | 48 | // ReservedLabelPrefix is a prefix which is not legal in user-supplied 49 | // label names. 50 | ReservedLabelPrefix = "__" 51 | 52 | // MetaLabelPrefix is a prefix for labels that provide meta information. 53 | // Labels with this prefix are used for intermediate label processing and 54 | // will not be attached to time series. 55 | MetaLabelPrefix = "__meta_" 56 | 57 | // TmpLabelPrefix is a prefix for temporary labels as part of relabelling. 58 | // Labels with this prefix are used for intermediate label processing and 59 | // will not be attached to time series. This is reserved for use in 60 | // Prometheus configuration files by users. 61 | TmpLabelPrefix = "__tmp_" 62 | 63 | // ParamLabelPrefix is a prefix for labels that provide URL parameters 64 | // used to scrape a target. 65 | ParamLabelPrefix = "__param_" 66 | 67 | // JobLabel is the label name indicating the job from which a timeseries 68 | // was scraped. 69 | JobLabel = "job" 70 | 71 | // InstanceLabel is the label name used for the instance label. 72 | InstanceLabel = "instance" 73 | 74 | // BucketLabel is used for the label that defines the upper bound of a 75 | // bucket of a histogram ("le" -> "less or equal"). 76 | BucketLabel = "le" 77 | 78 | // QuantileLabel is used for the label that defines the quantile in a 79 | // summary. 80 | QuantileLabel = "quantile" 81 | ) 82 | 83 | // LabelNameRE is a regular expression matching valid label names. 84 | var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") 85 | 86 | // A LabelName is a key for a LabelSet or Metric. It has a value associated 87 | // therewith. 88 | type LabelName string 89 | 90 | // UnmarshalYAML implements the yaml.Unmarshaler interface. 91 | func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { 92 | var s string 93 | if err := unmarshal(&s); err != nil { 94 | return err 95 | } 96 | if !LabelNameRE.MatchString(s) { 97 | return fmt.Errorf("%q is not a valid label name", s) 98 | } 99 | *ln = LabelName(s) 100 | return nil 101 | } 102 | 103 | // UnmarshalJSON implements the json.Unmarshaler interface. 104 | func (ln *LabelName) UnmarshalJSON(b []byte) error { 105 | var s string 106 | if err := json.Unmarshal(b, &s); err != nil { 107 | return err 108 | } 109 | if !LabelNameRE.MatchString(s) { 110 | return fmt.Errorf("%q is not a valid label name", s) 111 | } 112 | *ln = LabelName(s) 113 | return nil 114 | } 115 | 116 | // LabelNames is a sortable LabelName slice. In implements sort.Interface. 117 | type LabelNames []LabelName 118 | 119 | func (l LabelNames) Len() int { 120 | return len(l) 121 | } 122 | 123 | func (l LabelNames) Less(i, j int) bool { 124 | return l[i] < l[j] 125 | } 126 | 127 | func (l LabelNames) Swap(i, j int) { 128 | l[i], l[j] = l[j], l[i] 129 | } 130 | 131 | func (l LabelNames) String() string { 132 | labelStrings := make([]string, 0, len(l)) 133 | for _, label := range l { 134 | labelStrings = append(labelStrings, string(label)) 135 | } 136 | return strings.Join(labelStrings, ", ") 137 | } 138 | 139 | // A LabelValue is an associated value for a LabelName. 140 | type LabelValue string 141 | 142 | // LabelValues is a sortable LabelValue slice. It implements sort.Interface. 143 | type LabelValues []LabelValue 144 | 145 | func (l LabelValues) Len() int { 146 | return len(l) 147 | } 148 | 149 | func (l LabelValues) Less(i, j int) bool { 150 | return sort.StringsAreSorted([]string{string(l[i]), string(l[j])}) 151 | } 152 | 153 | func (l LabelValues) Swap(i, j int) { 154 | l[i], l[j] = l[j], l[i] 155 | } 156 | 157 | // LabelPair pairs a name with a value. 158 | type LabelPair struct { 159 | Name LabelName 160 | Value LabelValue 161 | } 162 | 163 | // LabelPairs is a sortable slice of LabelPair pointers. It implements 164 | // sort.Interface. 165 | type LabelPairs []*LabelPair 166 | 167 | func (l LabelPairs) Len() int { 168 | return len(l) 169 | } 170 | 171 | func (l LabelPairs) Less(i, j int) bool { 172 | switch { 173 | case l[i].Name > l[j].Name: 174 | return false 175 | case l[i].Name < l[j].Name: 176 | return true 177 | case l[i].Value > l[j].Value: 178 | return false 179 | case l[i].Value < l[j].Value: 180 | return true 181 | default: 182 | return false 183 | } 184 | } 185 | 186 | func (l LabelPairs) Swap(i, j int) { 187 | l[i], l[j] = l[j], l[i] 188 | } 189 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/labelset.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "sort" 20 | "strings" 21 | ) 22 | 23 | // A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet 24 | // may be fully-qualified down to the point where it may resolve to a single 25 | // Metric in the data store or not. All operations that occur within the realm 26 | // of a LabelSet can emit a vector of Metric entities to which the LabelSet may 27 | // match. 28 | type LabelSet map[LabelName]LabelValue 29 | 30 | func (ls LabelSet) Equal(o LabelSet) bool { 31 | if len(ls) != len(o) { 32 | return false 33 | } 34 | for ln, lv := range ls { 35 | olv, ok := o[ln] 36 | if !ok { 37 | return false 38 | } 39 | if olv != lv { 40 | return false 41 | } 42 | } 43 | return true 44 | } 45 | 46 | // Before compares the metrics, using the following criteria: 47 | // 48 | // If m has fewer labels than o, it is before o. If it has more, it is not. 49 | // 50 | // If the number of labels is the same, the superset of all label names is 51 | // sorted alphanumerically. The first differing label pair found in that order 52 | // determines the outcome: If the label does not exist at all in m, then m is 53 | // before o, and vice versa. Otherwise the label value is compared 54 | // alphanumerically. 55 | // 56 | // If m and o are equal, the method returns false. 57 | func (ls LabelSet) Before(o LabelSet) bool { 58 | if len(ls) < len(o) { 59 | return true 60 | } 61 | if len(ls) > len(o) { 62 | return false 63 | } 64 | 65 | lns := make(LabelNames, 0, len(ls)+len(o)) 66 | for ln := range ls { 67 | lns = append(lns, ln) 68 | } 69 | for ln := range o { 70 | lns = append(lns, ln) 71 | } 72 | // It's probably not worth it to de-dup lns. 73 | sort.Sort(lns) 74 | for _, ln := range lns { 75 | mlv, ok := ls[ln] 76 | if !ok { 77 | return true 78 | } 79 | olv, ok := o[ln] 80 | if !ok { 81 | return false 82 | } 83 | if mlv < olv { 84 | return true 85 | } 86 | if mlv > olv { 87 | return false 88 | } 89 | } 90 | return false 91 | } 92 | 93 | func (ls LabelSet) Clone() LabelSet { 94 | lsn := make(LabelSet, len(ls)) 95 | for ln, lv := range ls { 96 | lsn[ln] = lv 97 | } 98 | return lsn 99 | } 100 | 101 | // Merge is a helper function to non-destructively merge two label sets. 102 | func (l LabelSet) Merge(other LabelSet) LabelSet { 103 | result := make(LabelSet, len(l)) 104 | 105 | for k, v := range l { 106 | result[k] = v 107 | } 108 | 109 | for k, v := range other { 110 | result[k] = v 111 | } 112 | 113 | return result 114 | } 115 | 116 | func (l LabelSet) String() string { 117 | lstrs := make([]string, 0, len(l)) 118 | for l, v := range l { 119 | lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v)) 120 | } 121 | 122 | sort.Strings(lstrs) 123 | return fmt.Sprintf("{%s}", strings.Join(lstrs, ", ")) 124 | } 125 | 126 | // Fingerprint returns the LabelSet's fingerprint. 127 | func (ls LabelSet) Fingerprint() Fingerprint { 128 | return labelSetToFingerprint(ls) 129 | } 130 | 131 | // FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing 132 | // algorithm, which is, however, more susceptible to hash collisions. 133 | func (ls LabelSet) FastFingerprint() Fingerprint { 134 | return labelSetToFastFingerprint(ls) 135 | } 136 | 137 | // UnmarshalJSON implements the json.Unmarshaler interface. 138 | func (l *LabelSet) UnmarshalJSON(b []byte) error { 139 | var m map[LabelName]LabelValue 140 | if err := json.Unmarshal(b, &m); err != nil { 141 | return err 142 | } 143 | // encoding/json only unmarshals maps of the form map[string]T. It treats 144 | // LabelName as a string and does not call its UnmarshalJSON method. 145 | // Thus, we have to replicate the behavior here. 146 | for ln := range m { 147 | if !LabelNameRE.MatchString(string(ln)) { 148 | return fmt.Errorf("%q is not a valid label name", ln) 149 | } 150 | } 151 | *l = LabelSet(m) 152 | return nil 153 | } 154 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/metric.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "sort" 19 | "strings" 20 | ) 21 | 22 | var separator = []byte{0} 23 | 24 | // A Metric is similar to a LabelSet, but the key difference is that a Metric is 25 | // a singleton and refers to one and only one stream of samples. 26 | type Metric LabelSet 27 | 28 | // Equal compares the metrics. 29 | func (m Metric) Equal(o Metric) bool { 30 | return LabelSet(m).Equal(LabelSet(o)) 31 | } 32 | 33 | // Before compares the metrics' underlying label sets. 34 | func (m Metric) Before(o Metric) bool { 35 | return LabelSet(m).Before(LabelSet(o)) 36 | } 37 | 38 | // Clone returns a copy of the Metric. 39 | func (m Metric) Clone() Metric { 40 | clone := Metric{} 41 | for k, v := range m { 42 | clone[k] = v 43 | } 44 | return clone 45 | } 46 | 47 | func (m Metric) String() string { 48 | metricName, hasName := m[MetricNameLabel] 49 | numLabels := len(m) - 1 50 | if !hasName { 51 | numLabels = len(m) 52 | } 53 | labelStrings := make([]string, 0, numLabels) 54 | for label, value := range m { 55 | if label != MetricNameLabel { 56 | labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) 57 | } 58 | } 59 | 60 | switch numLabels { 61 | case 0: 62 | if hasName { 63 | return string(metricName) 64 | } 65 | return "{}" 66 | default: 67 | sort.Strings(labelStrings) 68 | return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", ")) 69 | } 70 | } 71 | 72 | // Fingerprint returns a Metric's Fingerprint. 73 | func (m Metric) Fingerprint() Fingerprint { 74 | return LabelSet(m).Fingerprint() 75 | } 76 | 77 | // FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing 78 | // algorithm, which is, however, more susceptible to hash collisions. 79 | func (m Metric) FastFingerprint() Fingerprint { 80 | return LabelSet(m).FastFingerprint() 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/model.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package model contains common data structures that are shared across 15 | // Prometheus componenets and libraries. 16 | package model 17 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/signature.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "bytes" 18 | "hash" 19 | "hash/fnv" 20 | "sort" 21 | "sync" 22 | ) 23 | 24 | // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is 25 | // used to separate label names, label values, and other strings from each other 26 | // when calculating their combined hash value (aka signature aka fingerprint). 27 | const SeparatorByte byte = 255 28 | 29 | var ( 30 | // cache the signature of an empty label set. 31 | emptyLabelSignature = fnv.New64a().Sum64() 32 | 33 | hashAndBufPool sync.Pool 34 | ) 35 | 36 | type hashAndBuf struct { 37 | h hash.Hash64 38 | b bytes.Buffer 39 | } 40 | 41 | func getHashAndBuf() *hashAndBuf { 42 | hb := hashAndBufPool.Get() 43 | if hb == nil { 44 | return &hashAndBuf{h: fnv.New64a()} 45 | } 46 | return hb.(*hashAndBuf) 47 | } 48 | 49 | func putHashAndBuf(hb *hashAndBuf) { 50 | hb.h.Reset() 51 | hb.b.Reset() 52 | hashAndBufPool.Put(hb) 53 | } 54 | 55 | // LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a 56 | // given label set. (Collisions are possible but unlikely if the number of label 57 | // sets the function is applied to is small.) 58 | func LabelsToSignature(labels map[string]string) uint64 { 59 | if len(labels) == 0 { 60 | return emptyLabelSignature 61 | } 62 | 63 | labelNames := make([]string, 0, len(labels)) 64 | for labelName := range labels { 65 | labelNames = append(labelNames, labelName) 66 | } 67 | sort.Strings(labelNames) 68 | 69 | hb := getHashAndBuf() 70 | defer putHashAndBuf(hb) 71 | 72 | for _, labelName := range labelNames { 73 | hb.b.WriteString(labelName) 74 | hb.b.WriteByte(SeparatorByte) 75 | hb.b.WriteString(labels[labelName]) 76 | hb.b.WriteByte(SeparatorByte) 77 | hb.h.Write(hb.b.Bytes()) 78 | hb.b.Reset() 79 | } 80 | return hb.h.Sum64() 81 | } 82 | 83 | // labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as 84 | // parameter (rather than a label map) and returns a Fingerprint. 85 | func labelSetToFingerprint(ls LabelSet) Fingerprint { 86 | if len(ls) == 0 { 87 | return Fingerprint(emptyLabelSignature) 88 | } 89 | 90 | labelNames := make(LabelNames, 0, len(ls)) 91 | for labelName := range ls { 92 | labelNames = append(labelNames, labelName) 93 | } 94 | sort.Sort(labelNames) 95 | 96 | hb := getHashAndBuf() 97 | defer putHashAndBuf(hb) 98 | 99 | for _, labelName := range labelNames { 100 | hb.b.WriteString(string(labelName)) 101 | hb.b.WriteByte(SeparatorByte) 102 | hb.b.WriteString(string(ls[labelName])) 103 | hb.b.WriteByte(SeparatorByte) 104 | hb.h.Write(hb.b.Bytes()) 105 | hb.b.Reset() 106 | } 107 | return Fingerprint(hb.h.Sum64()) 108 | } 109 | 110 | // labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a 111 | // faster and less allocation-heavy hash function, which is more susceptible to 112 | // create hash collisions. Therefore, collision detection should be applied. 113 | func labelSetToFastFingerprint(ls LabelSet) Fingerprint { 114 | if len(ls) == 0 { 115 | return Fingerprint(emptyLabelSignature) 116 | } 117 | 118 | var result uint64 119 | hb := getHashAndBuf() 120 | defer putHashAndBuf(hb) 121 | 122 | for labelName, labelValue := range ls { 123 | hb.b.WriteString(string(labelName)) 124 | hb.b.WriteByte(SeparatorByte) 125 | hb.b.WriteString(string(labelValue)) 126 | hb.h.Write(hb.b.Bytes()) 127 | result ^= hb.h.Sum64() 128 | hb.h.Reset() 129 | hb.b.Reset() 130 | } 131 | return Fingerprint(result) 132 | } 133 | 134 | // SignatureForLabels works like LabelsToSignature but takes a Metric as 135 | // parameter (rather than a label map) and only includes the labels with the 136 | // specified LabelNames into the signature calculation. The labels passed in 137 | // will be sorted by this function. 138 | func SignatureForLabels(m Metric, labels ...LabelName) uint64 { 139 | if len(m) == 0 || len(labels) == 0 { 140 | return emptyLabelSignature 141 | } 142 | 143 | sort.Sort(LabelNames(labels)) 144 | 145 | hb := getHashAndBuf() 146 | defer putHashAndBuf(hb) 147 | 148 | for _, label := range labels { 149 | hb.b.WriteString(string(label)) 150 | hb.b.WriteByte(SeparatorByte) 151 | hb.b.WriteString(string(m[label])) 152 | hb.b.WriteByte(SeparatorByte) 153 | hb.h.Write(hb.b.Bytes()) 154 | hb.b.Reset() 155 | } 156 | return hb.h.Sum64() 157 | } 158 | 159 | // SignatureWithoutLabels works like LabelsToSignature but takes a Metric as 160 | // parameter (rather than a label map) and excludes the labels with any of the 161 | // specified LabelNames from the signature calculation. 162 | func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { 163 | if len(m) == 0 { 164 | return emptyLabelSignature 165 | } 166 | 167 | labelNames := make(LabelNames, 0, len(m)) 168 | for labelName := range m { 169 | if _, exclude := labels[labelName]; !exclude { 170 | labelNames = append(labelNames, labelName) 171 | } 172 | } 173 | if len(labelNames) == 0 { 174 | return emptyLabelSignature 175 | } 176 | sort.Sort(labelNames) 177 | 178 | hb := getHashAndBuf() 179 | defer putHashAndBuf(hb) 180 | 181 | for _, labelName := range labelNames { 182 | hb.b.WriteString(string(labelName)) 183 | hb.b.WriteByte(SeparatorByte) 184 | hb.b.WriteString(string(m[labelName])) 185 | hb.b.WriteByte(SeparatorByte) 186 | hb.h.Write(hb.b.Bytes()) 187 | hb.b.Reset() 188 | } 189 | return hb.h.Sum64() 190 | } 191 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/silence.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "regexp" 20 | "time" 21 | ) 22 | 23 | // Matcher describes a matches the value of a given label. 24 | type Matcher struct { 25 | Name LabelName `json:"name"` 26 | Value string `json:"value"` 27 | IsRegex bool `json:"isRegex"` 28 | } 29 | 30 | func (m *Matcher) UnmarshalJSON(b []byte) error { 31 | type plain Matcher 32 | if err := json.Unmarshal(b, (*plain)(m)); err != nil { 33 | return err 34 | } 35 | 36 | if len(m.Name) == 0 { 37 | return fmt.Errorf("label name in matcher must not be empty") 38 | } 39 | if m.IsRegex { 40 | if _, err := regexp.Compile(m.Value); err != nil { 41 | return err 42 | } 43 | } 44 | return nil 45 | } 46 | 47 | // Silence defines the representation of a silence definiton 48 | // in the Prometheus eco-system. 49 | type Silence struct { 50 | ID uint64 `json:"id,omitempty"` 51 | 52 | Matchers []*Matcher `json:"matchers"` 53 | 54 | StartsAt time.Time `json:"startsAt"` 55 | EndsAt time.Time `json:"endsAt"` 56 | 57 | CreatedAt time.Time `json:"createdAt,omitempty"` 58 | CreatedBy string `json:"createdBy"` 59 | Comment string `json:"comment,omitempty"` 60 | } 61 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.3 5 | - 1.4 6 | - 1.5 7 | - tip 8 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/AUTHORS.md: -------------------------------------------------------------------------------- 1 | The Prometheus project was started by Matt T. Proud (emeritus) and 2 | Julius Volz in 2012. 3 | 4 | Maintainers of this repository: 5 | 6 | * Tobias Schmidt 7 | 8 | The following individuals have contributed code to this repository 9 | (listed in alphabetical order): 10 | 11 | * Armen Baghumian 12 | * Bjoern Rabenstein 13 | * David Cournapeau 14 | * Ji-Hoon, Seol 15 | * Jonas Große Sundrup 16 | * Julius Volz 17 | * Matthias Rampke 18 | * Nicky Gerritsen 19 | * Rémi Audebert 20 | * Tobias Schmidt 21 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Prometheus uses GitHub to manage reviews of pull requests. 4 | 5 | * If you have a trivial fix or improvement, go ahead and create a pull 6 | request, addressing (with `@...`) one or more of the maintainers 7 | (see [AUTHORS.md](AUTHORS.md)) in the description of the pull request. 8 | 9 | * If you plan to do something more involved, first discuss your ideas 10 | on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers). 11 | This will avoid unnecessary work and surely give you and us a good deal 12 | of inspiration. 13 | 14 | * Relevant coding style guidelines are the [Go Code Review 15 | Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments) 16 | and the _Formatting and style_ section of Peter Bourgon's [Go: Best 17 | Practices for Production 18 | Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style). 19 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/Makefile: -------------------------------------------------------------------------------- 1 | ci: 2 | ! gofmt -l *.go | read nothing 3 | go vet 4 | go test -v ./... 5 | go get github.com/golang/lint/golint 6 | golint *.go 7 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/NOTICE: -------------------------------------------------------------------------------- 1 | procfs provides functions to retrieve system, kernel and process 2 | metrics from the pseudo-filesystem proc. 3 | 4 | Copyright 2014-2015 The Prometheus Authors 5 | 6 | This product includes software developed at 7 | SoundCloud Ltd. (http://soundcloud.com/). 8 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/README.md: -------------------------------------------------------------------------------- 1 | # procfs 2 | 3 | This procfs package provides functions to retrieve system, kernel and process 4 | metrics from the pseudo-filesystem proc. 5 | 6 | *WARNING*: This package is a work in progress. Its API may still break in 7 | backwards-incompatible ways without warnings. Use it at your own risk. 8 | 9 | [![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs) 10 | [![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs) 11 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Prometheus Team 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package procfs provides functions to retrieve system, kernel and process 15 | // metrics from the pseudo-filesystem proc. 16 | // 17 | // Example: 18 | // 19 | // package main 20 | // 21 | // import ( 22 | // "fmt" 23 | // "log" 24 | // 25 | // "github.com/prometheus/procfs" 26 | // ) 27 | // 28 | // func main() { 29 | // p, err := procfs.Self() 30 | // if err != nil { 31 | // log.Fatalf("could not get process: %s", err) 32 | // } 33 | // 34 | // stat, err := p.NewStat() 35 | // if err != nil { 36 | // log.Fatalf("could not get process stat: %s", err) 37 | // } 38 | // 39 | // fmt.Printf("command: %s\n", stat.Comm) 40 | // fmt.Printf("cpu time: %fs\n", stat.CPUTime()) 41 | // fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) 42 | // fmt.Printf("rss: %dB\n", stat.ResidentMemory()) 43 | // } 44 | // 45 | package procfs 46 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/cmdline: -------------------------------------------------------------------------------- 1 | vimtest.go+10 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/comm: -------------------------------------------------------------------------------- 1 | vim 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/exe: -------------------------------------------------------------------------------- 1 | /usr/bin/vim -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/fd/0: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/abc -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/fd/1: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/def -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/fd/10: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/xyz -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/fd/2: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/ghi -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/fd/3: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/uvw -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/io: -------------------------------------------------------------------------------- 1 | rchar: 750339 2 | wchar: 818609 3 | syscr: 7405 4 | syscw: 5245 5 | read_bytes: 1024 6 | write_bytes: 2048 7 | cancelled_write_bytes: -1024 8 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/limits: -------------------------------------------------------------------------------- 1 | Limit Soft Limit Hard Limit Units 2 | Max cpu time unlimited unlimited seconds 3 | Max file size unlimited unlimited bytes 4 | Max data size unlimited unlimited bytes 5 | Max stack size 8388608 unlimited bytes 6 | Max core file size 0 unlimited bytes 7 | Max resident set unlimited unlimited bytes 8 | Max processes 62898 62898 processes 9 | Max open files 2048 4096 files 10 | Max locked memory 65536 65536 bytes 11 | Max address space unlimited unlimited bytes 12 | Max file locks unlimited unlimited locks 13 | Max pending signals 62898 62898 signals 14 | Max msgqueue size 819200 819200 bytes 15 | Max nice priority 0 0 16 | Max realtime priority 0 0 17 | Max realtime timeout unlimited unlimited us 18 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26231/stat: -------------------------------------------------------------------------------- 1 | 26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/cmdline: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/vendor/github.com/prometheus/procfs/fixtures/26232/cmdline -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/comm: -------------------------------------------------------------------------------- 1 | ata_sff 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/fd/0: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/abc -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/fd/1: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/def -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/fd/2: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/ghi -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/fd/3: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/uvw -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/fd/4: -------------------------------------------------------------------------------- 1 | ../../symlinktargets/xyz -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/limits: -------------------------------------------------------------------------------- 1 | Limit Soft Limit Hard Limit Units 2 | Max cpu time unlimited unlimited seconds 3 | Max file size unlimited unlimited bytes 4 | Max data size unlimited unlimited bytes 5 | Max stack size 8388608 unlimited bytes 6 | Max core file size 0 unlimited bytes 7 | Max resident set unlimited unlimited bytes 8 | Max processes 29436 29436 processes 9 | Max open files 1024 4096 files 10 | Max locked memory 65536 65536 bytes 11 | Max address space unlimited unlimited bytes 12 | Max file locks unlimited unlimited locks 13 | Max pending signals 29436 29436 signals 14 | Max msgqueue size 819200 819200 bytes 15 | Max nice priority 0 0 16 | Max realtime priority 0 0 17 | Max realtime timeout unlimited unlimited us 18 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/26232/stat: -------------------------------------------------------------------------------- 1 | 33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/584/stat: -------------------------------------------------------------------------------- 1 | 1020 ((a b ) ( c d) ) R 28378 1020 28378 34842 1020 4218880 286 0 0 0 0 0 0 0 20 0 1 0 10839175 10395648 155 18446744073709551615 4194304 4238788 140736466511168 140736466511168 140609271124624 0 0 0 0 0 0 0 17 5 0 0 0 0 0 6336016 6337300 25579520 140736466515030 140736466515061 140736466515061 140736466518002 0 2 | #!/bin/cat /proc/self/stat 3 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/mdstat: -------------------------------------------------------------------------------- 1 | Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 2 | md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9] 3 | 5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU] 4 | 5 | md127 : active raid1 sdi2[0] sdj2[1] 6 | 312319552 blocks [2/2] [UU] 7 | 8 | md0 : active raid1 sdk[2](S) sdi1[0] sdj1[1] 9 | 248896 blocks [2/2] [UU] 10 | 11 | md4 : inactive raid1 sda3[0] sdb3[1] 12 | 4883648 blocks [2/2] [UU] 13 | 14 | md6 : active raid1 sdb2[2] sda2[0] 15 | 195310144 blocks [2/1] [U_] 16 | [=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec 17 | 18 | md8 : active raid1 sdb1[1] sda1[0] 19 | 195310144 blocks [2/2] [UU] 20 | [=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec 21 | 22 | md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1] 23 | 7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU] 24 | bitmap: 0/30 pages [0KB], 65536KB chunk 25 | 26 | unused devices: 27 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/net/ip_vs: -------------------------------------------------------------------------------- 1 | IP Virtual Server version 1.2.1 (size=4096) 2 | Prot LocalAddress:Port Scheduler Flags 3 | -> RemoteAddress:Port Forward Weight ActiveConn InActConn 4 | TCP C0A80016:0CEA wlc 5 | -> C0A85216:0CEA Tunnel 100 248 2 6 | -> C0A85318:0CEA Tunnel 100 248 2 7 | -> C0A85315:0CEA Tunnel 100 248 1 8 | TCP C0A80039:0CEA wlc 9 | -> C0A85416:0CEA Tunnel 0 0 0 10 | -> C0A85215:0CEA Tunnel 100 1499 0 11 | -> C0A83215:0CEA Tunnel 100 1498 0 12 | TCP C0A80037:0CEA wlc 13 | -> C0A8321A:0CEA Tunnel 0 0 0 14 | -> C0A83120:0CEA Tunnel 100 0 0 15 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/net/ip_vs_stats: -------------------------------------------------------------------------------- 1 | Total Incoming Outgoing Incoming Outgoing 2 | Conns Packets Packets Bytes Bytes 3 | 16AA370 E33656E5 0 51D8C8883AB3 0 4 | 5 | Conns/s Pkts/s Pkts/s Bytes/s Bytes/s 6 | 4 1FB3C 0 1282A8F 0 7 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/self: -------------------------------------------------------------------------------- 1 | 26231 -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/stat: -------------------------------------------------------------------------------- 1 | cpu 301854 612 111922 8979004 3552 2 3944 0 0 0 2 | cpu0 44490 19 21045 1087069 220 1 3410 0 0 0 3 | cpu1 47869 23 16474 1110787 591 0 46 0 0 0 4 | cpu2 46504 36 15916 1112321 441 0 326 0 0 0 5 | cpu3 47054 102 15683 1113230 533 0 60 0 0 0 6 | cpu4 28413 25 10776 1140321 217 0 8 0 0 0 7 | cpu5 29271 101 11586 1136270 672 0 30 0 0 0 8 | cpu6 29152 36 10276 1139721 319 0 29 0 0 0 9 | cpu7 29098 268 10164 1139282 555 0 31 0 0 0 10 | intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 | ctxt 38014093 12 | btime 1418183276 13 | processes 26442 14 | procs_running 2 15 | procs_blocked 0 16 | softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444 17 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/symlinktargets/README: -------------------------------------------------------------------------------- 1 | This directory contains some empty files that are the symlinks the files in the "fd" directory point to. 2 | They are otherwise ignored by the tests 3 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/symlinktargets/abc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/vendor/github.com/prometheus/procfs/fixtures/symlinktargets/abc -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/symlinktargets/def: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/vendor/github.com/prometheus/procfs/fixtures/symlinktargets/def -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/symlinktargets/ghi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/vendor/github.com/prometheus/procfs/fixtures/symlinktargets/ghi -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/symlinktargets/uvw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/vendor/github.com/prometheus/procfs/fixtures/symlinktargets/uvw -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fixtures/symlinktargets/xyz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiorix/defacer/a700e338fc5228d6fa8cbd53d4ff8a75210e2dcd/vendor/github.com/prometheus/procfs/fixtures/symlinktargets/xyz -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fs.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path" 7 | ) 8 | 9 | // FS represents the pseudo-filesystem proc, which provides an interface to 10 | // kernel data structures. 11 | type FS string 12 | 13 | // DefaultMountPoint is the common mount point of the proc filesystem. 14 | const DefaultMountPoint = "/proc" 15 | 16 | // NewFS returns a new FS mounted under the given mountPoint. It will error 17 | // if the mount point can't be read. 18 | func NewFS(mountPoint string) (FS, error) { 19 | info, err := os.Stat(mountPoint) 20 | if err != nil { 21 | return "", fmt.Errorf("could not read %s: %s", mountPoint, err) 22 | } 23 | if !info.IsDir() { 24 | return "", fmt.Errorf("mount point %s is not a directory", mountPoint) 25 | } 26 | 27 | return FS(mountPoint), nil 28 | } 29 | 30 | // Path returns the path of the given subsystem relative to the procfs root. 31 | func (fs FS) Path(p ...string) string { 32 | return path.Join(append([]string{string(fs)}, p...)...) 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/ipvs.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "bufio" 5 | "encoding/hex" 6 | "errors" 7 | "fmt" 8 | "io" 9 | "io/ioutil" 10 | "net" 11 | "os" 12 | "strconv" 13 | "strings" 14 | ) 15 | 16 | // IPVSStats holds IPVS statistics, as exposed by the kernel in `/proc/net/ip_vs_stats`. 17 | type IPVSStats struct { 18 | // Total count of connections. 19 | Connections uint64 20 | // Total incoming packages processed. 21 | IncomingPackets uint64 22 | // Total outgoing packages processed. 23 | OutgoingPackets uint64 24 | // Total incoming traffic. 25 | IncomingBytes uint64 26 | // Total outgoing traffic. 27 | OutgoingBytes uint64 28 | } 29 | 30 | // IPVSBackendStatus holds current metrics of one virtual / real address pair. 31 | type IPVSBackendStatus struct { 32 | // The local (virtual) IP address. 33 | LocalAddress net.IP 34 | // The local (virtual) port. 35 | LocalPort uint16 36 | // The transport protocol (TCP, UDP). 37 | Proto string 38 | // The remote (real) IP address. 39 | RemoteAddress net.IP 40 | // The remote (real) port. 41 | RemotePort uint16 42 | // The current number of active connections for this virtual/real address pair. 43 | ActiveConn uint64 44 | // The current number of inactive connections for this virtual/real address pair. 45 | InactConn uint64 46 | // The current weight of this virtual/real address pair. 47 | Weight uint64 48 | } 49 | 50 | // NewIPVSStats reads the IPVS statistics. 51 | func NewIPVSStats() (IPVSStats, error) { 52 | fs, err := NewFS(DefaultMountPoint) 53 | if err != nil { 54 | return IPVSStats{}, err 55 | } 56 | 57 | return fs.NewIPVSStats() 58 | } 59 | 60 | // NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem. 61 | func (fs FS) NewIPVSStats() (IPVSStats, error) { 62 | file, err := os.Open(fs.Path("net/ip_vs_stats")) 63 | if err != nil { 64 | return IPVSStats{}, err 65 | } 66 | defer file.Close() 67 | 68 | return parseIPVSStats(file) 69 | } 70 | 71 | // parseIPVSStats performs the actual parsing of `ip_vs_stats`. 72 | func parseIPVSStats(file io.Reader) (IPVSStats, error) { 73 | var ( 74 | statContent []byte 75 | statLines []string 76 | statFields []string 77 | stats IPVSStats 78 | ) 79 | 80 | statContent, err := ioutil.ReadAll(file) 81 | if err != nil { 82 | return IPVSStats{}, err 83 | } 84 | 85 | statLines = strings.SplitN(string(statContent), "\n", 4) 86 | if len(statLines) != 4 { 87 | return IPVSStats{}, errors.New("ip_vs_stats corrupt: too short") 88 | } 89 | 90 | statFields = strings.Fields(statLines[2]) 91 | if len(statFields) != 5 { 92 | return IPVSStats{}, errors.New("ip_vs_stats corrupt: unexpected number of fields") 93 | } 94 | 95 | stats.Connections, err = strconv.ParseUint(statFields[0], 16, 64) 96 | if err != nil { 97 | return IPVSStats{}, err 98 | } 99 | stats.IncomingPackets, err = strconv.ParseUint(statFields[1], 16, 64) 100 | if err != nil { 101 | return IPVSStats{}, err 102 | } 103 | stats.OutgoingPackets, err = strconv.ParseUint(statFields[2], 16, 64) 104 | if err != nil { 105 | return IPVSStats{}, err 106 | } 107 | stats.IncomingBytes, err = strconv.ParseUint(statFields[3], 16, 64) 108 | if err != nil { 109 | return IPVSStats{}, err 110 | } 111 | stats.OutgoingBytes, err = strconv.ParseUint(statFields[4], 16, 64) 112 | if err != nil { 113 | return IPVSStats{}, err 114 | } 115 | 116 | return stats, nil 117 | } 118 | 119 | // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs. 120 | func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { 121 | fs, err := NewFS(DefaultMountPoint) 122 | if err != nil { 123 | return []IPVSBackendStatus{}, err 124 | } 125 | 126 | return fs.NewIPVSBackendStatus() 127 | } 128 | 129 | // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem. 130 | func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { 131 | file, err := os.Open(fs.Path("net/ip_vs")) 132 | if err != nil { 133 | return nil, err 134 | } 135 | defer file.Close() 136 | 137 | return parseIPVSBackendStatus(file) 138 | } 139 | 140 | func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) { 141 | var ( 142 | status []IPVSBackendStatus 143 | scanner = bufio.NewScanner(file) 144 | proto string 145 | localAddress net.IP 146 | localPort uint16 147 | err error 148 | ) 149 | 150 | for scanner.Scan() { 151 | fields := strings.Fields(string(scanner.Text())) 152 | if len(fields) == 0 { 153 | continue 154 | } 155 | switch { 156 | case fields[0] == "IP" || fields[0] == "Prot" || fields[1] == "RemoteAddress:Port": 157 | continue 158 | case fields[0] == "TCP" || fields[0] == "UDP": 159 | if len(fields) < 2 { 160 | continue 161 | } 162 | proto = fields[0] 163 | localAddress, localPort, err = parseIPPort(fields[1]) 164 | if err != nil { 165 | return nil, err 166 | } 167 | case fields[0] == "->": 168 | if len(fields) < 6 { 169 | continue 170 | } 171 | remoteAddress, remotePort, err := parseIPPort(fields[1]) 172 | if err != nil { 173 | return nil, err 174 | } 175 | weight, err := strconv.ParseUint(fields[3], 10, 64) 176 | if err != nil { 177 | return nil, err 178 | } 179 | activeConn, err := strconv.ParseUint(fields[4], 10, 64) 180 | if err != nil { 181 | return nil, err 182 | } 183 | inactConn, err := strconv.ParseUint(fields[5], 10, 64) 184 | if err != nil { 185 | return nil, err 186 | } 187 | status = append(status, IPVSBackendStatus{ 188 | LocalAddress: localAddress, 189 | LocalPort: localPort, 190 | RemoteAddress: remoteAddress, 191 | RemotePort: remotePort, 192 | Proto: proto, 193 | Weight: weight, 194 | ActiveConn: activeConn, 195 | InactConn: inactConn, 196 | }) 197 | } 198 | } 199 | return status, nil 200 | } 201 | 202 | func parseIPPort(s string) (net.IP, uint16, error) { 203 | tmp := strings.SplitN(s, ":", 2) 204 | 205 | if len(tmp) != 2 { 206 | return nil, 0, fmt.Errorf("invalid IP:Port: %s", s) 207 | } 208 | 209 | if len(tmp[0]) != 8 && len(tmp[0]) != 32 { 210 | return nil, 0, fmt.Errorf("invalid IP: %s", tmp[0]) 211 | } 212 | 213 | ip, err := hex.DecodeString(tmp[0]) 214 | if err != nil { 215 | return nil, 0, err 216 | } 217 | 218 | port, err := strconv.ParseUint(tmp[1], 16, 16) 219 | if err != nil { 220 | return nil, 0, err 221 | } 222 | 223 | return ip, uint16(port), nil 224 | } 225 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/mdstat.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "regexp" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | var ( 12 | statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`) 13 | buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`) 14 | ) 15 | 16 | // MDStat holds info parsed from /proc/mdstat. 17 | type MDStat struct { 18 | // Name of the device. 19 | Name string 20 | // activity-state of the device. 21 | ActivityState string 22 | // Number of active disks. 23 | DisksActive int64 24 | // Total number of disks the device consists of. 25 | DisksTotal int64 26 | // Number of blocks the device holds. 27 | BlocksTotal int64 28 | // Number of blocks on the device that are in sync. 29 | BlocksSynced int64 30 | } 31 | 32 | // ParseMDStat parses an mdstat-file and returns a struct with the relevant infos. 33 | func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { 34 | mdStatusFilePath := fs.Path("mdstat") 35 | content, err := ioutil.ReadFile(mdStatusFilePath) 36 | if err != nil { 37 | return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) 38 | } 39 | 40 | mdStates := []MDStat{} 41 | lines := strings.Split(string(content), "\n") 42 | for i, l := range lines { 43 | if l == "" { 44 | continue 45 | } 46 | if l[0] == ' ' { 47 | continue 48 | } 49 | if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") { 50 | continue 51 | } 52 | 53 | mainLine := strings.Split(l, " ") 54 | if len(mainLine) < 3 { 55 | return mdStates, fmt.Errorf("error parsing mdline: %s", l) 56 | } 57 | mdName := mainLine[0] 58 | activityState := mainLine[2] 59 | 60 | if len(lines) <= i+3 { 61 | return mdStates, fmt.Errorf( 62 | "error parsing %s: too few lines for md device %s", 63 | mdStatusFilePath, 64 | mdName, 65 | ) 66 | } 67 | 68 | active, total, size, err := evalStatusline(lines[i+1]) 69 | if err != nil { 70 | return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) 71 | } 72 | 73 | // j is the line number of the syncing-line. 74 | j := i + 2 75 | if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line 76 | j = i + 3 77 | } 78 | 79 | // If device is syncing at the moment, get the number of currently 80 | // synced bytes, otherwise that number equals the size of the device. 81 | syncedBlocks := size 82 | if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") { 83 | syncedBlocks, err = evalBuildline(lines[j]) 84 | if err != nil { 85 | return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) 86 | } 87 | } 88 | 89 | mdStates = append(mdStates, MDStat{ 90 | Name: mdName, 91 | ActivityState: activityState, 92 | DisksActive: active, 93 | DisksTotal: total, 94 | BlocksTotal: size, 95 | BlocksSynced: syncedBlocks, 96 | }) 97 | } 98 | 99 | return mdStates, nil 100 | } 101 | 102 | func evalStatusline(statusline string) (active, total, size int64, err error) { 103 | matches := statuslineRE.FindStringSubmatch(statusline) 104 | if len(matches) != 4 { 105 | return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline) 106 | } 107 | 108 | size, err = strconv.ParseInt(matches[1], 10, 64) 109 | if err != nil { 110 | return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) 111 | } 112 | 113 | total, err = strconv.ParseInt(matches[2], 10, 64) 114 | if err != nil { 115 | return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) 116 | } 117 | 118 | active, err = strconv.ParseInt(matches[3], 10, 64) 119 | if err != nil { 120 | return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) 121 | } 122 | 123 | return active, total, size, nil 124 | } 125 | 126 | func evalBuildline(buildline string) (syncedBlocks int64, err error) { 127 | matches := buildlineRE.FindStringSubmatch(buildline) 128 | if len(matches) != 2 { 129 | return 0, fmt.Errorf("unexpected buildline: %s", buildline) 130 | } 131 | 132 | syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64) 133 | if err != nil { 134 | return 0, fmt.Errorf("%s in buildline: %s", err, buildline) 135 | } 136 | 137 | return syncedBlocks, nil 138 | } 139 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | // Proc provides information about a running process. 12 | type Proc struct { 13 | // The process ID. 14 | PID int 15 | 16 | fs FS 17 | } 18 | 19 | // Procs represents a list of Proc structs. 20 | type Procs []Proc 21 | 22 | func (p Procs) Len() int { return len(p) } 23 | func (p Procs) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 24 | func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID } 25 | 26 | // Self returns a process for the current process read via /proc/self. 27 | func Self() (Proc, error) { 28 | fs, err := NewFS(DefaultMountPoint) 29 | if err != nil { 30 | return Proc{}, err 31 | } 32 | return fs.Self() 33 | } 34 | 35 | // NewProc returns a process for the given pid under /proc. 36 | func NewProc(pid int) (Proc, error) { 37 | fs, err := NewFS(DefaultMountPoint) 38 | if err != nil { 39 | return Proc{}, err 40 | } 41 | return fs.NewProc(pid) 42 | } 43 | 44 | // AllProcs returns a list of all currently avaible processes under /proc. 45 | func AllProcs() (Procs, error) { 46 | fs, err := NewFS(DefaultMountPoint) 47 | if err != nil { 48 | return Procs{}, err 49 | } 50 | return fs.AllProcs() 51 | } 52 | 53 | // Self returns a process for the current process. 54 | func (fs FS) Self() (Proc, error) { 55 | p, err := os.Readlink(fs.Path("self")) 56 | if err != nil { 57 | return Proc{}, err 58 | } 59 | pid, err := strconv.Atoi(strings.Replace(p, string(fs), "", -1)) 60 | if err != nil { 61 | return Proc{}, err 62 | } 63 | return fs.NewProc(pid) 64 | } 65 | 66 | // NewProc returns a process for the given pid. 67 | func (fs FS) NewProc(pid int) (Proc, error) { 68 | if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil { 69 | return Proc{}, err 70 | } 71 | return Proc{PID: pid, fs: fs}, nil 72 | } 73 | 74 | // AllProcs returns a list of all currently avaible processes. 75 | func (fs FS) AllProcs() (Procs, error) { 76 | d, err := os.Open(fs.Path()) 77 | if err != nil { 78 | return Procs{}, err 79 | } 80 | defer d.Close() 81 | 82 | names, err := d.Readdirnames(-1) 83 | if err != nil { 84 | return Procs{}, fmt.Errorf("could not read %s: %s", d.Name(), err) 85 | } 86 | 87 | p := Procs{} 88 | for _, n := range names { 89 | pid, err := strconv.ParseInt(n, 10, 64) 90 | if err != nil { 91 | continue 92 | } 93 | p = append(p, Proc{PID: int(pid), fs: fs}) 94 | } 95 | 96 | return p, nil 97 | } 98 | 99 | // CmdLine returns the command line of a process. 100 | func (p Proc) CmdLine() ([]string, error) { 101 | f, err := os.Open(p.path("cmdline")) 102 | if err != nil { 103 | return nil, err 104 | } 105 | defer f.Close() 106 | 107 | data, err := ioutil.ReadAll(f) 108 | if err != nil { 109 | return nil, err 110 | } 111 | 112 | if len(data) < 1 { 113 | return []string{}, nil 114 | } 115 | 116 | return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil 117 | } 118 | 119 | // Comm returns the command name of a process. 120 | func (p Proc) Comm() (string, error) { 121 | f, err := os.Open(p.path("comm")) 122 | if err != nil { 123 | return "", err 124 | } 125 | defer f.Close() 126 | 127 | data, err := ioutil.ReadAll(f) 128 | if err != nil { 129 | return "", err 130 | } 131 | 132 | return strings.TrimSpace(string(data)), nil 133 | } 134 | 135 | // Executable returns the absolute path of the executable command of a process. 136 | func (p Proc) Executable() (string, error) { 137 | exe, err := os.Readlink(p.path("exe")) 138 | if os.IsNotExist(err) { 139 | return "", nil 140 | } 141 | 142 | return exe, err 143 | } 144 | 145 | // FileDescriptors returns the currently open file descriptors of a process. 146 | func (p Proc) FileDescriptors() ([]uintptr, error) { 147 | names, err := p.fileDescriptors() 148 | if err != nil { 149 | return nil, err 150 | } 151 | 152 | fds := make([]uintptr, len(names)) 153 | for i, n := range names { 154 | fd, err := strconv.ParseInt(n, 10, 32) 155 | if err != nil { 156 | return nil, fmt.Errorf("could not parse fd %s: %s", n, err) 157 | } 158 | fds[i] = uintptr(fd) 159 | } 160 | 161 | return fds, nil 162 | } 163 | 164 | // FileDescriptorTargets returns the targets of all file descriptors of a process. 165 | // If a file descriptor is not a symlink to a file (like a socket), that value will be the empty string. 166 | func (p Proc) FileDescriptorTargets() ([]string, error) { 167 | names, err := p.fileDescriptors() 168 | if err != nil { 169 | return nil, err 170 | } 171 | 172 | targets := make([]string, len(names)) 173 | 174 | for i, name := range names { 175 | target, err := os.Readlink(p.path("fd", name)) 176 | if err == nil { 177 | targets[i] = target 178 | } 179 | } 180 | 181 | return targets, nil 182 | } 183 | 184 | // FileDescriptorsLen returns the number of currently open file descriptors of 185 | // a process. 186 | func (p Proc) FileDescriptorsLen() (int, error) { 187 | fds, err := p.fileDescriptors() 188 | if err != nil { 189 | return 0, err 190 | } 191 | 192 | return len(fds), nil 193 | } 194 | 195 | func (p Proc) fileDescriptors() ([]string, error) { 196 | d, err := os.Open(p.path("fd")) 197 | if err != nil { 198 | return nil, err 199 | } 200 | defer d.Close() 201 | 202 | names, err := d.Readdirnames(-1) 203 | if err != nil { 204 | return nil, fmt.Errorf("could not read %s: %s", d.Name(), err) 205 | } 206 | 207 | return names, nil 208 | } 209 | 210 | func (p Proc) path(pa ...string) string { 211 | return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) 212 | } 213 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_io.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | ) 8 | 9 | // ProcIO models the content of /proc//io. 10 | type ProcIO struct { 11 | // Chars read. 12 | RChar uint64 13 | // Chars written. 14 | WChar uint64 15 | // Read syscalls. 16 | SyscR uint64 17 | // Write syscalls. 18 | SyscW uint64 19 | // Bytes read. 20 | ReadBytes uint64 21 | // Bytes written. 22 | WriteBytes uint64 23 | // Bytes written, but taking into account truncation. See 24 | // Documentation/filesystems/proc.txt in the kernel sources for 25 | // detailed explanation. 26 | CancelledWriteBytes int64 27 | } 28 | 29 | // NewIO creates a new ProcIO instance from a given Proc instance. 30 | func (p Proc) NewIO() (ProcIO, error) { 31 | pio := ProcIO{} 32 | 33 | f, err := os.Open(p.path("io")) 34 | if err != nil { 35 | return pio, err 36 | } 37 | defer f.Close() 38 | 39 | data, err := ioutil.ReadAll(f) 40 | if err != nil { 41 | return pio, err 42 | } 43 | 44 | ioFormat := "rchar: %d\nwchar: %d\nsyscr: %d\nsyscw: %d\n" + 45 | "read_bytes: %d\nwrite_bytes: %d\n" + 46 | "cancelled_write_bytes: %d\n" 47 | 48 | _, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR, 49 | &pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes) 50 | if err != nil { 51 | return pio, err 52 | } 53 | 54 | return pio, nil 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_limits.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "regexp" 8 | "strconv" 9 | ) 10 | 11 | // ProcLimits represents the soft limits for each of the process's resource 12 | // limits. For more information see getrlimit(2): 13 | // http://man7.org/linux/man-pages/man2/getrlimit.2.html. 14 | type ProcLimits struct { 15 | // CPU time limit in seconds. 16 | CPUTime int 17 | // Maximum size of files that the process may create. 18 | FileSize int 19 | // Maximum size of the process's data segment (initialized data, 20 | // uninitialized data, and heap). 21 | DataSize int 22 | // Maximum size of the process stack in bytes. 23 | StackSize int 24 | // Maximum size of a core file. 25 | CoreFileSize int 26 | // Limit of the process's resident set in pages. 27 | ResidentSet int 28 | // Maximum number of processes that can be created for the real user ID of 29 | // the calling process. 30 | Processes int 31 | // Value one greater than the maximum file descriptor number that can be 32 | // opened by this process. 33 | OpenFiles int 34 | // Maximum number of bytes of memory that may be locked into RAM. 35 | LockedMemory int 36 | // Maximum size of the process's virtual memory address space in bytes. 37 | AddressSpace int 38 | // Limit on the combined number of flock(2) locks and fcntl(2) leases that 39 | // this process may establish. 40 | FileLocks int 41 | // Limit of signals that may be queued for the real user ID of the calling 42 | // process. 43 | PendingSignals int 44 | // Limit on the number of bytes that can be allocated for POSIX message 45 | // queues for the real user ID of the calling process. 46 | MsqqueueSize int 47 | // Limit of the nice priority set using setpriority(2) or nice(2). 48 | NicePriority int 49 | // Limit of the real-time priority set using sched_setscheduler(2) or 50 | // sched_setparam(2). 51 | RealtimePriority int 52 | // Limit (in microseconds) on the amount of CPU time that a process 53 | // scheduled under a real-time scheduling policy may consume without making 54 | // a blocking system call. 55 | RealtimeTimeout int 56 | } 57 | 58 | const ( 59 | limitsFields = 3 60 | limitsUnlimited = "unlimited" 61 | ) 62 | 63 | var ( 64 | limitsDelimiter = regexp.MustCompile(" +") 65 | ) 66 | 67 | // NewLimits returns the current soft limits of the process. 68 | func (p Proc) NewLimits() (ProcLimits, error) { 69 | f, err := os.Open(p.path("limits")) 70 | if err != nil { 71 | return ProcLimits{}, err 72 | } 73 | defer f.Close() 74 | 75 | var ( 76 | l = ProcLimits{} 77 | s = bufio.NewScanner(f) 78 | ) 79 | for s.Scan() { 80 | fields := limitsDelimiter.Split(s.Text(), limitsFields) 81 | if len(fields) != limitsFields { 82 | return ProcLimits{}, fmt.Errorf( 83 | "couldn't parse %s line %s", f.Name(), s.Text()) 84 | } 85 | 86 | switch fields[0] { 87 | case "Max cpu time": 88 | l.CPUTime, err = parseInt(fields[1]) 89 | case "Max file size": 90 | l.FileLocks, err = parseInt(fields[1]) 91 | case "Max data size": 92 | l.DataSize, err = parseInt(fields[1]) 93 | case "Max stack size": 94 | l.StackSize, err = parseInt(fields[1]) 95 | case "Max core file size": 96 | l.CoreFileSize, err = parseInt(fields[1]) 97 | case "Max resident set": 98 | l.ResidentSet, err = parseInt(fields[1]) 99 | case "Max processes": 100 | l.Processes, err = parseInt(fields[1]) 101 | case "Max open files": 102 | l.OpenFiles, err = parseInt(fields[1]) 103 | case "Max locked memory": 104 | l.LockedMemory, err = parseInt(fields[1]) 105 | case "Max address space": 106 | l.AddressSpace, err = parseInt(fields[1]) 107 | case "Max file locks": 108 | l.FileLocks, err = parseInt(fields[1]) 109 | case "Max pending signals": 110 | l.PendingSignals, err = parseInt(fields[1]) 111 | case "Max msgqueue size": 112 | l.MsqqueueSize, err = parseInt(fields[1]) 113 | case "Max nice priority": 114 | l.NicePriority, err = parseInt(fields[1]) 115 | case "Max realtime priority": 116 | l.RealtimePriority, err = parseInt(fields[1]) 117 | case "Max realtime timeout": 118 | l.RealtimeTimeout, err = parseInt(fields[1]) 119 | } 120 | if err != nil { 121 | return ProcLimits{}, err 122 | } 123 | } 124 | 125 | return l, s.Err() 126 | } 127 | 128 | func parseInt(s string) (int, error) { 129 | if s == limitsUnlimited { 130 | return -1, nil 131 | } 132 | i, err := strconv.ParseInt(s, 10, 32) 133 | if err != nil { 134 | return 0, fmt.Errorf("couldn't parse value %s: %s", s, err) 135 | } 136 | return int(i), nil 137 | } 138 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_stat.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | ) 9 | 10 | // Originally, this USER_HZ value was dynamically retrieved via a sysconf call 11 | // which required cgo. However, that caused a lot of problems regarding 12 | // cross-compilation. Alternatives such as running a binary to determine the 13 | // value, or trying to derive it in some other way were all problematic. After 14 | // much research it was determined that USER_HZ is actually hardcoded to 100 on 15 | // all Go-supported platforms as of the time of this writing. This is why we 16 | // decided to hardcode it here as well. It is not impossible that there could 17 | // be systems with exceptions, but they should be very exotic edge cases, and 18 | // in that case, the worst outcome will be two misreported metrics. 19 | // 20 | // See also the following discussions: 21 | // 22 | // - https://github.com/prometheus/node_exporter/issues/52 23 | // - https://github.com/prometheus/procfs/pull/2 24 | // - http://stackoverflow.com/questions/17410841/how-does-user-hz-solve-the-jiffy-scaling-issue 25 | const userHZ = 100 26 | 27 | // ProcStat provides status information about the process, 28 | // read from /proc/[pid]/stat. 29 | type ProcStat struct { 30 | // The process ID. 31 | PID int 32 | // The filename of the executable. 33 | Comm string 34 | // The process state. 35 | State string 36 | // The PID of the parent of this process. 37 | PPID int 38 | // The process group ID of the process. 39 | PGRP int 40 | // The session ID of the process. 41 | Session int 42 | // The controlling terminal of the process. 43 | TTY int 44 | // The ID of the foreground process group of the controlling terminal of 45 | // the process. 46 | TPGID int 47 | // The kernel flags word of the process. 48 | Flags uint 49 | // The number of minor faults the process has made which have not required 50 | // loading a memory page from disk. 51 | MinFlt uint 52 | // The number of minor faults that the process's waited-for children have 53 | // made. 54 | CMinFlt uint 55 | // The number of major faults the process has made which have required 56 | // loading a memory page from disk. 57 | MajFlt uint 58 | // The number of major faults that the process's waited-for children have 59 | // made. 60 | CMajFlt uint 61 | // Amount of time that this process has been scheduled in user mode, 62 | // measured in clock ticks. 63 | UTime uint 64 | // Amount of time that this process has been scheduled in kernel mode, 65 | // measured in clock ticks. 66 | STime uint 67 | // Amount of time that this process's waited-for children have been 68 | // scheduled in user mode, measured in clock ticks. 69 | CUTime uint 70 | // Amount of time that this process's waited-for children have been 71 | // scheduled in kernel mode, measured in clock ticks. 72 | CSTime uint 73 | // For processes running a real-time scheduling policy, this is the negated 74 | // scheduling priority, minus one. 75 | Priority int 76 | // The nice value, a value in the range 19 (low priority) to -20 (high 77 | // priority). 78 | Nice int 79 | // Number of threads in this process. 80 | NumThreads int 81 | // The time the process started after system boot, the value is expressed 82 | // in clock ticks. 83 | Starttime uint64 84 | // Virtual memory size in bytes. 85 | VSize int 86 | // Resident set size in pages. 87 | RSS int 88 | 89 | fs FS 90 | } 91 | 92 | // NewStat returns the current status information of the process. 93 | func (p Proc) NewStat() (ProcStat, error) { 94 | f, err := os.Open(p.path("stat")) 95 | if err != nil { 96 | return ProcStat{}, err 97 | } 98 | defer f.Close() 99 | 100 | data, err := ioutil.ReadAll(f) 101 | if err != nil { 102 | return ProcStat{}, err 103 | } 104 | 105 | var ( 106 | ignore int 107 | 108 | s = ProcStat{PID: p.PID, fs: p.fs} 109 | l = bytes.Index(data, []byte("(")) 110 | r = bytes.LastIndex(data, []byte(")")) 111 | ) 112 | 113 | if l < 0 || r < 0 { 114 | return ProcStat{}, fmt.Errorf( 115 | "unexpected format, couldn't extract comm: %s", 116 | data, 117 | ) 118 | } 119 | 120 | s.Comm = string(data[l+1 : r]) 121 | _, err = fmt.Fscan( 122 | bytes.NewBuffer(data[r+2:]), 123 | &s.State, 124 | &s.PPID, 125 | &s.PGRP, 126 | &s.Session, 127 | &s.TTY, 128 | &s.TPGID, 129 | &s.Flags, 130 | &s.MinFlt, 131 | &s.CMinFlt, 132 | &s.MajFlt, 133 | &s.CMajFlt, 134 | &s.UTime, 135 | &s.STime, 136 | &s.CUTime, 137 | &s.CSTime, 138 | &s.Priority, 139 | &s.Nice, 140 | &s.NumThreads, 141 | &ignore, 142 | &s.Starttime, 143 | &s.VSize, 144 | &s.RSS, 145 | ) 146 | if err != nil { 147 | return ProcStat{}, err 148 | } 149 | 150 | return s, nil 151 | } 152 | 153 | // VirtualMemory returns the virtual memory size in bytes. 154 | func (s ProcStat) VirtualMemory() int { 155 | return s.VSize 156 | } 157 | 158 | // ResidentMemory returns the resident memory size in bytes. 159 | func (s ProcStat) ResidentMemory() int { 160 | return s.RSS * os.Getpagesize() 161 | } 162 | 163 | // StartTime returns the unix timestamp of the process in seconds. 164 | func (s ProcStat) StartTime() (float64, error) { 165 | stat, err := s.fs.NewStat() 166 | if err != nil { 167 | return 0, err 168 | } 169 | return float64(stat.BootTime) + (float64(s.Starttime) / userHZ), nil 170 | } 171 | 172 | // CPUTime returns the total CPU user and system time in seconds. 173 | func (s ProcStat) CPUTime() float64 { 174 | return float64(s.UTime+s.STime) / userHZ 175 | } 176 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/stat.go: -------------------------------------------------------------------------------- 1 | package procfs 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | // Stat represents kernel/system statistics. 12 | type Stat struct { 13 | // Boot time in seconds since the Epoch. 14 | BootTime int64 15 | } 16 | 17 | // NewStat returns kernel/system statistics read from /proc/stat. 18 | func NewStat() (Stat, error) { 19 | fs, err := NewFS(DefaultMountPoint) 20 | if err != nil { 21 | return Stat{}, err 22 | } 23 | 24 | return fs.NewStat() 25 | } 26 | 27 | // NewStat returns an information about current kernel/system statistics. 28 | func (fs FS) NewStat() (Stat, error) { 29 | f, err := os.Open(fs.Path("stat")) 30 | if err != nil { 31 | return Stat{}, err 32 | } 33 | defer f.Close() 34 | 35 | s := bufio.NewScanner(f) 36 | for s.Scan() { 37 | line := s.Text() 38 | if !strings.HasPrefix(line, "btime") { 39 | continue 40 | } 41 | fields := strings.Fields(line) 42 | if len(fields) != 2 { 43 | return Stat{}, fmt.Errorf("couldn't parse %s line %s", f.Name(), line) 44 | } 45 | i, err := strconv.ParseInt(fields[1], 10, 32) 46 | if err != nil { 47 | return Stat{}, fmt.Errorf("couldn't parse %s: %s", fields[1], err) 48 | } 49 | return Stat{BootTime: i}, nil 50 | } 51 | if err := s.Err(); err != nil { 52 | return Stat{}, fmt.Errorf("couldn't parse %s: %s", f.Name(), err) 53 | } 54 | 55 | return Stat{}, fmt.Errorf("couldn't parse %s, missing btime", f.Name()) 56 | } 57 | --------------------------------------------------------------------------------