Skip to content

Commit

Permalink
Storage plugin: Azure Application Insights (sourcegraph#132)
Browse files Browse the repository at this point in the history
* New Application Insights storage plugin

* Update Application Insights storage plugin

  - Change healthy status message to "Up"
  - Add support for retries
  - Add tests
  - Add documentation

* Fixes PR comments

- Use builtin functions and check Id
- Rename TelemetryClient to client
- Make max timeout configurable when retries disabled
- Fix typo

* Add test for valid InstrumentationKey

* Make telemetryConfig private
  • Loading branch information
mcdafydd authored Jul 20, 2020
1 parent 0624503 commit 76fc114
Show file tree
Hide file tree
Showing 6 changed files with 402 additions and 1 deletion.
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ Checkup implements these storage providers:
- MySQL
- PostgreSQL
- SQLite3
- Azure Application Insights

*Currently the status page does not support SQL storage back-ends.*
*Currently the status page does not support SQL or Azure Application Insights storage back-ends.*

Checkup can even send notifications through your service of choice (if an integration exists).

Expand Down Expand Up @@ -281,6 +282,48 @@ Example configuration:
When `create` is set to true, checkup will issue `CREATE TABLE` statements required for storage.


#### Azure Application Insights Storage

**[godoc: appinsights](https://godoc.org/github.com/sourcegraph/checkup/storage/appinsights)**

Azure Application Insights can be used as a storage backend, enabling Checkup to be used as a source of custom availability tests and metrics. An example use case is documented [here](https://docs.microsoft.com/en-us/azure/azure-monitor/app/availability-azure-functions).

A sample storage configuration with retries enabled:
```js
{
"type": "appinsights",
"test_location": "data center 1",
"instrumentation_key": "11111111-1111-1111-1111-111111111111",
"retry_interval": 1,
"max_retries": 3,
"tags": {
"service": "front end",
"product": "main web app"
}
}
```

The following keys are optional:

- `test_location` (default is **Checkup Monitor**)
- `retry_interval` (default is 0)
- `max_retries` (default is 0)
- `timeout` (defaults to 2 seconds if omitted or set to 0)
- `tags`

If retries are disabled, the plugin will wait up to `timeout` seconds to submit telemetry before closing.

When check results are sent to Application Insights, the following values are included in the logged telemetry:

- `success` is set to `1` if the check passes, `0` otherwise
- `message` is set to `Up`, `Down`, or `Degraded`
- `duration` is set to the average of all check result round-trip times and is displayed as a string in milliseconds
- `customMeasurements` is set to a JSON object including the number of the check as a string and the round-trip time of the check in nanoseconds
- If the check included a `threshold_rtt` setting, it will be added to the `customDimensions` JSON object as key `ThresholdRTT` with a time duration string value (ie: `200ms`)
- If any tags were included in the storage configuation, they will be added to the `customDimensions` JSON object

Currently the status page does not support Application Insights storage.

#### Slack notifier

Enable notifications in Slack with this Notifier configuration:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/lib/pq v1.3.0
github.com/mailgun/mailgun-go/v4 v4.1.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/microsoft/ApplicationInsights-Go v0.4.3
github.com/miekg/dns v1.1.29
github.com/parnurzeal/gorequest v0.2.16 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
Expand Down
22 changes: 22 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c h1:5eeuG0BHx1+DHeT3AP+ISKZ2ht1UjGhm581ljqYpVeQ=
code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
Expand Down Expand Up @@ -36,6 +38,7 @@ github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQD
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi v4.0.0+incompatible h1:SiLLEDyAkqNnw+T/uDTf3aFB9T4FTrwMpuYrgaRcnW4=
Expand Down Expand Up @@ -70,6 +73,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
Expand Down Expand Up @@ -106,12 +111,19 @@ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microsoft/ApplicationInsights-Go v0.4.3 h1:gBuy5rM3o6Zo69QTkq1Ens8wx6sVf+mpgMjjfayiRcw=
github.com/microsoft/ApplicationInsights-Go v0.4.3/go.mod h1:ih0t3h84PdzV1qGeUs89o9wL8eCuwf24M7TZp/nyqXk=
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=
github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
Expand All @@ -133,6 +145,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
Expand All @@ -154,6 +168,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc h1:LUUe4cdABGrIJAhl1P1ZpWY76AwukVszFdwkVFVLwIk=
github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
Expand All @@ -171,6 +187,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -191,6 +208,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEha
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down Expand Up @@ -220,9 +238,13 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
Expand Down
3 changes: 3 additions & 0 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"

"github.com/sourcegraph/checkup/storage/appinsights"
"github.com/sourcegraph/checkup/storage/fs"
"github.com/sourcegraph/checkup/storage/github"
"github.com/sourcegraph/checkup/storage/mysql"
Expand All @@ -29,6 +30,8 @@ func storageDecode(typeName string, config json.RawMessage) (Storage, error) {
return fs.New(config)
case sql.Type:
return sql.New(config)
case appinsights.Type:
return appinsights.New(config)
default:
return nil, fmt.Errorf(errUnknownStorageType, typeName)
}
Expand Down
152 changes: 152 additions & 0 deletions storage/appinsights/appinsights.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package appinsights

import (
"encoding/json"
"fmt"
"strconv"
"time"

"github.com/microsoft/ApplicationInsights-Go/appinsights"
"github.com/sourcegraph/checkup/types"
)

// Type should match the package name
const Type = "appinsights"

// Storage will send results to Azure Application Insights
type Storage struct {
// InstrumentationKey is a GUID that identifies an app insights instance
InstrumentationKey string `json:"instrumentation_key"`

// TestLocation identifies the test location sent
// in Application Insights trackAvailability() events
TestLocation string `json:"test_location,omitempty"`

// Tags will be applied to all telemetry items and
// visible in the customDimensions field when viewing the
// submitted data
Tags map[string]string `json:"tags,omitempty"`

// MaxRetries specifies the number of retries before returning error
// from close(). To enable retries, both RetryInterval and MaxRetries
// must be greater than 0. Default is 0 (disabled).
MaxRetries time.Duration `json:"max_retries,omitempty"`

// RetryInterval specifies the time between retries in seconds. To enable retries,
// both RetryInterval and MaxRetries must
// be greater than 0. Default is 0 (disabled).
RetryInterval time.Duration `json:"retry_interval,omitempty"`

// Timeout specifies the number of seconds to wait for telemetry submission
// before returning error from close() if retries are disabled. If omitted or
// set to 0, timeout will be 2 seconds. If retries are enabled, this setting
// is ignored.
Timeout time.Duration `json:"timeout,omitempty"`

// telemetryConfig defines the settings for client
telemetryConfig *appinsights.TelemetryConfiguration

// client is the appinsights.Client used to
// send Application Insights trackAvailability() events
client appinsights.TelemetryClient
}

// New creates a new Storage instance based on json config
func New(config json.RawMessage) (Storage, error) {
var storage Storage
err := json.Unmarshal(config, &storage)

if storage.InstrumentationKey == "" {
err = fmt.Errorf("Must supply value for InstrumentationKey")
}
if storage.MaxRetries < 0 {
err = fmt.Errorf("Invalid storage max_retries: %d", storage.MaxRetries)
}
if storage.MaxRetries < 0 {
err = fmt.Errorf("Invalid storage max_retries: %d", storage.MaxRetries)
}
if storage.RetryInterval < 0 {
err = fmt.Errorf("Invalid storage retry_interval: %d", storage.RetryInterval)
}
if storage.Timeout < 0 {
err = fmt.Errorf("Invalid storage timeout: %d", storage.Timeout)
}

storage.telemetryConfig = appinsights.NewTelemetryConfiguration(storage.InstrumentationKey)
if storage.TestLocation == "" {
storage.TestLocation = "Checkup Monitor"
}
if storage.TestLocation == "" {
storage.TestLocation = "Checkup Monitor"
}
if storage.Timeout == 0 {
storage.Timeout = 2
}
return storage, err
}

// Type returns the logger package name
func (Storage) Type() string {
return Type
}

// Store takes a list of Checker results and sends them to the configured
// Application Insights instance.
func (c Storage) Store(results []types.Result) error {
c.telemetryConfig.InstrumentationKey = c.InstrumentationKey
c.client = appinsights.NewTelemetryClientFromConfig(c.telemetryConfig)
for k, v := range c.Tags {
c.client.Context().CommonProperties[k] = v
}
for _, result := range results {
c.send(result)
}
return c.close()
}

// Close will submit all queued telemetry to the configured Application Insights
// service. If either RetryInterval or MaxRetries are <= 0, Close() should proceed
// without a retry and a maximum timeout of 2 seconds.
// Ref: https://github.com/microsoft/ApplicationInsights-Go#shutdown
func (c Storage) close() error {
if c.RetryInterval <= 0 || c.MaxRetries <= 0 {
select {
case <-c.client.Channel().Close():
return nil
case <-time.After(c.Timeout * time.Second):
return fmt.Errorf("Failed to submit telemetry before timeout expired")
}
}
select {
case <-c.client.Channel().Close(c.RetryInterval * time.Second):
return nil
case <-time.After((c.MaxRetries + 1) * c.RetryInterval * time.Second):
return fmt.Errorf("Failed to submit telemetry after retries")
}
}

// Send a result
// Multiple test result measurements will be added to the telemetry item's
// customMeasurements field
func (c Storage) send(conclude types.Result) {
message := string(conclude.Status())

if conclude.Notice != "" {
message = fmt.Sprintf("%s - %s", message, conclude.Notice)
}

stats := conclude.ComputeStats()
availability := appinsights.NewAvailabilityTelemetry(conclude.Title, stats.Mean, conclude.Healthy)
availability.RunLocation = c.TestLocation
availability.Message = message
availability.Id = fmt.Sprintf("%d", conclude.Timestamp)
for i := 0; i < len(conclude.Times); i++ {
k := strconv.Itoa(i)
availability.GetMeasurements()[k] = float64(conclude.Times[i].RTT)
}
availability.GetProperties()["ThresholdRTT"] = conclude.ThresholdRTT.String()

// Submit the telemetry
c.client.Track(availability)
return
}
Loading

0 comments on commit 76fc114

Please sign in to comment.