go.ligato.io/vpp-agent/v3@v3.5.0/pkg/debug/debug.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 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 debug 16 17 import ( 18 _ "expvar" 19 "log" 20 "net/http" 21 _ "net/http/pprof" 22 "os" 23 "strconv" 24 "strings" 25 26 "github.com/pkg/profile" 27 ) 28 29 const ( 30 defaultServerAddr = ":1234" 31 defaultMemProfileRate = 1024 32 ) 33 34 var ( 35 debugServerAddr = os.Getenv("DEBUG_SERVER_ADDR") 36 37 profileMode = os.Getenv("DEBUG_PROFILE_MODE") 38 profilePath = os.Getenv("DEBUG_PROFILE_PATH") 39 profileMemRate = os.Getenv("DEBUG_PROFILE_MEMRATE") 40 ) 41 42 type Debug struct { 43 closer func() 44 } 45 46 func Start() interface { 47 Stop() 48 } { 49 var d Debug 50 51 d.runProfiling() 52 53 d.runServer() 54 55 return &d 56 } 57 58 func (d *Debug) Stop() { 59 if d.closer != nil { 60 d.closer() 61 } 62 } 63 64 func (d *Debug) runProfiling() { 65 var profiling func(*profile.Profile) 66 67 memRate := defaultMemProfileRate 68 if profileMemRate != "" { 69 if x, err := strconv.Atoi(profileMemRate); err == nil { 70 memRate = x 71 } 72 } 73 74 switch strings.ToLower(profileMode) { 75 case "cpu": 76 profiling = profile.CPUProfile 77 case "mem": 78 profiling = profile.MemProfileRate(memRate) 79 case "mutex": 80 profiling = profile.MutexProfile 81 case "block": 82 profiling = profile.BlockProfile 83 case "trace": 84 profiling = profile.TraceProfile 85 default: 86 // do nothing 87 return 88 } 89 90 opts := []func(*profile.Profile){ 91 profiling, 92 profile.ProfilePath(profilePath), 93 profile.NoShutdownHook, 94 } 95 96 d.closer = profile.Start(opts...).Stop 97 } 98 99 func (d *Debug) runServer() { 100 addr := debugServerAddr 101 if addr == "" { 102 addr = defaultServerAddr 103 } 104 105 log.Printf("debug server listening on: %s", addr) 106 107 go func() { 108 if err := http.ListenAndServe(addr, nil); err != nil { 109 log.Printf("debug server error: %v", err) 110 } 111 }() 112 }