== A surprise to watch out for with Go's expvar package (in expvar.Var) The standard [[expvar package https://golang.org/pkg/expvar/]] is a handy thing for easily exposing counters, values, and so on in a way that can be queried from outside your running program. As you might expect, it ultimately works through an interface type, [[_expvar.Var_ https://golang.org/pkg/expvar/#Var]]. This interface is very simple: .pn prewrap on > type Var interface { > String() string > } If you see this definition, your eyes may light up with familiarity (as mine did), because this is exactly the extremely standard [[fmt.Stringer https://golang.org/pkg/fmt/#Stringer]] interface, where everything that has a _.String()_ method can be handled by a lot of things. So of course you might well write code like this: > m := expvar.NewMap("myapp") > // the time.Time type has a String() > // method, so this will totally work. > m.Set("startTime", time.Now()) If you do this, everything will work right up to the point where [[programs https://github.com/divan/expvarmon]] that parse the JSON returned by the _/debug/vars_ endpoint start failing with weird errors. If you look at the raw JSON, what you will see is something like this: > [...], "startTime": 2016-04-01 17:49:09.385829528 -0400 EDT, > "anothervar": "something", [...] In case you don't see the problem (as I didn't for some time), the string value for "startTime" doesn't have quotes around it, which makes it very invalid JSON. Go's current JSON parser starts trying to interpret the starting '2016-' bit as a number, then runs into the '-' and complains about it. What is happening is that the expvar.Var String() interface method is misnamed; it should really be called something like _JSON()_. What the Var.String() method is actually required to do is produce the JSON representation of the Var as a _string_; for strings, this requires them to be quoted. A normal Stringer _.String()_ method doesn't do this quoting, of course, because it would get in the way. The two interpretations of _.String()_ are not really compatible, but there is no way to tell them apart and Go's implicitly satisfied interfaces will let you substitute one for the other (as I did when I tried to use time.Time as a Var). So the takeaway here is that just because something has a _.String()_ doesn't mean you can use it as an expvar.Var; in fact, you probably can't. Anything that's designed to be used as an expvar.Var will specifically say so in its documentation (or at least it should). Anything that has a _.String()_ but doesn't mention expvar should be assumed to be satisfying the far more common fmt.Stringer interface instead. (I don't have any clever solution for this. And I think [[the Go 1 API compatibility guarantee https://golang.org/doc/go1compat]] will keep this from changing, as _expvar.Var_ was in its current form in the initial Go 1 release.)