Skip to content
This repository has been archived by the owner on Oct 27, 2020. It is now read-only.

Commit

Permalink
initial newrelic integration
Browse files Browse the repository at this point in the history
  • Loading branch information
frankgreco committed Jun 15, 2018
1 parent c562326 commit f86c934
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Contextual and performant logging using zap.
- New `MockTarget` resource.
- Optional New Relic middleware.
### Changed
- Using `client-go@v5.0.0` for Kubernetes client.
- Using `CRDs` to replace the deprecated `TPRs`.
Expand Down
16 changes: 15 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ required = [
[[constraint]]
name = "github.com/onsi/gomega"
version = "v1.3.0"

[[constraint]]
name = "github.com/newrelic/go-agent"
version = "v2.0.0"
4 changes: 4 additions & 0 deletions cmd/kanali/app/kanali.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ func Run(sigCtx context.Context) error {
middleware.Correlation,
middleware.Recover,
middleware.Metrics,
middleware.NewRelic(
viper.GetBool(options.FlagNewRelicEnabled.GetLong()),
viper.GetString(options.FlagNewRelicLicenseKey.GetLong()),
),
).Link(middleware.Gateway(coreV1SharedInformer)),
Logger: logger.Sugar(),
})
Expand Down
49 changes: 49 additions & 0 deletions cmd/kanali/app/options/new_relic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2018 Northwestern Mutual.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package options

import (
"github.com/northwesternmutual/kanali/pkg/flags"
)

func init() {
KanaliGatewayOptions.Add(
FlagNewRelicEnabled,
FlagNewRelicLicenseKey,
)
}

var (
// FlagNewRelicEnabled determines whether New Relic integration should be enabled.
FlagNewRelicEnabled = flags.Flag{
Long: "new_relic.enabled",
Short: "",
Value: false,
Usage: "Should New Relic Integration be enabled.",
}
// FlagNewRelicLicenseKey is the license key to use for New Relic.
FlagNewRelicLicenseKey = flags.Flag{
Long: "new_relic.license_key",
Short: "",
Value: "",
Usage: "The license key to use for New Relic.",
}
)
4 changes: 4 additions & 0 deletions helm/kanali/templates/configmap-kanali.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ data:
[tracing]
config_file = ""
[new_relic]
enabled = {{default false .Values.gateway.newRelic.enabled}}
license_key = {{.Values.gateway.newRelic.licenseKey}}
3 changes: 3 additions & 0 deletions helm/kanali/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ gateway:
insecurePort: 9000
secureBindAddress: 0.0.0.0
securePort: 0
newRelic:
enabled: false
licenseKey: ""
validator:
namespace: kanali
logLevel: info
Expand Down
105 changes: 105 additions & 0 deletions pkg/middleware/new_relic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright (c) 2018 Northwestern Mutual.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package middleware

import (
"net/http"

newrelic "github.com/newrelic/go-agent"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"

"github.com/northwesternmutual/kanali/pkg/log"
"github.com/northwesternmutual/kanali/pkg/tags"
)

// newRelicLoggingShim implemnts https://godoc.org/github.com/newrelic/go-agent#Logger
type newRelicLoggingShim struct {
l *zap.Logger
}

// Error implements https://godoc.org/github.com/newrelic/go-agent#Logger
func (shim *newRelicLoggingShim) Error(msg string, context map[string]interface{}) {
shim.l.Error(msg, zapifyMap(context)...)
}

// Warn implements https://godoc.org/github.com/newrelic/go-agent#Logger
func (shim *newRelicLoggingShim) Warn(msg string, context map[string]interface{}) {
shim.l.Warn(msg, zapifyMap(context)...)
}

// Info implements https://godoc.org/github.com/newrelic/go-agent#Logger
func (shim *newRelicLoggingShim) Info(msg string, context map[string]interface{}) {
shim.l.Info(msg, zapifyMap(context)...)
}

// Debug implements https://godoc.org/github.com/newrelic/go-agent#Logger
func (shim *newRelicLoggingShim) Debug(msg string, context map[string]interface{}) {
shim.l.Debug(msg, zapifyMap(context)...)
}

// DebugEnabled implements https://godoc.org/github.com/newrelic/go-agent#Logger
func (shim *newRelicLoggingShim) DebugEnabled() bool {
return shim.l.Core().Enabled(zapcore.DebugLevel)
}

func zapifyMap(m map[string]interface{}) []zapcore.Field {
fields := make([]zapcore.Field, len(m))
for k, v := range m {
fields = append(fields, zap.Any(k, v))
}
return fields
}

func NewRelic(enabled bool, licenseKey string) func(next http.Handler) http.Handler {
logger := log.WithContext(nil)

config := newrelic.NewConfig(tags.AppName, licenseKey)
config.Enabled = enabled
config.Logger = &newRelicLoggingShim{
l: log.WithContext(nil).Named("New Relic"),
}

app, err := newrelic.NewApplication(config)
if err != nil {
logger.Warn("error creating New Relic application",
zap.String(tags.Error, err.Error()),
)
return NoOp
}

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger := log.WithContext(r.Context())
tnx := app.StartTransaction(r.URL.EscapedPath(), w, r)

defer func() {
if err := tnx.End(); err != nil {
logger.Error("could not end New Relic transaction",
zap.String(tags.Error, err.Error()),
)
}
}()

next.ServeHTTP(w, r)
})
}
}
31 changes: 31 additions & 0 deletions pkg/middleware/no_op.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2018 Northwestern Mutual.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package middleware

import (
"net/http"
)

func NoOp(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
}
20 changes: 20 additions & 0 deletions pkg/tags/headers.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
// Copyright (c) 2018 Northwestern Mutual.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tags

const (
Expand Down
3 changes: 3 additions & 0 deletions pkg/tags/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
package tags

const (
// AppName is the name of this application
AppName = "kanali"

// Error is the opentracing tag name that represents an error
Error = "error"

Expand Down

0 comments on commit f86c934

Please sign in to comment.