This implements a basic Spectator library for instrumenting Go applications. It consists of a thin client designed to send metrics through spectatord.
This library currently targets the latest two stable versions of Go.
There is one language feature used in the project which requires at least 1.21 - the log/slog structured logging library.
package main
import (
"github.com/Netflix/spectator-go/v2/spectator"
"github.com/Netflix/spectator-go/v2/spectator/meter"
"strconv"
"time"
)
type Server struct {
registry spectator.Registry
requestCountId *meter.Id
requestLatency *meter.Timer
responseSizes *meter.DistributionSummary
}
type Request struct {
country string
}
type Response struct {
status int
size int64
}
func (s *Server) Handle(request *Request) (res *Response) {
start := time.Now()
// initialize response
res = &Response{200, 64}
// Update the counter with dimensions based on the request.
tags := map[string]string{
"country": request.country,
"status": strconv.Itoa(res.status),
}
requestCounterWithTags := s.requestCountId.WithTags(tags)
counter := s.registry.CounterWithId(requestCounterWithTags)
counter.Increment()
// ...
s.requestLatency.Record(time.Since(start))
s.responseSizes.Record(res.size)
return
}
func newServer(registry spectator.Registry) *Server {
return &Server{
registry,
registry.NewId("server.requestCount", nil),
registry.Timer("server.requestLatency", nil),
registry.DistributionSummary("server.responseSizes", nil),
}
}
func getNextRequest() *Request {
// ...
return &Request{"US"}
}
func main() {
commonTags := map[string]string{"nf.platform": "my_platform", "process_name": "my_process"}
// if desired, replace the logger with a custom one, using the third parameter here:
config, _ := spectator.NewConfig("", commonTags, nil)
registry, _ := spectator.NewRegistry(config)
defer registry.Close()
server := newServer(registry)
for i := 1; i < 3; i++ {
// get a request
req := getNextRequest()
server.Handle(req)
}
}Logging is implemented with the standard Golang slog package. The logger defines interfaces for Debugf, Infof, and Errorf. There are useful messages implemented at the Debug level which can help diagnose the metric publishing workflow.
Use spectator-go-runtime-metrics. Follow instructions in the README to enable collection.
Version 0.3 consists of a major rewrite that turns spectator-go into a thin client designed to send metrics through spectatord. As a result some functionality has been moved to other packages or removed.
spectator.Registry now supports different writers. The default writer is writer.UdpWriter which sends metrics
to spectatord through UDP.
Writers can be configured through spectator.Config.Location.
Possible values are:
none: Configures a no-op writer that does nothing. Can be used to disable metrics collection.stdout: Writes metrics to stdout.stderr: Writes metrics to stderr.memory: Writes metrics to memory. Useful for testing.file:///path/to/file: Writes metrics to a file.unix:///path/to/socket: Writes metrics to a Unix domain socket.udp://host:port: Writes metrics to a UDP socket.
Location can also be set through the environment variable SPECTATOR_OUTPUT_LOCATION. If both are set, the environment variable
takes precedence over the passed config.
The environment variable SPECTATOR_OUTPUT_LOCATION can be set to none to disable metrics collection.
The following new Meters have been added:
meter.MaxGaugemeter.Gaugewith TTL
Common tags are now automatically added to all Meters. Their values are read from the environment variables.
| Tag | Environment Variable |
|---|---|
| nf.container | TITUS_CONTAINER_NAME |
| nf.process | NETFLIX_PROCESS_NAME |
Tags from environment variables take precedence over tags passed on code when creating the Config.
Note that common tags sourced by spectatord can't be overwritten.
Configis now created through a constructor which throws error if the passed in parameters are not valid.Configmembers are now private.
- Runtime metrics collection has been moved to spectator-go-runtime-metrics. Follow instructions in the README to enable collection.
- Some types have been moved to different packages. For example,
spectator.Counteris now inmeter.Counter.
spectator.HttpClienthas been removed. Use the standardhttp.Clientinstead.spectator.Meters no longer has aMeasure() []Measurementfunction. Meters are now stateless and do not store measurements.spectator.Clockhas been removed. Use the standardtimepackage instead.spectator.Confighas been greatly simplified.spectator.Registryno longer has aStart()function. It is now automatically started when created.spectator.Registryno longer has aStop()function. Instead, useClose()to close the registry. Once the registry is closed, it can't be started again.spectator.Config.IpcTimerRecordhas been removed. Use ameter.Timerinstead to record Ipc metrics.spectator.MeterFactoryFunhas been removed. If you need to create a custom meter you can do so by wrapping one of the meters returned byspectator.Registry.spectator.Registryno longer reportsspectator.measurementsmetrics. Instead, you can use spectatord metrics to troubleshoot.spectator.Registryno longer keep track of the Meters it creates. This means that you can't get a list of all Meters from the Registry. If you need to keep track of Meters, you can do so in your application code.Percentile*meters no longer support defining min/max values.spectator.Registryno longer allows setting a different logger after creation. A custom logger can be set in thespectator.Configbefore creating the Registry.- File-based configuration is no longer supported.
- Make sure you're not relying on any of the removed functionality.
- Update imports to use
meterspackage instead ofspectatorfor Meters. - If you want to collect runtime metrics pull spectator-go-runtime-metrics and follow the instructions in the README
- If you use
PercentileDistributionSummaryorPercentileTimeryou need to update your code to use the respective functions provided by the Registry to initialize these meters. - Remove dependency on Spectator Go Internal configuration library. Such dependency is no longer required.
- There is no longer an option to start or stop the registry at runtime. If you need to configure a registry that
doesn't emit metrics, you can use the
spectator.Config.Locationoption withnoneto configure a no-op writer.