mirror of
https://github.com/divan/expvarmon.git
synced 2025-04-25 13:48:54 +08:00
Add customizable endpoints ('/debug/vars')
This commit is contained in:
parent
b4e096514e
commit
b82a1e996c
@ -11,8 +11,8 @@ import (
|
|||||||
"github.com/antonholmquist/jason"
|
"github.com/antonholmquist/jason"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExpvarsUrl is the default url for fetching expvar info.
|
// DefaultEndpoint is the default url for fetching expvar info.
|
||||||
const ExpvarsPath = "/debug/vars"
|
var DefaultEndpoint = "/debug/vars"
|
||||||
|
|
||||||
// Expvar represents fetched expvar variable.
|
// Expvar represents fetched expvar variable.
|
||||||
type Expvar struct {
|
type Expvar struct {
|
||||||
|
3
main.go
3
main.go
@ -17,12 +17,15 @@ var (
|
|||||||
varsArg = flag.String("vars", "mem:memstats.Alloc,mem:memstats.Sys,mem:memstats.HeapAlloc,mem:memstats.HeapInuse,duration:memstats.PauseNs,duration:memstats.PauseTotalNs", "Vars to monitor (comma-separated)")
|
varsArg = flag.String("vars", "mem:memstats.Alloc,mem:memstats.Sys,mem:memstats.HeapAlloc,mem:memstats.HeapInuse,duration:memstats.PauseNs,duration:memstats.PauseTotalNs", "Vars to monitor (comma-separated)")
|
||||||
dummy = flag.Bool("dummy", false, "Use dummy (console) output")
|
dummy = flag.Bool("dummy", false, "Use dummy (console) output")
|
||||||
self = flag.Bool("self", false, "Monitor itself")
|
self = flag.Bool("self", false, "Monitor itself")
|
||||||
|
endpoint = flag.String("endpoint", DefaultEndpoint, "URL endpoint for expvars")
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Usage = Usage
|
flag.Usage = Usage
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
DefaultEndpoint = *endpoint
|
||||||
|
|
||||||
// Process ports/urls
|
// Process ports/urls
|
||||||
ports, _ := ParsePorts(*urls)
|
ports, _ := ParsePorts(*urls)
|
||||||
if *self {
|
if *self {
|
||||||
|
70
utils.go
70
utils.go
@ -53,7 +53,9 @@ func flattenURLs(rawurl string, ports []string) ([]url.URL, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
baseUrl.Path = ExpvarsPath
|
if baseUrl.Path == "" {
|
||||||
|
baseUrl.Path = DefaultEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
// Create new URL for each port
|
// Create new URL for each port
|
||||||
for _, port := range ports {
|
for _, port := range ports {
|
||||||
@ -69,35 +71,9 @@ func ParsePorts(s string) ([]url.URL, error) {
|
|||||||
var urls []url.URL
|
var urls []url.URL
|
||||||
fields := strings.FieldsFunc(s, func(r rune) bool { return r == ',' })
|
fields := strings.FieldsFunc(s, func(r rune) bool { return r == ',' })
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
// Try simple 'ports range' mode, ports only ("1234-1235,80")
|
rawurl, portsRange := extractUrlAndPorts(field)
|
||||||
// Defaults to "localhost" will be used.
|
|
||||||
ports, err := parseRange(field)
|
|
||||||
if err == nil {
|
|
||||||
furls, err := flattenURLs("http://localhost", ports)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
urls = append(urls, furls...)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// then, try host:ports notation ("localhost:1234-1235,https://remote:2000,2345")
|
ports, err := parseRange(portsRange)
|
||||||
var rawurl, portsRange string
|
|
||||||
parts := strings.FieldsFunc(field, func(r rune) bool { return r == ':' })
|
|
||||||
switch len(parts) {
|
|
||||||
case 1:
|
|
||||||
// "1234-234"
|
|
||||||
rawurl = "http://localhost"
|
|
||||||
case 2:
|
|
||||||
// "localhost:1234"
|
|
||||||
rawurl, portsRange = parts[0], parts[1]
|
|
||||||
default:
|
|
||||||
// "https://user:pass@remote.name:1234"
|
|
||||||
rawurl = strings.Join(parts[:len(parts)-1], ":")
|
|
||||||
portsRange = parts[len(parts)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
ports, err = parseRange(portsRange)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrParsePorts
|
return nil, ErrParsePorts
|
||||||
}
|
}
|
||||||
@ -113,6 +89,42 @@ func ParsePorts(s string) ([]url.URL, error) {
|
|||||||
return urls, nil
|
return urls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractUrlAndPorts attempts to split url and extract raw url
|
||||||
|
// for the single port and range of ports to parse.
|
||||||
|
//
|
||||||
|
// i.e. "http://name:1234-1236/_endpoint" would return "http://name/_endpoint" and
|
||||||
|
// "1234-1236"
|
||||||
|
func extractUrlAndPorts(s string) (string, string) {
|
||||||
|
var rawurl, ports string
|
||||||
|
parts := strings.Split(s, ":")
|
||||||
|
switch len(parts) {
|
||||||
|
case 1:
|
||||||
|
// "1234-234"
|
||||||
|
rawurl = "http://localhost"
|
||||||
|
ports = parts[0]
|
||||||
|
case 2:
|
||||||
|
// "localhost:1234"
|
||||||
|
rawurl, ports = parts[0], parts[1]
|
||||||
|
default:
|
||||||
|
// "https://user:pass@remote.name:1234" or "http://name:1234-1236/_endpoint"
|
||||||
|
|
||||||
|
// construct endpoint from the first part of URI, before ports appera
|
||||||
|
rawurl = strings.Join(parts[:len(parts)-1], ":")
|
||||||
|
|
||||||
|
// get either "1234-1235" or "1234-1235/_endpoint"
|
||||||
|
lastPart := parts[len(parts)-1]
|
||||||
|
|
||||||
|
// try to find endpoint and attach it to rawurl
|
||||||
|
fields := strings.SplitN(lastPart, "/", 2)
|
||||||
|
ports = fields[0]
|
||||||
|
if len(fields) > 1 {
|
||||||
|
rawurl = fmt.Sprintf("%s/%s", rawurl, fields[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawurl, ports
|
||||||
|
}
|
||||||
|
|
||||||
// parseRange flattens port ranges, such as "1234-1240,1333"
|
// parseRange flattens port ranges, such as "1234-1240,1333"
|
||||||
func parseRange(s string) ([]string, error) {
|
func parseRange(s string) ([]string, error) {
|
||||||
portsInt, err := ranges.Parse(s)
|
portsInt, err := ranges.Parse(s)
|
||||||
|
@ -26,6 +26,29 @@ func TestUtils(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExtractUrlAndPorts(t *testing.T) {
|
||||||
|
var rawurl, ports string
|
||||||
|
rawurl, ports = extractUrlAndPorts("40000-40002")
|
||||||
|
if rawurl != "http://localhost" || ports != "40000-40002" {
|
||||||
|
t.Fatalf("extract url and ports failed: %v, %v", rawurl, ports)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawurl, ports = extractUrlAndPorts("https://example.com:1234")
|
||||||
|
if rawurl != "https://example.com" || ports != "1234" {
|
||||||
|
t.Fatalf("extract url and ports failed: %v, %v", rawurl, ports)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawurl, ports = extractUrlAndPorts("http://user:passwd@example.com:1234-1256")
|
||||||
|
if rawurl != "http://user:passwd@example.com" || ports != "1234-1256" {
|
||||||
|
t.Fatalf("extract url and ports failed: %v, %v", rawurl, ports)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawurl, ports = extractUrlAndPorts("https://example.com:1234-1256/_endpoint")
|
||||||
|
if rawurl != "https://example.com/_endpoint" || ports != "1234-1256" {
|
||||||
|
t.Fatalf("extract url and ports failed: %v, %v", rawurl, ports)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPorts(t *testing.T) {
|
func TestPorts(t *testing.T) {
|
||||||
arg := "1234,1235"
|
arg := "1234,1235"
|
||||||
ports, err := ParsePorts(arg)
|
ports, err := ParsePorts(arg)
|
||||||
@ -85,4 +108,14 @@ func TestPorts(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("err shouldn't be nil")
|
t.Fatalf("err shouldn't be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test endpoints
|
||||||
|
arg = "localhost:2000,https://example.com:1234/_custom_expvars"
|
||||||
|
ports, err = ParsePorts(arg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if ports[0].Path != "/debug/vars" || ports[1].Path != "/_custom_expvars" {
|
||||||
|
t.Fatalf("ParsePorts returns wrong data: %v", ports)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user