Skip to content

Commit

Permalink
remove need for nil checks around statsd metrics (#932)
Browse files Browse the repository at this point in the history
Currently, we have to check if `autographer.stats` is nil anywhere we
want to emit a statsd metric. This is error-prone and verbose. Work for
AUT-150 (and more) would be easier if we do this here.

This patch makes the `autographer.stats` field always non-nil. By
default, `autographer`s created with `newAutographer` will have a
`statsd.NoOpClient` object for its `stats` and if the autograph config
has a statsd server configured, it will be replaced with a real statsd
client when `autographer.addStats` is called. That addStats call will
now always occur in autograph's main function.

This moves the conditional for checking if the statsd server is
configured into autographer.addStats. However, it would probably be
better in the future for us to have this and the similar
`autograph.add*` methods moved into the `newAutographer` contructor.
This, though, at least makes the autographer type a lil safer on
construction.

This means that we use `statds.ClientInterface` instead of
`*statsd.Client` everywhere to fit both client types.

Along the way, we also have to fix up the main_test.go that was
reproducing that conditional from the main inside it. We also fix an
signer/xpi test that was depending on a statsd server running but not
actually needing it to finish.

This patch doesn't remove all of the nil checks. A follow up will be
made to do so.

Updates AUT-159
Updates AUT-150
  • Loading branch information
jmhodges authored Aug 1, 2024
1 parent 3e85ead commit 5f97ba3
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 25 deletions.
11 changes: 5 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type configuration struct {
// with all signers and permissions configured
type autographer struct {
db *database.Handler
stats *statsd.Client
stats statsd.ClientInterface
nonces *lru.Cache
debug bool
heartbeatConf *heartbeatConfig
Expand Down Expand Up @@ -166,11 +166,9 @@ func run(conf configuration, listen string, debug bool) {
ag.initHSM(conf)
}

if conf.Statsd.Addr != "" {
err = ag.addStats(conf)
if err != nil {
log.Fatal(err)
}
err = ag.addStats(conf)
if err != nil {
log.Fatal(err)
}

err = ag.addSigners(conf.Signers)
Expand Down Expand Up @@ -292,6 +290,7 @@ func newAutographer(cachesize int) (a *autographer) {
a.authBackend = newInMemoryAuthBackend()
a.nonces, err = lru.New(cachesize)
a.exit = make(chan interface{})
a.stats = &statsd.NoOpClient{}
if err != nil {
log.Fatal(err)
}
Expand Down
8 changes: 3 additions & 5 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@ func TestMain(m *testing.M) {
if err != nil {
log.Fatal(err)
}
if conf.Statsd.Addr != "" {
err = ag.addStats(conf)
if err != nil {
log.Fatal(err)
}
err = ag.addStats(conf)
if err != nil {
log.Fatal(err)
}
if conf.HawkTimestampValidity != "" {
ag.hawkMaxTimestampSkew, err = time.ParseDuration(conf.HawkTimestampValidity)
Expand Down
7 changes: 2 additions & 5 deletions signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,14 +523,11 @@ type StatsClient struct {
signerTags []string

// stats is the statsd client for reporting metrics
stats *statsd.Client
stats statsd.ClientInterface
}

// NewStatsClient makes a new stats client
func NewStatsClient(signerConfig Configuration, stats *statsd.Client) (*StatsClient, error) {
if stats == nil {
return nil, fmt.Errorf("xpi: statsd client is nil. Could not create StatsClient for signer %s", signerConfig.ID)
}
func NewStatsClient(signerConfig Configuration, stats statsd.ClientInterface) (*StatsClient, error) {
return &StatsClient{
stats: stats,
signerTags: []string{
Expand Down
7 changes: 1 addition & 6 deletions signer/xpi/xpi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,7 @@ func TestSignFile(t *testing.T) {
StatsSampleRate: 10 * time.Second,
}

statsdClient, err := statsd.NewBuffered("localhost:8135", 1)
if err != nil {
t.Fatalf("passing testcase %d: Error constructing statsdClient: %v", i, err)
}
statsdClient.Namespace = "test_autograph_stats_ns"
signerStatsClient, err := signer.NewStatsClient(testcase, statsdClient)
signerStatsClient, err := signer.NewStatsClient(testcase, &statsd.NoOpClient{})
if err != nil {
t.Fatalf("passing testcase %d: Error constructing signer.StatsdClient: %v", i, err)
}
Expand Down
17 changes: 14 additions & 3 deletions stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,19 @@ func loadStatsd(conf configuration) (*statsd.Client, error) {
return statsdClient, nil
}

func (a *autographer) addStats(conf configuration) (err error) {
a.stats, err = loadStatsd(conf)
func (a *autographer) addStats(conf configuration) error {
if conf.Statsd.Addr == "" {
// a.stats is set to a safe value in newAutographer, so we leave it
// alone and return.
log.Infof("Statsd left disabled as no `statsd.addr` was provided in config")
return nil
}

stats, err := loadStatsd(conf)
if err != nil {
return err
}
a.stats = stats
log.Infof("Statsd enabled at %s with namespace %s", conf.Statsd.Addr, conf.Statsd.Namespace)
return err
return nil
}

0 comments on commit 5f97ba3

Please sign in to comment.