2016-07-22 19:49:23 +00:00
# Circonus metrics tracking for Go applications
2017-01-04 21:47:38 +00:00
This library supports named counters, gauges and histograms. It also provides convenience wrappers for registering latency instrumented functions with Go's builtin http server.
2016-07-22 19:49:23 +00:00
2017-01-04 21:47:38 +00:00
Initializing only requires setting an [API Token ](https://login.circonus.com/user/tokens ) at a minimum.
## Options
See [OPTIONS.md ](OPTIONS.md ) for information on all of the available cgm options.
2016-07-22 19:49:23 +00:00
## Example
2017-01-04 21:47:38 +00:00
### Bare bones minimum
A working cut-n-past example. Simply set the required environment variable `CIRCONUS_API_TOKEN` and run.
2016-07-22 19:49:23 +00:00
```go
package main
import (
2017-01-27 01:16:19 +00:00
"log"
"math/rand"
"os"
2017-01-04 21:47:38 +00:00
"os/signal"
"syscall"
2017-01-27 01:16:19 +00:00
"time"
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
cgm "github.com/circonus-labs/circonus-gometrics"
2016-07-22 19:49:23 +00:00
)
func main() {
2016-11-02 19:34:30 +00:00
logger := log.New(os.Stdout, "", log.LstdFlags)
2017-01-27 01:16:19 +00:00
logger.Println("Configuring cgm")
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
cmc := & cgm.Config{}
2017-03-31 00:03:13 +00:00
cmc.Debug = false // set to true for debug messages
2017-01-27 01:16:19 +00:00
cmc.Log = logger
2016-12-14 00:12:26 +00:00
2017-01-27 01:16:19 +00:00
// Circonus API Token key (https://login.circonus.com/user/tokens)
cmc.CheckManager.API.TokenKey = os.Getenv("CIRCONUS_API_TOKEN")
2016-11-02 19:34:30 +00:00
2017-01-27 01:16:19 +00:00
logger.Println("Creating new cgm instance")
2016-11-02 19:34:30 +00:00
2017-01-27 01:16:19 +00:00
metrics, err := cgm.NewCirconusMetrics(cmc)
if err != nil {
2017-01-04 21:47:38 +00:00
logger.Println(err)
2017-01-27 01:16:19 +00:00
os.Exit(1)
}
2017-01-04 21:47:38 +00:00
2017-01-27 01:16:19 +00:00
src := rand.NewSource(time.Now().UnixNano())
rnd := rand.New(src)
2017-01-04 21:47:38 +00:00
logger.Println("Adding ctrl-c trap")
2017-01-27 01:16:19 +00:00
c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
< -c
logger.Println("Received CTRL-C, flushing outstanding metrics before exit")
metrics.Flush()
os.Exit(0)
}()
logger.Println("Starting to send metrics")
// number of "sets" of metrics to send
max := 60
for i := 1; i < max ; i + + {
logger.Printf("\tmetric set %d of %d", i, 60)
metrics.Timing("foo", rnd.Float64()*10)
metrics.Increment("bar")
metrics.Gauge("baz", 10)
2017-01-04 21:47:38 +00:00
time.Sleep(time.Second)
2017-01-27 01:16:19 +00:00
}
2016-12-14 00:12:26 +00:00
2017-01-04 21:47:38 +00:00
metrics.SetText("fini", "complete")
2017-01-27 01:16:19 +00:00
logger.Println("Flushing any outstanding metrics manually")
metrics.Flush()
2017-01-04 21:47:38 +00:00
}
```
### A more complete example
A working, cut-n-paste example with all options available for modification. Also, demonstrates metric tagging.
```go
package main
import (
2017-01-27 01:16:19 +00:00
"log"
"math/rand"
"os"
2017-01-04 21:47:38 +00:00
"os/signal"
"syscall"
2017-01-27 01:16:19 +00:00
"time"
2017-01-04 21:47:38 +00:00
2017-01-27 01:16:19 +00:00
cgm "github.com/circonus-labs/circonus-gometrics"
2017-01-04 21:47:38 +00:00
)
func main() {
logger := log.New(os.Stdout, "", log.LstdFlags)
2017-01-27 01:16:19 +00:00
logger.Println("Configuring cgm")
2017-01-04 21:47:38 +00:00
2017-01-27 01:16:19 +00:00
cmc := & cgm.Config{}
2017-01-04 21:47:38 +00:00
// General
2017-01-27 01:16:19 +00:00
cmc.Interval = "10s"
2017-01-04 21:47:38 +00:00
cmc.Log = logger
2017-01-27 01:16:19 +00:00
cmc.Debug = false
2017-01-04 21:47:38 +00:00
cmc.ResetCounters = "true"
cmc.ResetGauges = "true"
cmc.ResetHistograms = "true"
cmc.ResetText = "true"
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
// Circonus API configuration options
cmc.CheckManager.API.TokenKey = os.Getenv("CIRCONUS_API_TOKEN")
cmc.CheckManager.API.TokenApp = os.Getenv("CIRCONUS_API_APP")
cmc.CheckManager.API.URL = os.Getenv("CIRCONUS_API_URL")
// Check configuration options
2017-02-02 21:19:55 +00:00
cmc.CheckManager.Check.SubmissionURL = os.Getenv("CIRCONUS_SUBMISSION_URL")
2017-01-27 01:16:19 +00:00
cmc.CheckManager.Check.ID = os.Getenv("CIRCONUS_CHECK_ID")
cmc.CheckManager.Check.InstanceID = ""
cmc.CheckManager.Check.DisplayName = ""
2017-01-04 21:47:38 +00:00
cmc.CheckManager.Check.TargetHost = ""
// if hn, err := os.Hostname(); err == nil {
// cmc.CheckManager.Check.TargetHost = hn
// }
2017-01-27 01:16:19 +00:00
cmc.CheckManager.Check.SearchTag = ""
cmc.CheckManager.Check.Secret = ""
cmc.CheckManager.Check.Tags = ""
cmc.CheckManager.Check.MaxURLAge = "5m"
cmc.CheckManager.Check.ForceMetricActivation = "false"
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
// Broker configuration options
cmc.CheckManager.Broker.ID = ""
cmc.CheckManager.Broker.SelectTag = ""
cmc.CheckManager.Broker.MaxResponseTime = "500ms"
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
logger.Println("Creating new cgm instance")
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
metrics, err := cgm.NewCirconusMetrics(cmc)
if err != nil {
2017-01-04 21:47:38 +00:00
logger.Println(err)
2017-01-27 01:16:19 +00:00
os.Exit(1)
}
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
src := rand.NewSource(time.Now().UnixNano())
rnd := rand.New(src)
2016-07-22 19:49:23 +00:00
2016-11-02 19:34:30 +00:00
logger.Println("Adding ctrl-c trap")
2017-01-27 01:16:19 +00:00
c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
< -c
logger.Println("Received CTRL-C, flushing outstanding metrics before exit")
metrics.Flush()
os.Exit(0)
}()
2016-07-22 19:49:23 +00:00
2016-11-02 19:34:30 +00:00
// Add metric tags (append to any existing tags on specified metric)
metrics.AddMetricTags("foo", []string{"cgm:test"})
metrics.AddMetricTags("baz", []string{"cgm:test"})
2017-01-27 01:16:19 +00:00
logger.Println("Starting to send metrics")
2016-11-02 19:34:30 +00:00
2017-01-27 01:16:19 +00:00
// number of "sets" of metrics to send
max := 60
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
for i := 1; i < max ; i + + {
logger.Printf("\tmetric set %d of %d", i, 60)
2016-11-02 19:34:30 +00:00
2017-01-27 01:16:19 +00:00
metrics.Timing("foo", rnd.Float64()*10)
metrics.Increment("bar")
metrics.Gauge("baz", 10)
2016-11-02 19:34:30 +00:00
if i == 35 {
// Set metric tags (overwrite current tags on specified metric)
metrics.SetMetricTags("baz", []string{"cgm:reset_test", "cgm:test2"})
}
time.Sleep(time.Second)
2017-01-27 01:16:19 +00:00
}
2016-07-22 19:49:23 +00:00
2017-01-27 01:16:19 +00:00
logger.Println("Flushing any outstanding metrics manually")
metrics.Flush()
2016-07-22 19:49:23 +00:00
}
```
### HTTP Handler wrapping
2017-01-04 21:47:38 +00:00
```go
2016-07-22 19:49:23 +00:00
http.HandleFunc("/", metrics.TrackHTTPLatency("/", handler_func))
```
### HTTP latency example
2017-01-04 21:47:38 +00:00
```go
2016-07-22 19:49:23 +00:00
package main
import (
"os"
"fmt"
"net/http"
cgm "github.com/circonus-labs/circonus-gometrics"
)
func main() {
cmc := & cgm.Config{}
cmc.CheckManager.API.TokenKey = os.Getenv("CIRCONUS_API_TOKEN")
2016-09-02 22:05:09 +00:00
2016-07-22 19:49:23 +00:00
metrics, err := cgm.NewCirconusMetrics(cmc)
if err != nil {
panic(err)
}
http.HandleFunc("/", metrics.TrackHTTPLatency("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}))
http.ListenAndServe(":8080", http.DefaultServeMux)
}
```
2016-09-02 22:05:09 +00:00
Unless otherwise noted, the source files are distributed under the BSD-style license found in the LICENSE file.