diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index d386ba5..65e83a6 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,8 +1,38 @@ { "ImportPath": "github.com/scoiatael/archai", - "GoVersion": "go1.7", + "GoVersion": "go1.8", "GodepVersion": "v79", "Deps": [ + { + "ImportPath": "github.com/DataDog/datadog-go/statsd", + "Comment": "1.0.0-10-g6fa3e39", + "Rev": "6fa3e39b86f8cbb638a971f2a90b9ebd98074c6b" + }, + { + "ImportPath": "github.com/geekypanda/httpcache", + "Comment": "v0.0.1-11-g76ba6c6", + "Rev": "76ba6c68462ae362cda7564c44492b95322b363a" + }, + { + "ImportPath": "github.com/geekypanda/httpcache/internal", + "Comment": "v0.0.1-11-g76ba6c6", + "Rev": "76ba6c68462ae362cda7564c44492b95322b363a" + }, + { + "ImportPath": "github.com/geekypanda/httpcache/internal/nethttp", + "Comment": "v0.0.1-11-g76ba6c6", + "Rev": "76ba6c68462ae362cda7564c44492b95322b363a" + }, + { + "ImportPath": "github.com/geekypanda/httpcache/internal/nethttp/rule", + "Comment": "v0.0.1-11-g76ba6c6", + "Rev": "76ba6c68462ae362cda7564c44492b95322b363a" + }, + { + "ImportPath": "github.com/geekypanda/httpcache/internal/server", + "Comment": "v0.0.1-11-g76ba6c6", + "Rev": "76ba6c68462ae362cda7564c44492b95322b363a" + }, { "ImportPath": "github.com/gocql/gocql", "Comment": "pre-node-events-459-g9d95e30", @@ -27,10 +57,63 @@ "ImportPath": "github.com/golang/snappy", "Rev": "7db9049039a047d955fe8c19b83c8ff5abd765c7" }, + { + "ImportPath": "github.com/google/go-github/github", + "Rev": "04b64a7f8ccd7701ed660231f3805bd585fb486c" + }, + { + "ImportPath": "github.com/google/go-querystring/query", + "Rev": "53e6ce116135b80d037921a7fdd5138cf32d7a8a" + }, { "ImportPath": "github.com/hailocab/go-hostpool", "Rev": "e80d13ce29ede4452c43dea11e79b9bc8a15b478" }, + { + "ImportPath": "github.com/hashicorp/go-version", + "Rev": "03c5bf6be031b6dd45afec16b1cf94fc8938bc77" + }, + { + "ImportPath": "github.com/imdario/mergo", + "Comment": "0.2.2-6-g50d4dbd", + "Rev": "50d4dbd4eb0e84778abe37cefef140271d96fade" + }, + { + "ImportPath": "github.com/iris-contrib/formBinder", + "Rev": "81b6a071e35797b83562caf4b3cad24dc01912dc" + }, + { + "ImportPath": "github.com/kataras/go-errors", + "Rev": "6fb46ef666f60ce19b5cc73906d531645d5bf8bc" + }, + { + "ImportPath": "github.com/kataras/go-fs", + "Rev": "7f223df24981d99323fdf283bfb5f6f85905b68c" + }, + { + "ImportPath": "github.com/kataras/go-serializer", + "Rev": "b61f2e8acda9377f80b5bf183a79ea32b9838f9d" + }, + { + "ImportPath": "github.com/kataras/go-serializer/json", + "Rev": "b61f2e8acda9377f80b5bf183a79ea32b9838f9d" + }, + { + "ImportPath": "github.com/kataras/go-serializer/jsonp", + "Rev": "b61f2e8acda9377f80b5bf183a79ea32b9838f9d" + }, + { + "ImportPath": "github.com/kataras/go-serializer/markdown", + "Rev": "b61f2e8acda9377f80b5bf183a79ea32b9838f9d" + }, + { + "ImportPath": "github.com/kataras/go-serializer/xml", + "Rev": "b61f2e8acda9377f80b5bf183a79ea32b9838f9d" + }, + { + "ImportPath": "github.com/kataras/go-template", + "Rev": "8fa0a515640e526dabba4752e4188e5a3784ce21" + }, { "ImportPath": "github.com/klauspost/compress/flate", "Comment": "v1.2.1-3-g14c9a76", @@ -56,6 +139,10 @@ "Comment": "v1.1-2-g1bab8b3", "Rev": "1bab8b35b6bb565f92cbc97939610af9369f942a" }, + { + "ImportPath": "github.com/microcosm-cc/bluemonday", + "Rev": "e79763773ab6222ca1d5a7cbd9d62d83c1f77081" + }, { "ImportPath": "github.com/onsi/ginkgo", "Comment": "v1.2.0-90-gbb93381", @@ -206,6 +293,15 @@ "Comment": "v0.8.0-2-g248dadf", "Rev": "248dadf4e9068a0b3e79f02ed0a610d935de5302" }, + { + "ImportPath": "github.com/russross/blackfriday", + "Comment": "v1.4-40-g5f33e7b", + "Rev": "5f33e7b7878355cd2b7e6b8eefc48a5472c69f70" + }, + { + "ImportPath": "github.com/shurcooL/sanitized_anchor_name", + "Rev": "1dba4b3954bc059efc3991ec364f9f9a35f597d2" + }, { "ImportPath": "github.com/urfave/cli", "Comment": "v1.19.1-21-g347a988", @@ -230,10 +326,30 @@ "Comment": "v20160617-91-g32c72cd", "Rev": "32c72cde80f0c591604f825586d6a4bbbb39d9c5" }, + { + "ImportPath": "golang.org/x/crypto/acme", + "Rev": "453249f01cfeb54c3d549ddb75ff152ca243f9d8" + }, + { + "ImportPath": "golang.org/x/crypto/acme/autocert", + "Rev": "453249f01cfeb54c3d549ddb75ff152ca243f9d8" + }, { "ImportPath": "golang.org/x/net/context", "Rev": "61557ac0112b576429a0df080e1c2cef5dfbb642" }, + { + "ImportPath": "golang.org/x/net/context/ctxhttp", + "Rev": "61557ac0112b576429a0df080e1c2cef5dfbb642" + }, + { + "ImportPath": "golang.org/x/net/html", + "Rev": "61557ac0112b576429a0df080e1c2cef5dfbb642" + }, + { + "ImportPath": "golang.org/x/net/html/atom", + "Rev": "61557ac0112b576429a0df080e1c2cef5dfbb642" + }, { "ImportPath": "golang.org/x/sys/unix", "Rev": "075e574b89e4c2d22f2286a7e2b919519c6f3547" @@ -243,6 +359,14 @@ "Comment": "v0.9.0", "Rev": "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4" }, + { + "ImportPath": "gopkg.in/kataras/iris.v6", + "Rev": "37285b908f73781858ba99d0b8c936aad428c9e7" + }, + { + "ImportPath": "gopkg.in/kataras/iris.v6/adaptors/httprouter", + "Rev": "37285b908f73781858ba99d0b8c936aad428c9e7" + }, { "ImportPath": "gopkg.in/yaml.v2", "Rev": "a3f3340b5840cee44f372bddb5880fcbc419b46a" diff --git a/actions/context.go b/actions/context.go index a3d88c8..9b8ac13 100644 --- a/actions/context.go +++ b/actions/context.go @@ -3,6 +3,7 @@ package actions import ( "github.com/scoiatael/archai/http" "github.com/scoiatael/archai/persistence" + "github.com/scoiatael/archai/telemetry" ) type HttpHandler interface { @@ -17,6 +18,7 @@ type Context interface { Version() string HandleErr(error) HttpHandler() HttpHandler + Telemetry() telemetry.Datadog } type Action interface { diff --git a/actions/http_server.go b/actions/http_server.go index 4769873..925d1af 100644 --- a/actions/http_server.go +++ b/actions/http_server.go @@ -39,6 +39,7 @@ func (hs HttpServer) Run(c Context) error { events[i]["blob"] = payload } root["results"] = events + c.Telemetry().Incr("read", []string{"stream:" + stream}) ctx.SendJson(root) } }) @@ -64,6 +65,7 @@ func (hs HttpServer) Run(c Context) error { c.HandleErr(err) ctx.ServerErr(err) } else { + c.Telemetry().Incr("write", []string{"stream:" + stream}) ctx.SendJson("OK") } }) diff --git a/actions_test.go b/actions_test.go index 13f23f6..8237fea 100644 --- a/actions_test.go +++ b/actions_test.go @@ -26,6 +26,7 @@ var _ = BeforeSuite(func() { config = Config{} config.Hosts = []string{"127.0.0.1"} config.Keyspace = testingKeyspace + config.StatsdAddr = "dd-agent.service.consul:8125" err := config.Init() if err != nil { panic(err) diff --git a/config.go b/config.go index 011ee9b..a2cec92 100644 --- a/config.go +++ b/config.go @@ -7,19 +7,25 @@ import ( "github.com/scoiatael/archai/actions" "github.com/scoiatael/archai/http" "github.com/scoiatael/archai/persistence" + "github.com/scoiatael/archai/telemetry" ) // Config is a context for all application actions. type Config struct { - Keyspace string - Hosts []string - Actions []actions.Action + Keyspace string + Hosts []string + Actions []actions.Action + StatsdAddr string + Features map[string]bool + provider persistence.Provider + telemetry telemetry.Datadog initialized bool } func (c Config) HandleErr(err error) { log.Print(err) + c.Telemetry().Failure("server_error", err.Error()) } func (c Config) Migrations() map[string]persistence.Migration { @@ -30,18 +36,25 @@ func (c Config) Migrations() map[string]persistence.Migration { func (c Config) Persistence() persistence.Provider { if !c.initialized { - panic(fmt.Errorf("Persistence not initialized!")) + panic(fmt.Errorf("Config not initialized!")) } return c.provider } +func (c Config) Telemetry() telemetry.Datadog { + if !c.initialized { + panic(fmt.Errorf("Config not initialized!")) + } + return c.telemetry +} + // Version returns current version func (c Config) Version() string { return Version } func (c Config) HttpHandler() actions.HttpHandler { - return http.NewIris(c) + return http.NewIris(c, c.Features["dev_logger"]) } func (c *Config) Init() error { @@ -51,6 +64,10 @@ func (c *Config) Init() error { return err } c.provider = &new_provider + + dd := telemetry.NewDatadog(c.StatsdAddr, c.Keyspace) + c.telemetry = dd + c.initialized = true return nil } diff --git a/http/new.go b/http/new.go index 41f94a5..56c76ec 100644 --- a/http/new.go +++ b/http/new.go @@ -5,14 +5,18 @@ import ( "gopkg.in/kataras/iris.v6/adaptors/httprouter" ) -func NewIris(c Context) *IrisHandler { +func NewIris(c Context, useDevLogger bool) *IrisHandler { handler := IrisHandler{} handler.context = c app := iris.New() + if useDevLogger { + app.Adapt( + // adapt a logger which prints all errors to the os.Stdout + iris.DevLogger(), + ) + } app.Adapt( - // adapt a logger which prints all errors to the os.Stdout - iris.DevLogger(), // adapt the adaptors/httprouter or adaptors/gorillamux httprouter.New(), ) diff --git a/telemetry/datadog.go b/telemetry/datadog.go new file mode 100644 index 0000000..261e2b6 --- /dev/null +++ b/telemetry/datadog.go @@ -0,0 +1,53 @@ +package telemetry + +import ( + "log" + + "github.com/DataDog/datadog-go/statsd" + "github.com/pkg/errors" +) + +type Datadog interface { + Incr(name string, tags []string) + Failure(title, text string) +} + +type Client struct { + client *statsd.Client + initialized bool +} + +func (c *Client) on_error(err error) { + log.Println(err) +} + +func (c *Client) Failure(title, text string) { + if c.initialized { + ev := statsd.NewEvent(title, text) + ev.AlertType = statsd.Error + err := errors.Wrap(c.client.Event(ev), "Failed sending event to DataDog") + if err != nil { + c.on_error(err) + } + } +} + +func (c *Client) Incr(name string, tags []string) { + if c.initialized { + err := c.client.Incr(name, tags, 1.0) + if err != nil { + c.on_error(err) + } + } +} + +func NewDatadog(addr string, namespace string) Datadog { + c, err := statsd.New(addr) + if err != nil { + client := &Client{} + client.on_error(err) + return client + } + c.Namespace = namespace + "." + return &Client{client: c, initialized: true} +}