github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/mungegithub/features/server.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package features 18 19 import ( 20 "net/http" 21 "os" 22 23 "github.com/NYTimes/gziphandler" 24 "github.com/golang/glog" 25 "github.com/prometheus/client_golang/prometheus" 26 "github.com/prometheus/client_golang/prometheus/promhttp" 27 28 "k8s.io/kubernetes/pkg/util/sets" 29 "k8s.io/test-infra/mungegithub/github" 30 "k8s.io/test-infra/mungegithub/mungeopts" 31 "k8s.io/test-infra/mungegithub/options" 32 "k8s.io/test-infra/mungegithub/sharedmux" 33 ) 34 35 const ( 36 ServerFeatureName = "server" 37 ) 38 39 // ServerFeature runs a server and allows mungers to register handlers for paths, or 40 // prometheus metrics. 41 type ServerFeature struct { 42 *sharedmux.ConcurrentMux 43 Enabled bool 44 45 Address string 46 WWWRoot string 47 48 prometheus struct { 49 loops prometheus.Counter 50 tokenUsage prometheus.Gauge 51 } 52 53 getTokenUsage func() (int, error) 54 } 55 56 func init() { 57 s := &ServerFeature{} 58 RegisterFeature(s) 59 } 60 61 // Name is just going to return the name mungers use to request this feature 62 func (s *ServerFeature) Name() string { 63 return ServerFeatureName 64 } 65 66 // Initialize will initialize the feature. 67 func (s *ServerFeature) Initialize(config *github.Config) error { 68 config.ServeDebugStats("/stats") 69 s.ConcurrentMux = sharedmux.NewConcurrentMux(http.DefaultServeMux) 70 if len(s.Address) == 0 { 71 return nil 72 } 73 if len(s.WWWRoot) > 0 { 74 wwwStat, err := os.Stat(s.WWWRoot) 75 if !os.IsNotExist(err) && wwwStat.IsDir() { 76 s.ConcurrentMux.Handle("/", gziphandler.GzipHandler(http.FileServer(http.Dir(s.WWWRoot)))) 77 } 78 } 79 // config indicates that ServerFeature should be enabled. 80 s.Enabled = true 81 82 s.prometheus.loops = prometheus.NewCounter(prometheus.CounterOpts{ 83 Name: "mungegithub_loops", 84 Help: "Number of loops performed by the munger", 85 ConstLabels: map[string]string{"org": config.Org, "repo": config.Project, "app": mungeopts.App}, 86 }) 87 s.prometheus.tokenUsage = prometheus.NewGauge(prometheus.GaugeOpts{ 88 Name: "github_token_usage", 89 Help: "Number of github tokens used by the munger", 90 ConstLabels: map[string]string{"org": config.Org, "repo": config.Project, "app": mungeopts.App}, 91 }) 92 prometheus.MustRegister(s.prometheus.loops) 93 prometheus.MustRegister(s.prometheus.tokenUsage) 94 s.getTokenUsage = config.GetTokenUsage 95 s.ConcurrentMux.Handle("/prometheus", promhttp.Handler()) 96 97 go http.ListenAndServe(s.Address, s.ConcurrentMux) 98 return nil 99 } 100 101 // EachLoop is called at the start of every munge loop 102 func (s *ServerFeature) EachLoop() error { 103 s.prometheus.loops.Inc() 104 tokenUsage, err := s.getTokenUsage() 105 if err != nil { 106 glog.Warningf("Cannot get token usage: %v", err) 107 } else { 108 s.prometheus.tokenUsage.Set(float64(tokenUsage)) 109 } 110 return nil 111 } 112 113 // RegisterOptions registers options for this feature; returns any that require a restart when changed. 114 func (s *ServerFeature) RegisterOptions(opts *options.Options) sets.String { 115 opts.RegisterString(&s.Address, "address", ":8080", "The address to listen on for HTTP Status") 116 opts.RegisterString(&s.WWWRoot, "www", "www", "Path to static web files to serve from the webserver") 117 return sets.NewString("address", "www") 118 }