Srikanth Chekuri 7aeaecaf1f
ci: add golangci to workflow (#1369)
* style: reformat the code to follow go guidelines
* chore: add golangci lint
* chore: remove context check
* chore: go fmt
2022-07-13 23:44:42 +05:30

196 lines
4.2 KiB
Go

package telemetry
import (
"context"
"io/ioutil"
"net/http"
"os"
"sync"
"time"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/interfaces"
"go.signoz.io/query-service/model"
"go.signoz.io/query-service/version"
"gopkg.in/segmentio/analytics-go.v3"
)
const (
EventPath = "API Call"
EventUser = "User"
EventInproductFeedback = "InProduct Feedback Submitted"
EventNumberOfServices = "Number of Services"
EventHeartBeat = "Heart Beat"
EventOrgSettings = "Org Settings"
)
const writeKey = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
const IpNotFoundPlaceholder = "NA"
const HeartBeatDuration = 6 * time.Hour
// const HEART_BEAT_DURATION = 10 * time.Second
var telemetry *Telemetry
var once sync.Once
type Telemetry struct {
operator analytics.Client
ipAddress string
isEnabled bool
isAnonymous bool
distinctId string
reader interfaces.Reader
}
func createTelemetry() {
telemetry = &Telemetry{
operator: analytics.New(writeKey),
ipAddress: getOutboundIP(),
}
data := map[string]interface{}{}
telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled())
telemetry.SendEvent(EventHeartBeat, data)
ticker := time.NewTicker(HeartBeatDuration)
go func() {
for {
select {
case <-ticker.C:
totalSpans, _ := telemetry.reader.GetTotalSpans(context.Background())
spansInLastHeartBeatInterval, _ := telemetry.reader.GetSpansInLastHeartBeatInterval(context.Background())
getSamplesInfoInLastHeartBeatInterval, _ := telemetry.reader.GetSamplesInfoInLastHeartBeatInterval(context.Background())
tsInfo, _ := telemetry.reader.GetTimeSeriesInfo(context.Background())
data := map[string]interface{}{
"totalSpans": totalSpans,
"spansInLastHeartBeatInterval": spansInLastHeartBeatInterval,
"getSamplesInfoInLastHeartBeatInterval": getSamplesInfoInLastHeartBeatInterval,
}
for key, value := range tsInfo {
data[key] = value
}
telemetry.SendEvent(EventHeartBeat, data)
}
}
}()
}
// Get preferred outbound ip of this machine
func getOutboundIP() string {
ip := []byte(IpNotFoundPlaceholder)
resp, err := http.Get("https://api.ipify.org?format=text")
if err != nil {
return string(ip)
}
defer resp.Body.Close()
if err == nil {
ipBody, err := ioutil.ReadAll(resp.Body)
if err == nil {
ip = ipBody
}
}
return string(ip)
}
func (a *Telemetry) IdentifyUser(user *model.User) {
if !a.isTelemetryEnabled() || a.isTelemetryAnonymous() {
return
}
a.operator.Enqueue(analytics.Identify{
UserId: a.ipAddress,
Traits: analytics.NewTraits().SetName(user.Name).SetEmail(user.Email).Set("ip", a.ipAddress),
})
}
func (a *Telemetry) checkEvents(event string) bool {
sendEvent := true
if event == EventUser && a.isTelemetryAnonymous() {
sendEvent = false
}
return sendEvent
}
func (a *Telemetry) SendEvent(event string, data map[string]interface{}) {
if !a.isTelemetryEnabled() {
return
}
ok := a.checkEvents(event)
if !ok {
return
}
// zap.S().Info(data)
properties := analytics.NewProperties()
properties.Set("version", version.GetVersion())
properties.Set("deploymentType", getDeploymentType())
for k, v := range data {
properties.Set(k, v)
}
userId := a.ipAddress
if a.isTelemetryAnonymous() || userId == IpNotFoundPlaceholder {
userId = a.GetDistinctId()
}
a.operator.Enqueue(analytics.Track{
Event: event,
UserId: userId,
Properties: properties,
})
}
func (a *Telemetry) GetDistinctId() string {
return a.distinctId
}
func (a *Telemetry) SetDistinctId(distinctId string) {
a.distinctId = distinctId
}
func (a *Telemetry) isTelemetryAnonymous() bool {
return a.isAnonymous
}
func (a *Telemetry) SetTelemetryAnonymous(value bool) {
a.isAnonymous = value
}
func (a *Telemetry) isTelemetryEnabled() bool {
return a.isEnabled
}
func (a *Telemetry) SetTelemetryEnabled(value bool) {
a.isEnabled = value
}
func (a *Telemetry) SetReader(reader interfaces.Reader) {
a.reader = reader
}
func GetInstance() *Telemetry {
once.Do(func() {
createTelemetry()
})
return telemetry
}
func getDeploymentType() string {
deploymentType := os.Getenv("DEPLOYMENT_TYPE")
if deploymentType == "" {
return "unknown"
}
return deploymentType
}