Skip to content

Commit 33f8ed9

Browse files
added newrelic support (#192)
* added newrelic support
1 parent 68c354e commit 33f8ed9

File tree

17 files changed

+384
-20
lines changed

17 files changed

+384
-20
lines changed

venona/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.4.30
1+
1.5.0

venona/cmd/root.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ import (
1818
"github.com/spf13/cobra"
1919
)
2020

21+
const (
22+
// AppName holds the name of the application, to be used in monitoring tools
23+
AppName = "Codefresh-Runner"
24+
)
25+
2126
var version string
2227

2328
var rootCmd = &cobra.Command{

venona/cmd/start.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ import (
2929
"github.com/codefresh-io/go/venona/pkg/config"
3030
"github.com/codefresh-io/go/venona/pkg/kubernetes"
3131
"github.com/codefresh-io/go/venona/pkg/logger"
32+
"github.com/codefresh-io/go/venona/pkg/monitoring"
33+
"github.com/codefresh-io/go/venona/pkg/monitoring/newrelic"
3234
"github.com/codefresh-io/go/venona/pkg/runtime"
3335
"github.com/codefresh-io/go/venona/pkg/server"
36+
nr "github.com/newrelic/go-agent"
3437
"github.com/spf13/cobra"
3538
"github.com/spf13/pflag"
3639
"github.com/spf13/viper"
@@ -50,6 +53,8 @@ type startOptions struct {
5053
statusReportingSecondsInterval int64
5154
configDir string
5255
serverPort string
56+
newrelicLicenseKey string
57+
newrelicAppname string
5358
}
5459

5560
var (
@@ -75,10 +80,13 @@ func init() {
7580
dieOnError(viper.BindEnv("port", "PORT"))
7681
dieOnError(viper.BindEnv("NODE_TLS_REJECT_UNAUTHORIZED"))
7782
dieOnError(viper.BindEnv("verbose", "VERBOSE"))
83+
dieOnError(viper.BindEnv("newrelic-license-key", "NEWRELIC_LICENSE_KEY"))
84+
dieOnError(viper.BindEnv("newrelic-appname", "NEWRELIC_APPNAME"))
7885

7986
viper.SetDefault("codefresh-host", defaultCodefreshHost)
8087
viper.SetDefault("port", "8080")
8188
viper.SetDefault("NODE_TLS_REJECT_UNAUTHORIZED", "1")
89+
viper.SetDefault("newrelic-appname", AppName)
8290

8391
startCmd.Flags().BoolVar(&startCmdOptions.verbose, "verbose", viper.GetBool("verbose"), "Show more logs")
8492
startCmd.Flags().BoolVar(&startCmdOptions.rejectTLSUnauthorized, "tls-reject-unauthorized", viper.GetBool("NODE_TLS_REJECT_UNAUTHORIZED"), "Disable certificate validation for TLS connections")
@@ -89,6 +97,8 @@ func init() {
8997
startCmd.Flags().StringVar(&startCmdOptions.codefreshHost, "codefresh-host", viper.GetString("codefresh-host"), "Codefresh API host default [$CODEFRESH_HOST]")
9098
startCmd.Flags().Int64Var(&startCmdOptions.taskPullingSecondsInterval, "task-pulling-interval", 3, "The interval (seconds) to pull new tasks from Codefresh")
9199
startCmd.Flags().Int64Var(&startCmdOptions.statusReportingSecondsInterval, "status-reporting-interval", 10, "The interval (seconds) to report status back to Codefresh")
100+
startCmd.Flags().StringVar(&startCmdOptions.newrelicLicenseKey, "newrelic-license-key", viper.GetString("newrelic-license-key"), "New-Relic license key [$NEWRELIC_LICENSE_KEY]")
101+
startCmd.Flags().StringVar(&startCmdOptions.newrelicAppname, "newrelic-appname", viper.GetString("newrelic-appname"), "New-Relic application name [$NEWRELIC_APPNAME]")
92102

93103
startCmd.Flags().VisitAll(func(f *pflag.Flag) {
94104
if viper.IsSet(f.Name) && viper.GetString(f.Name) != "" {
@@ -135,6 +145,19 @@ func run(options startOptions) {
135145
runtimes[config.Name] = re
136146
}
137147
}
148+
149+
var monitor monitoring.Monitor = monitoring.NewEmpty()
150+
if options.newrelicLicenseKey != "" {
151+
conf := nr.NewConfig(options.newrelicAppname, options.newrelicLicenseKey)
152+
if monitor, err = newrelic.New(conf); err != nil {
153+
log.Warn("Failed to create monitor", "error", err)
154+
} else {
155+
log.Info("Using New Relic monitor", "app-name", options.newrelicAppname, "license-key", options.newrelicLicenseKey)
156+
}
157+
} else {
158+
log.Warn("New Relic not starting without license key!")
159+
}
160+
138161
var cf codefresh.Codefresh
139162
{
140163
var httpClient http.Client
@@ -148,6 +171,8 @@ func run(options startOptions) {
148171
}
149172
}
150173

174+
httpClient.Transport = monitor.NewRoundTripper(httpClient.Transport)
175+
151176
httpHeaders := http.Header{}
152177
{
153178
httpHeaders.Add("User-Agent", fmt.Sprintf("codefresh-runner-%s", version))
@@ -170,6 +195,7 @@ func run(options startOptions) {
170195
ID: options.agentID,
171196
TaskPullingSecondsInterval: time.Duration(options.taskPullingSecondsInterval) * time.Second,
172197
StatusReportingSecondsInterval: time.Duration(options.statusReportingSecondsInterval) * time.Second,
198+
Monitor: monitor,
173199
})
174200
dieOnError(err)
175201

@@ -178,9 +204,10 @@ func run(options startOptions) {
178204
serverMode = server.Debug
179205
}
180206
server, err := server.New(&server.Options{
181-
Port: fmt.Sprintf(":%s", options.serverPort),
182-
Logger: log.New("module", "server"),
183-
Mode: serverMode,
207+
Port: fmt.Sprintf(":%s", options.serverPort),
208+
Logger: log.New("module", "server"),
209+
Mode: serverMode,
210+
Monitor: monitor,
184211
})
185212
dieOnError(err)
186213

venona/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ go 1.14
44

55
require (
66
github.com/evanphx/json-patch v4.5.0+incompatible // indirect
7-
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 // indirect
87
github.com/gin-gonic/gin v1.6.3
98
github.com/go-playground/validator/v10 v10.3.0 // indirect
109
github.com/golang/protobuf v1.4.2 // indirect
1110
github.com/hashicorp/go-retryablehttp v0.6.7
1211
github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1
1312
github.com/json-iterator/go v1.1.10 // indirect
1413
github.com/mattn/go-colorable v0.1.6 // indirect
14+
github.com/newrelic/go-agent v3.9.0+incompatible
1515
github.com/pkg/errors v0.9.1 // indirect
1616
github.com/spf13/cobra v1.0.0
1717
github.com/spf13/pflag v1.0.5

venona/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
6868
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
6969
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
7070
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
71-
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 h1:roDmqJ4Qes7hrDOsWsMCce0vQHz3xiMPjJ9m4c2eeNs=
72-
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8=
7371
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
7472
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
7573
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
@@ -244,6 +242,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
244242
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
245243
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
246244
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
245+
github.com/newrelic/go-agent v3.9.0+incompatible h1:W2Zummx9jNATZVX6QVjYksX1TwxJGf4E6x1Wf3CG/jY=
246+
github.com/newrelic/go-agent v3.9.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
247247
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
248248
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
249249
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=

venona/pkg/agent/agent.go

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
"github.com/codefresh-io/go/venona/pkg/codefresh"
2727
"github.com/codefresh-io/go/venona/pkg/logger"
28+
"github.com/codefresh-io/go/venona/pkg/monitoring"
2829
"github.com/codefresh-io/go/venona/pkg/runtime"
2930
"github.com/codefresh-io/go/venona/pkg/task"
3031
retryablehttp "github.com/hashicorp/go-retryablehttp"
@@ -39,6 +40,7 @@ var (
3940
errIDRequired = errors.New("ID options is required")
4041
errRuntimesRequired = errors.New("Runtimes options is required")
4142
errLoggerRequired = errors.New("Logger options is required")
43+
errRuntimeNotFound = errors.New("Runtime environment not found")
4244
errFailedToParseAgentTask = errors.New("Failed to parse agent task spec")
4345
errUknownAgentTaskType = errors.New("Agent task has unknown type")
4446
errAgentTaskMalformedParams = errors.New("failed to marshal agent task params")
@@ -49,7 +51,7 @@ var (
4951
const (
5052
defaultTaskPullingInterval = time.Second * 3
5153
defaultStatusReportingInterval = time.Second * 10
52-
defaultProxyRequestTimeout = time.Second * 10
54+
defaultProxyRequestTimeout = time.Second * 20
5355
defaultProxyRequestRetries = 3
5456
)
5557

@@ -62,6 +64,7 @@ type (
6264
Logger logger.Logger
6365
TaskPullingSecondsInterval time.Duration
6466
StatusReportingSecondsInterval time.Duration
67+
Monitor monitoring.Monitor
6568
}
6669

6770
// Agent holds all the references from Codefresh
@@ -77,6 +80,7 @@ type (
7780
lastStatus Status
7881
terminationChan chan struct{}
7982
wg *sync.WaitGroup
83+
monitor monitoring.Monitor
8084
}
8185

8286
// Status of the agent
@@ -121,6 +125,11 @@ func New(opt *Options) (*Agent, error) {
121125
terminationChan := make(chan struct{})
122126
wg := &sync.WaitGroup{}
123127

128+
if opt.Monitor == nil {
129+
opt.Monitor = monitoring.NewEmpty()
130+
}
131+
httpClient.HTTPClient.Transport = opt.Monitor.NewRoundTripper(httpClient.HTTPClient.Transport)
132+
124133
return &Agent{
125134
id,
126135
cf,
@@ -132,6 +141,7 @@ func New(opt *Options) (*Agent, error) {
132141
Status{},
133142
terminationChan,
134143
wg,
144+
opt.Monitor,
135145
}, nil
136146
}
137147

@@ -180,12 +190,12 @@ func (a *Agent) startTaskPullerRoutine() {
180190
return
181191
case <-a.taskPullerTicker.C:
182192
a.wg.Add(1)
183-
go func(client codefresh.Codefresh, runtimes map[string]runtime.Runtime, wg *sync.WaitGroup, logger logger.Logger) {
193+
go func(client codefresh.Codefresh, runtimes map[string]runtime.Runtime, wg *sync.WaitGroup, logger logger.Logger, monitor monitoring.Monitor) {
184194
tasks := pullTasks(client, logger)
185-
startTasks(tasks, runtimes, logger)
195+
startTasks(tasks, runtimes, logger, monitor)
186196
time.Sleep(time.Second * 10)
187197
wg.Done()
188-
}(a.cf, a.runtimes, a.wg, a.log)
198+
}(a.cf, a.runtimes, a.wg, a.log, a.monitor)
189199
}
190200
}
191201
}
@@ -229,7 +239,7 @@ func pullTasks(client codefresh.Codefresh, logger logger.Logger) []task.Task {
229239
return tasks
230240
}
231241

232-
func startTasks(tasks []task.Task, runtimes map[string]runtime.Runtime, logger logger.Logger) {
242+
func startTasks(tasks []task.Task, runtimes map[string]runtime.Runtime, logger logger.Logger, monitor monitoring.Monitor) {
233243
creationTasks := []task.Task{}
234244
deletionTasks := []task.Task{}
235245
agentTasks := []task.Task{}
@@ -253,39 +263,54 @@ func startTasks(tasks []task.Task, runtimes map[string]runtime.Runtime, logger l
253263
for i := range agentTasks {
254264
t := agentTasks[i]
255265
logger.Info("executing agent task", "tid", t.Metadata.Workflow)
266+
txn := newTransaction(monitor, t.Type, t.Metadata.Workflow, t.Metadata.ReName)
256267
if err := executeAgentTask(&t, logger); err != nil {
257268
logger.Error(err.Error())
269+
noticeError(txn, err, logger)
258270
}
271+
endTransaction(txn, logger)
259272
}
260273

261274
// process creation tasks
262275
for _, tasks := range groupTasks(creationTasks) {
263276
reName := tasks[0].Metadata.ReName
264277
runtime, ok := runtimes[reName]
278+
txn := newTransaction(monitor, "start-workflow", tasks[0].Metadata.Workflow, reName)
279+
265280
if !ok {
266281
logger.Error("Runtime not found", "workflow", tasks[0].Metadata.Workflow, "runtime", reName)
282+
noticeError(txn, errRuntimeNotFound, logger)
283+
endTransaction(txn, logger)
267284
continue
268285
}
269286
logger.Info("Starting workflow", "workflow", tasks[0].Metadata.Workflow, "runtime", reName)
270287
if err := runtime.StartWorkflow(tasks); err != nil {
271288
logger.Error(err.Error())
289+
noticeError(txn, err, logger)
272290
}
291+
endTransaction(txn, logger)
273292
}
274293

275294
// process deletion tasks
276295
for _, tasks := range groupTasks(deletionTasks) {
277296
reName := tasks[0].Metadata.ReName
278297
runtime, ok := runtimes[reName]
298+
txn := newTransaction(monitor, "terminate-workflow", tasks[0].Metadata.Workflow, reName)
299+
279300
if !ok {
280301
logger.Error("Runtime not found", "workflow", tasks[0].Metadata.Workflow, "runtime", reName)
302+
noticeError(txn, errRuntimeNotFound, logger)
303+
endTransaction(txn, logger)
281304
continue
282305
}
283306
logger.Info("Terminating workflow", "workflow", tasks[0].Metadata.Workflow, "runtime", reName)
284307
if errs := runtime.TerminateWorkflow(tasks); len(errs) != 0 {
285308
for _, err := range errs {
286309
logger.Error(err.Error())
310+
noticeError(txn, err, logger)
287311
}
288312
}
313+
endTransaction(txn, logger)
289314
}
290315
}
291316

@@ -388,6 +413,26 @@ func checkOptions(opt *Options) error {
388413
return nil
389414
}
390415

416+
func newTransaction(monitor monitoring.Monitor, taskType, tid, runtime string) monitoring.Transaction {
417+
txn := monitor.NewTransaction("runner-tasks-execution", nil, nil)
418+
_ = txn.AddAttribute("task-type", taskType)
419+
_ = txn.AddAttribute("tid", tid)
420+
_ = txn.AddAttribute("runtime-environment", runtime)
421+
return txn
422+
}
423+
424+
func noticeError(txn monitoring.Transaction, error error, log logger.Logger) {
425+
if err := txn.NoticeError(error); err != nil {
426+
log.Error("Failed to report error to monitor", "err", err)
427+
}
428+
}
429+
430+
func endTransaction(txn monitoring.Transaction, log logger.Logger) {
431+
if err := txn.End(); err != nil {
432+
log.Error("Failed to end transaction", "err", err)
433+
}
434+
}
435+
391436
func init() {
392437
httpClient.RetryMax = defaultProxyRequestRetries
393438
httpClient.HTTPClient.Timeout = defaultProxyRequestTimeout

0 commit comments

Comments
 (0)