1 // Copyright 2009 The Go Authors. 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.
5 // Package expvar provides a standardized interface to public variables, such
6 // as operation counters in servers. It exposes these variables via HTTP at
7 // /debug/vars in JSON format.
9 // Operations to set or modify these public variables are atomic.
11 // In addition to adding the HTTP handler, this package registers the
12 // following variables:
15 // memstats runtime.Memstats
17 // The package is sometimes only imported for the side effect of
18 // registering its HTTP handler and the above variables. To use it
19 // this way, simply link this package into your program:
36 // Var is an abstract type for all exported variables.
41 // Int is a 64-bit integer variable that satisfies the Var interface.
47 func (v *Int) String() string { return strconv.Itoa64(v.i) }
49 func (v *Int) Add(delta int64) {
55 func (v *Int) Set(value int64) {
61 // Float is a 64-bit float variable that satisfies the Var interface.
67 func (v *Float) String() string { return strconv.Ftoa64(v.f, 'g', -1) }
69 // Add adds delta to v.
70 func (v *Float) Add(delta float64) {
76 // Set sets v to value.
77 func (v *Float) Set(value float64) {
83 // Map is a string-to-Var map variable that satisfies the Var interface.
89 // KeyValue represents a single entry in a Map.
90 type KeyValue struct {
95 func (v *Map) String() string {
98 b := new(bytes.Buffer)
101 for key, val := range v.m {
105 fmt.Fprintf(b, "\"%s\": %v", key, val.String())
112 func (v *Map) Init() *Map {
113 v.m = make(map[string]Var)
117 func (v *Map) Get(key string) Var {
123 func (v *Map) Set(key string, av Var) {
129 func (v *Map) Add(key string, delta int64) {
138 // Add to Int; ignore otherwise.
139 if iv, ok := av.(*Int); ok {
144 // AddFloat adds delta to the *Float value stored under the given map key.
145 func (v *Map) AddFloat(key string, delta float64) {
154 // Add to Float; ignore otherwise.
155 if iv, ok := av.(*Float); ok {
160 // TODO(rsc): Make sure map access in separate thread is safe.
161 func (v *Map) iterate(c chan<- KeyValue) {
162 for k, v := range v.m {
168 func (v *Map) Iter() <-chan KeyValue {
169 c := make(chan KeyValue)
174 // String is a string variable, and satisfies the Var interface.
179 func (v *String) String() string { return strconv.Quote(v.s) }
181 func (v *String) Set(value string) { v.s = value }
183 // Func implements Var by calling the function
184 // and formatting the returned value using JSON.
185 type Func func() interface{}
187 func (f Func) String() string {
188 v, _ := json.Marshal(f())
192 // All published variables.
193 var vars map[string]Var = make(map[string]Var)
196 // Publish declares an named exported variable. This should be called from a
197 // package's init function when it creates its Vars. If the name is already
198 // registered then this will log.Panic.
199 func Publish(name string, v Var) {
202 if _, existing := vars[name]; existing {
203 log.Panicln("Reuse of exported var name:", name)
208 // Get retrieves a named exported variable.
209 func Get(name string) Var {
213 // RemoveAll removes all exported variables.
214 // This is for tests; don't call this on a real server.
218 vars = make(map[string]Var)
221 // Convenience functions for creating new exported variables.
223 func NewInt(name string) *Int {
229 func NewFloat(name string) *Float {
235 func NewMap(name string) *Map {
241 func NewString(name string) *String {
247 // TODO(rsc): Make sure map access in separate thread is safe.
248 func iterate(c chan<- KeyValue) {
249 for k, v := range vars {
255 func Iter() <-chan KeyValue {
256 c := make(chan KeyValue)
261 func expvarHandler(w http.ResponseWriter, r *http.Request) {
262 w.Header().Set("Content-Type", "application/json; charset=utf-8")
263 fmt.Fprintf(w, "{\n")
265 for name, value := range vars {
267 fmt.Fprintf(w, ",\n")
270 fmt.Fprintf(w, "%q: %s", name, value)
272 fmt.Fprintf(w, "\n}\n")
275 func cmdline() interface{} {
279 func memstats() interface{} {
280 return runtime.MemStats
284 http.Handle("/debug/vars", http.HandlerFunc(expvarHandler))
285 Publish("cmdline", Func(cmdline))
286 Publish("memstats", Func(memstats))