Commit 426d1652 authored by Matthew Holt's avatar Matthew Holt

expvar: Allow no args; publish number of goroutines

parent a3127bed
package setup package setup
import ( import (
_ "expvar" stdexpvar "expvar"
"runtime"
"sync"
"github.com/mholt/caddy/middleware" "github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/expvar" "github.com/mholt/caddy/middleware/expvar"
...@@ -14,6 +16,9 @@ func ExpVar(c *Controller) (middleware.Middleware, error) { ...@@ -14,6 +16,9 @@ func ExpVar(c *Controller) (middleware.Middleware, error) {
return nil, err return nil, err
} }
// publish any extra information/metrics we may want to capture
publishExtraVars()
expvar := expvar.ExpVar{Resource: resource} expvar := expvar.ExpVar{Resource: resource}
return func(next middleware.Handler) middleware.Handler { return func(next middleware.Handler) middleware.Handler {
...@@ -24,12 +29,13 @@ func ExpVar(c *Controller) (middleware.Middleware, error) { ...@@ -24,12 +29,13 @@ func ExpVar(c *Controller) (middleware.Middleware, error) {
func expVarParse(c *Controller) (expvar.Resource, error) { func expVarParse(c *Controller) (expvar.Resource, error) {
var resource expvar.Resource var resource expvar.Resource
var err error var err error
for c.Next() { for c.Next() {
args := c.RemainingArgs() args := c.RemainingArgs()
switch len(args) { switch len(args) {
case 0:
resource = expvar.Resource(defaultExpvarPath)
case 1: case 1:
resource = expvar.Resource(args[0]) resource = expvar.Resource(args[0])
default: default:
...@@ -39,3 +45,16 @@ func expVarParse(c *Controller) (expvar.Resource, error) { ...@@ -39,3 +45,16 @@ func expVarParse(c *Controller) (expvar.Resource, error) {
return resource, err return resource, err
} }
func publishExtraVars() {
// By using sync.Once instead of an init() function, we don't clutter
// the app's expvar export unnecessarily, or risk colliding with it.
publishOnce.Do(func() {
stdexpvar.Publish("Goroutines", stdexpvar.Func(func() interface{} {
return runtime.NumGoroutine()
}))
})
}
var publishOnce sync.Once // publishing variables should only be done once
var defaultExpvarPath = "/debug/vars"
...@@ -7,29 +7,32 @@ import ( ...@@ -7,29 +7,32 @@ import (
) )
func TestExpvar(t *testing.T) { func TestExpvar(t *testing.T) {
c := NewTestController(`expvar /d/v`) c := NewTestController(`expvar`)
mid, err := ExpVar(c) mid, err := ExpVar(c)
if err != nil { if err != nil {
t.Errorf("Expected no errors, got: %v", err) t.Errorf("Expected no errors, got: %v", err)
} }
if mid == nil {
t.Fatal("Expected middleware, was nil instead")
}
c = NewTestController(`expvar /d/v`)
mid, err = ExpVar(c)
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
if mid == nil { if mid == nil {
t.Fatal("Expected middleware, was nil instead") t.Fatal("Expected middleware, was nil instead")
} }
handler := mid(EmptyNext) handler := mid(EmptyNext)
myHandler, ok := handler.(expvar.ExpVar) myHandler, ok := handler.(expvar.ExpVar)
if !ok { if !ok {
t.Fatalf("Expected handler to be type ExpVar, got: %#v", handler) t.Fatalf("Expected handler to be type ExpVar, got: %#v", handler)
} }
if myHandler.Resource != "/d/v" { if myHandler.Resource != "/d/v" {
t.Errorf("Expected /d/v as expvar resource") t.Errorf("Expected /d/v as expvar resource")
} }
if !SameNext(myHandler.Next, EmptyNext) { if !SameNext(myHandler.Next, EmptyNext) {
t.Error("'Next' field of handler was not set properly") t.Error("'Next' field of handler was not set properly")
} }
......
...@@ -2,6 +2,7 @@ CHANGES ...@@ -2,6 +2,7 @@ CHANGES
<master> <master>
- New pprof directive for exposing process performance profile - New pprof directive for exposing process performance profile
- New expvar directive for reading memory/GC performance
- New -restart option to force in-process restarts on Unix systems - New -restart option to force in-process restarts on Unix systems
- Toggle case-sensitive path matching with environment variable - Toggle case-sensitive path matching with environment variable
- proxy: New max_conns setting to limit max connections per upstream - proxy: New max_conns setting to limit max connections per upstream
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment