diff --git a/deploy/docker/clickhouse-setup/docker-compose.yaml b/deploy/docker/clickhouse-setup/docker-compose.yaml index 16851112da..6261cd66f3 100644 --- a/deploy/docker/clickhouse-setup/docker-compose.yaml +++ b/deploy/docker/clickhouse-setup/docker-compose.yaml @@ -45,8 +45,8 @@ services: environment: - ClickHouseUrl=tcp://clickhouse:9000 - STORAGE=clickhouse - - POSTHOG_API_KEY=H-htDCae7CR3RV57gUzmol6IAKtm5IMCvbcm_fwnL-w - GODEBUG=netdns=go + - TELEMETRY_ENABLED=true depends_on: clickhouse: diff --git a/deploy/kubernetes/platform/signoz-charts/query-service/templates/statefulset.yaml b/deploy/kubernetes/platform/signoz-charts/query-service/templates/statefulset.yaml index 179bb4d72f..7fbad5057d 100644 --- a/deploy/kubernetes/platform/signoz-charts/query-service/templates/statefulset.yaml +++ b/deploy/kubernetes/platform/signoz-charts/query-service/templates/statefulset.yaml @@ -41,6 +41,8 @@ spec: value: {{ .Values.configVars.ClickHouseUrl}} - name: GODEBUG value: netdns=go + - name: TELEMETRY_ENABLED + value: {{ .Values.configVars.TELEMETRY_ENABLED}} # livenessProbe: # httpGet: # path: / diff --git a/deploy/kubernetes/platform/signoz-charts/query-service/values.yaml b/deploy/kubernetes/platform/signoz-charts/query-service/values.yaml index 82d438b51b..038d5802a5 100644 --- a/deploy/kubernetes/platform/signoz-charts/query-service/values.yaml +++ b/deploy/kubernetes/platform/signoz-charts/query-service/values.yaml @@ -19,7 +19,6 @@ configVars: DruidDatasource: flattened_spans ClickHouseUrl: http://signoz-clickhouse:9000?username=clickhouse_operator&password=clickhouse_operator_password STORAGE: clickhouse - POSTHOG_API_KEY: "H-htDCae7CR3RV57gUzmol6IAKtm5IMCvbcm_fwnL-w" serviceAccount: diff --git a/deploy/kubernetes/platform/values.yaml b/deploy/kubernetes/platform/values.yaml index 14c369e09a..e37ea7a5d9 100644 --- a/deploy/kubernetes/platform/values.yaml +++ b/deploy/kubernetes/platform/values.yaml @@ -6,6 +6,7 @@ query-service: configVars: ClickHouseUrl: http://signoz-clickhouse:9000?username=clickhouse_operator&password=clickhouse_operator_password STORAGE: clickhouse + TELEMETRY_ENABLED: true cloud: aws diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index e64a9ac1d6..e8a7ebca7f 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -10,10 +10,12 @@ import ( "github.com/gorilla/mux" jsoniter "github.com/json-iterator/go" _ "github.com/mattn/go-sqlite3" - "github.com/posthog/posthog-go" "github.com/prometheus/prometheus/promql" "go.signoz.io/query-service/app/dashboards" + "go.signoz.io/query-service/dao/interfaces" "go.signoz.io/query-service/model" + "go.signoz.io/query-service/telemetry" + "go.signoz.io/query-service/version" "go.uber.org/zap" ) @@ -33,28 +35,26 @@ func NewRouter() *mux.Router { type APIHandler struct { // queryService *querysvc.QueryService // queryParser queryParser - basePath string - apiPrefix string - reader *Reader - pc *posthog.Client - distinctId string - ready func(http.HandlerFunc) http.HandlerFunc + basePath string + apiPrefix string + reader *Reader + relationalDB *interfaces.ModelDao + ready func(http.HandlerFunc) http.HandlerFunc } // NewAPIHandler returns an APIHandler -func NewAPIHandler(reader *Reader, pc *posthog.Client, distinctId string) (*APIHandler, error) { +func NewAPIHandler(reader *Reader, relationalDB *interfaces.ModelDao) (*APIHandler, error) { aH := &APIHandler{ - reader: reader, - pc: pc, - distinctId: distinctId, + reader: reader, + relationalDB: relationalDB, } aH.ready = aH.testReady - errReadingDashboards := dashboards.LoadDashboardFiles() - if errReadingDashboards != nil { - return nil, errReadingDashboards - } + dashboards.LoadDashboardFiles() + // if errReadingDashboards != nil { + // return nil, errReadingDashboards + // } return aH, nil } @@ -184,6 +184,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) { router.HandleFunc("/api/v1/dashboards/{uuid}", aH.deleteDashboard).Methods(http.MethodDelete) router.HandleFunc("/api/v1/user", aH.user).Methods(http.MethodPost) + router.HandleFunc("/api/v1/feedback", aH.submitFeedback).Methods(http.MethodPost) // router.HandleFunc("/api/v1/get_percentiles", aH.getApplicationPercentiles).Methods(http.MethodGet) router.HandleFunc("/api/v1/services", aH.getServices).Methods(http.MethodGet) @@ -203,10 +204,16 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) { router.HandleFunc("/api/v1/serviceMapDependencies", aH.serviceMapDependencies).Methods(http.MethodGet) router.HandleFunc("/api/v1/settings/ttl", aH.setTTL).Methods(http.MethodPost) router.HandleFunc("/api/v1/settings/ttl", aH.getTTL).Methods(http.MethodGet) + + router.HandleFunc("/api/v1/userPreferences", aH.setUserPreferences).Methods(http.MethodPost) + router.HandleFunc("/api/v1/userPreferences", aH.getUserPreferences).Methods(http.MethodGet) + router.HandleFunc("/api/v1/version", aH.getVersion).Methods(http.MethodGet) + router.HandleFunc("/api/v1/getSpanFilters", aH.getSpanFilters).Methods(http.MethodGet) router.HandleFunc("/api/v1/getTagFilters", aH.getTagFilters).Methods(http.MethodGet) router.HandleFunc("/api/v1/getFilteredSpans", aH.getFilteredSpans).Methods(http.MethodGet) router.HandleFunc("/api/v1/getFilteredSpans/aggregates", aH.getFilteredSpanAggregates).Methods(http.MethodGet) + router.HandleFunc("/api/v1/errors", aH.getErrors).Methods(http.MethodGet) router.HandleFunc("/api/v1/errorWithId", aH.getErrorForId).Methods(http.MethodGet) router.HandleFunc("/api/v1/errorWithType", aH.getErrorForType).Methods(http.MethodGet) @@ -656,11 +663,11 @@ func (aH *APIHandler) submitFeedback(w http.ResponseWriter, r *http.Request) { email := postData["email"] - (*aH.pc).Enqueue(posthog.Capture{ - DistinctId: distinctId, - Event: "InProduct Feeback Submitted", - Properties: posthog.NewProperties().Set("email", email).Set("message", message), - }) + data := map[string]interface{}{ + "email": email, + "message": message, + } + telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_INPRODUCT_FEEDBACK, data) } @@ -673,11 +680,12 @@ func (aH *APIHandler) user(w http.ResponseWriter, r *http.Request) { } } - (*aH.pc).Enqueue(posthog.Identify{ - DistinctId: aH.distinctId, - Properties: posthog.NewProperties(). - Set("email", user.Email).Set("name", user.Name), - }) + telemetry.GetInstance().IdentifyUser(user) + data := map[string]interface{}{ + "name": user.Name, + "email": user.Email, + } + telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER, data) } @@ -852,13 +860,12 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) { if aH.handleError(w, err, http.StatusBadRequest) { return } - // if len(*result) != 4 { - (*aH.pc).Enqueue(posthog.Capture{ - DistinctId: distinctId, - Event: "Different Number of Services", - Properties: posthog.NewProperties().Set("number", len(*result)), - }) - // } + + data := map[string]interface{}{ + "number": len(*result), + } + + telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_NUMBER_OF_SERVICES, data) aH.writeJSON(w, r, result) } @@ -1062,6 +1069,39 @@ func (aH *APIHandler) getTTL(w http.ResponseWriter, r *http.Request) { aH.writeJSON(w, r, result) } +func (aH *APIHandler) getUserPreferences(w http.ResponseWriter, r *http.Request) { + + result, apiError := (*aH.relationalDB).FetchUserPreference(context.Background()) + if apiError != nil { + aH.respondError(w, apiError, "Error from Fetch Dao") + return + } + + aH.writeJSON(w, r, result) +} + +func (aH *APIHandler) setUserPreferences(w http.ResponseWriter, r *http.Request) { + userParams, err := parseUserPreferences(r) + if aH.handleError(w, err, http.StatusBadRequest) { + return + } + + apiErr := (*aH.relationalDB).UpdateUserPreferece(context.Background(), userParams) + if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) { + return + } + + aH.writeJSON(w, r, map[string]string{"data": "user preferences set successfully"}) + +} + +func (aH *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) { + + version := version.GetVersion() + + aH.writeJSON(w, r, map[string]string{"version": version}) +} + // func (aH *APIHandler) getApplicationPercentiles(w http.ResponseWriter, r *http.Request) { // // vars := mux.Vars(r) diff --git a/pkg/query-service/app/parser.go b/pkg/query-service/app/parser.go index 39113823b9..1c02d17652 100644 --- a/pkg/query-service/app/parser.go +++ b/pkg/query-service/app/parser.go @@ -1045,3 +1045,15 @@ func parseGetTTL(r *http.Request) (*model.GetTTLParams, error) { return &model.GetTTLParams{Type: typeTTL, GetAllTTL: getAllTTL}, nil } + +func parseUserPreferences(r *http.Request) (*model.UserPreferences, error) { + + var userPreferences model.UserPreferences + err := json.NewDecoder(r.Body).Decode(&userPreferences) + if err != nil { + return nil, err + } + + return &userPreferences, nil + +} diff --git a/pkg/query-service/app/server.go b/pkg/query-service/app/server.go index 8e2b42b28a..62e44fc522 100644 --- a/pkg/query-service/app/server.go +++ b/pkg/query-service/app/server.go @@ -7,16 +7,18 @@ import ( "os" "time" - "github.com/google/uuid" "github.com/gorilla/handlers" "github.com/gorilla/mux" - "github.com/posthog/posthog-go" + "github.com/rs/cors" "github.com/soheilhy/cmux" "go.signoz.io/query-service/app/clickhouseReader" "go.signoz.io/query-service/app/dashboards" "go.signoz.io/query-service/app/druidReader" + "go.signoz.io/query-service/constants" + "go.signoz.io/query-service/dao" "go.signoz.io/query-service/healthcheck" + "go.signoz.io/query-service/telemetry" "go.signoz.io/query-service/utils" "go.uber.org/zap" ) @@ -66,38 +68,35 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { // if err != nil { // return nil, err // } - httpServer, err := createHTTPServer() - if err != nil { - return nil, err - } - - return &Server{ + s := &Server{ // logger: logger, // querySvc: querySvc, // queryOptions: options, // tracer: tracer, // grpcServer: grpcServer, serverOptions: serverOptions, - httpServer: httpServer, separatePorts: true, // separatePorts: grpcPort != httpPort, unavailableChannel: make(chan healthcheck.Status), - }, nil -} + } + httpServer, err := s.createHTTPServer() -var posthogClient posthog.Client -var distinctId string - -func createHTTPServer() (*http.Server, error) { - - posthogClient = posthog.New("H-htDCae7CR3RV57gUzmol6IAKtm5IMCvbcm_fwnL-w") - distinctId = uuid.New().String() - - localDB, err := dashboards.InitDB("./signoz.db") if err != nil { return nil, err } + s.httpServer = httpServer + + return s, nil +} + +func (s *Server) createHTTPServer() (*http.Server, error) { + + localDB, err := dashboards.InitDB(constants.RELATIONAL_DATASOURCE_PATH) + if err != nil { + return nil, err + } + localDB.SetMaxOpenConns(10) var reader Reader @@ -114,14 +113,19 @@ func createHTTPServer() (*http.Server, error) { return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage) } - apiHandler, err := NewAPIHandler(&reader, &posthogClient, distinctId) + relationalDB, err := dao.FactoryDao("sqlite") + if err != nil { + return nil, err + } + + apiHandler, err := NewAPIHandler(&reader, relationalDB) if err != nil { return nil, err } r := NewRouter() - r.Use(analyticsMiddleware) + r.Use(s.analyticsMiddleware) r.Use(loggingMiddleware) apiHandler.RegisterRoutes(r) @@ -152,15 +156,16 @@ func loggingMiddleware(next http.Handler) http.Handler { }) } -func analyticsMiddleware(next http.Handler) http.Handler { +func (s *Server) analyticsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { route := mux.CurrentRoute(r) path, _ := route.GetPathTemplate() - posthogClient.Enqueue(posthog.Capture{ - DistinctId: distinctId, - Event: path, - }) + data := map[string]interface{}{"path": path} + + if _, ok := telemetry.IgnoredPaths()[path]; !ok { + telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data) + } next.ServeHTTP(w, r) }) diff --git a/pkg/query-service/config/prometheus.yml b/pkg/query-service/config/prometheus.yml index c4834f9849..c515a46662 100644 --- a/pkg/query-service/config/prometheus.yml +++ b/pkg/query-service/config/prometheus.yml @@ -23,4 +23,4 @@ scrape_configs: remote_read: - - url: tcp://3.135.248.251:9001/?database=signoz_metrics + - url: tcp://localhost:9001/?database=signoz_metrics diff --git a/pkg/query-service/constants/constants.go b/pkg/query-service/constants/constants.go index 1a77b4053b..422396bf90 100644 --- a/pkg/query-service/constants/constants.go +++ b/pkg/query-service/constants/constants.go @@ -2,14 +2,26 @@ package constants import ( "os" + "strconv" ) const HTTPHostPort = "0.0.0.0:8080" var DruidClientUrl = os.Getenv("DruidClientUrl") var DruidDatasource = os.Getenv("DruidDatasource") +var DEFAULT_TELEMETRY_ANONYMOUS = false + +func IsTelemetryEnabled() bool { + isTelemetryEnabledStr := os.Getenv("TELEMETRY_ENABLED") + isTelemetryEnabledBool, err := strconv.ParseBool(isTelemetryEnabledStr) + if err != nil { + return true + } + return isTelemetryEnabledBool +} const TraceTTL = "traces" const MetricsTTL = "metrics" const ALERTMANAGER_API_PREFIX = "http://alertmanager:9093/api/" +const RELATIONAL_DATASOURCE_PATH = "/var/lib/signoz/signoz.db" diff --git a/pkg/query-service/dao/factory.go b/pkg/query-service/dao/factory.go new file mode 100644 index 0000000000..92f2b7e534 --- /dev/null +++ b/pkg/query-service/dao/factory.go @@ -0,0 +1,26 @@ +package dao + +import ( + "fmt" + + "go.signoz.io/query-service/constants" + "go.signoz.io/query-service/dao/interfaces" + "go.signoz.io/query-service/dao/sqlite" +) + +func FactoryDao(engine string) (*interfaces.ModelDao, error) { + var i interfaces.ModelDao + var err error + + switch engine { + case "sqlite": + i, err = sqlite.InitDB(constants.RELATIONAL_DATASOURCE_PATH) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("RelationalDB type: %s is not supported in query service", engine) + } + + return &i, nil +} diff --git a/pkg/query-service/dao/interfaces/interface.go b/pkg/query-service/dao/interfaces/interface.go new file mode 100644 index 0000000000..e7d043fbf7 --- /dev/null +++ b/pkg/query-service/dao/interfaces/interface.go @@ -0,0 +1,5 @@ +package interfaces + +type ModelDao interface { + UserPreferenceDao +} diff --git a/pkg/query-service/dao/interfaces/userPreference.go b/pkg/query-service/dao/interfaces/userPreference.go new file mode 100644 index 0000000000..c4770ae2de --- /dev/null +++ b/pkg/query-service/dao/interfaces/userPreference.go @@ -0,0 +1,12 @@ +package interfaces + +import ( + "context" + + "go.signoz.io/query-service/model" +) + +type UserPreferenceDao interface { + UpdateUserPreferece(ctx context.Context, userPreferences *model.UserPreferences) *model.ApiError + FetchUserPreference(ctx context.Context) (*model.UserPreferences, *model.ApiError) +} diff --git a/pkg/query-service/dao/sqlite/connection.go b/pkg/query-service/dao/sqlite/connection.go new file mode 100644 index 0000000000..8237cc21ee --- /dev/null +++ b/pkg/query-service/dao/sqlite/connection.go @@ -0,0 +1,70 @@ +package sqlite + +import ( + "context" + "fmt" + + "github.com/jmoiron/sqlx" + "go.signoz.io/query-service/constants" + "go.signoz.io/query-service/telemetry" +) + +type ModelDaoSqlite struct { + db *sqlx.DB +} + +// InitDB sets up setting up the connection pool global variable. +func InitDB(dataSourceName string) (*ModelDaoSqlite, error) { + var err error + + db, err := sqlx.Open("sqlite3", dataSourceName) + if err != nil { + return nil, err + } + db.SetMaxOpenConns(10) + + table_schema := `CREATE TABLE IF NOT EXISTS user_preferences ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + uuid TEXT NOT NULL, + isAnonymous INTEGER NOT NULL DEFAULT 0 CHECK(isAnonymous IN (0,1)), + hasOptedUpdates INTEGER NOT NULL DEFAULT 1 CHECK(hasOptedUpdates IN (0,1)) + );` + + _, err = db.Exec(table_schema) + if err != nil { + return nil, fmt.Errorf("Error in creating user_preferences table: ", err.Error()) + } + + mds := &ModelDaoSqlite{db: db} + + err = mds.initializeUserPreferences() + if err != nil { + return nil, err + } + return mds, nil + +} +func (mds *ModelDaoSqlite) initializeUserPreferences() error { + + // set anonymous setting as default in case of any failures to fetch UserPreference in below section + telemetry.GetInstance().SetTelemetryAnonymous(constants.DEFAULT_TELEMETRY_ANONYMOUS) + + ctx := context.Background() + userPreference, apiError := mds.FetchUserPreference(ctx) + + if apiError != nil { + return apiError.Err + } + if userPreference == nil { + userPreference, apiError = mds.CreateDefaultUserPreference(ctx) + } + if apiError != nil { + return apiError.Err + } + + // set telemetry fields from userPreferences + telemetry.GetInstance().SetTelemetryAnonymous(userPreference.GetIsAnonymous()) + telemetry.GetInstance().SetDistinctId(userPreference.GetUUID()) + + return nil +} diff --git a/pkg/query-service/dao/sqlite/userPreferenceImpl.go b/pkg/query-service/dao/sqlite/userPreferenceImpl.go new file mode 100644 index 0000000000..618a78ef1d --- /dev/null +++ b/pkg/query-service/dao/sqlite/userPreferenceImpl.go @@ -0,0 +1,91 @@ +package sqlite + +import ( + "context" + "fmt" + + "github.com/google/uuid" + "go.signoz.io/query-service/model" + "go.signoz.io/query-service/telemetry" + "go.uber.org/zap" +) + +func (mds *ModelDaoSqlite) FetchUserPreference(ctx context.Context) (*model.UserPreferences, *model.ApiError) { + + userPreferences := []model.UserPreferences{} + query := fmt.Sprintf("SELECT id, uuid, isAnonymous, hasOptedUpdates FROM user_preferences;") + + err := mds.db.Select(&userPreferences, query) + + if err != nil { + zap.S().Debug("Error in processing sql query: ", err) + return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + + // zap.S().Info(query) + if len(userPreferences) > 1 { + zap.S().Debug("Error in processing sql query: ", fmt.Errorf("more than 1 row in user_preferences found")) + return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + + if len(userPreferences) == 0 { + return nil, nil + } + + return &userPreferences[0], nil + +} + +func (mds *ModelDaoSqlite) UpdateUserPreferece(ctx context.Context, userPreferences *model.UserPreferences) *model.ApiError { + + tx, err := mds.db.Begin() + if err != nil { + return &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + + userPreferencesFound, apiError := mds.FetchUserPreference(ctx) + if apiError != nil { + return apiError + } + + stmt, err := tx.Prepare(`UPDATE user_preferences SET isAnonymous=$1, hasOptedUpdates=$2 WHERE id=$3;`) + defer stmt.Close() + + if err != nil { + zap.S().Errorf("Error in preparing statement for INSERT to user_preferences\n", err) + tx.Rollback() + return &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + + query_result, err := stmt.Exec(userPreferences.GetIsAnonymous(), userPreferences.GetHasOptedUpdate(), userPreferencesFound.GetId()) + if err != nil { + zap.S().Errorf("Error in Executing prepared statement for INSERT to user_preferences\n", err) + tx.Rollback() // return an error too, we may want to wrap them + return &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + zap.S().Debug(query_result.RowsAffected()) + zap.S().Debug(userPreferences.GetIsAnonymous(), userPreferences.GetHasOptedUpdate(), userPreferencesFound.GetId()) + + err = tx.Commit() + if err != nil { + zap.S().Errorf("Error in commiting transaction for INSERT to user_preferences\n", err) + return &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + telemetry.GetInstance().SetTelemetryAnonymous(userPreferences.GetIsAnonymous()) + + return nil +} + +func (mds *ModelDaoSqlite) CreateDefaultUserPreference(ctx context.Context) (*model.UserPreferences, *model.ApiError) { + + uuid := uuid.New().String() + _, err := mds.db.ExecContext(ctx, `INSERT INTO user_preferences (uuid, isAnonymous, hasOptedUpdates) VALUES (?, 0, 1);`, uuid) + + if err != nil { + zap.S().Errorf("Error in preparing statement for INSERT to user_preferences\n", err) + return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} + } + + return mds.FetchUserPreference(ctx) + +} diff --git a/pkg/query-service/go.mod b/pkg/query-service/go.mod index d64a824ab2..79dfc473bb 100644 --- a/pkg/query-service/go.mod +++ b/pkg/query-service/go.mod @@ -4,14 +4,19 @@ go 1.14 require ( cloud.google.com/go v0.88.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/ClickHouse/clickhouse-go v1.4.5 github.com/Microsoft/go-winio v0.5.1 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect github.com/aws/aws-sdk-go v1.27.0 // indirect + + github.com/beorn7/perks v1.0.1 // indirect + github.com/containerd/containerd v1.4.12 // indirect github.com/dhui/dktest v0.3.4 // indirect github.com/docker/docker v20.10.12+incompatible // indirect + github.com/frankban/quicktest v1.13.0 // indirect github.com/go-kit/log v0.1.0 github.com/golang-migrate/migrate/v4 v4.14.1 @@ -36,7 +41,6 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/oklog/oklog v0.3.2 github.com/oklog/run v1.1.0 // indirect github.com/onsi/gomega v1.14.0 // indirect @@ -45,7 +49,6 @@ require ( github.com/pascaldekloe/goe v0.1.0 // indirect github.com/pierrec/lz4 v2.4.1+incompatible // indirect github.com/pkg/errors v0.9.1 - github.com/posthog/posthog-go v0.0.0-20200525173953-e46dc8e6b89b github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03 github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1 github.com/prometheus/procfs v0.0.8 // indirect @@ -53,9 +56,11 @@ require ( github.com/rs/cors v1.7.0 github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/segmentio/backo-go v1.0.0 // indirect github.com/smartystreets/goconvey v1.6.4 github.com/soheilhy/cmux v0.1.4 github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/pflag v1.0.3 // indirect github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect @@ -68,7 +73,7 @@ require ( google.golang.org/grpc/examples v0.0.0-20210803221256-6ba56c814be7 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect - gotest.tools/v3 v3.0.3 // indirect + gopkg.in/segmentio/analytics-go.v3 v3.1.0 ) diff --git a/pkg/query-service/go.sum b/pkg/query-service/go.sum index 7daf49653f..034d9b992e 100644 --- a/pkg/query-service/go.sum +++ b/pkg/query-service/go.sum @@ -58,7 +58,6 @@ github.com/ClickHouse/clickhouse-go v1.3.12/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhH github.com/ClickHouse/clickhouse-go v1.4.5 h1:FfhyEnv6/BaWldyjgT2k4gDDmeNwJ9C4NbY/MXxJlXk= github.com/ClickHouse/clickhouse-go v1.4.5/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -76,11 +75,13 @@ github.com/aws/aws-sdk-go v1.13.44-0.20180507225419-00862f899353/go.mod h1:ZRmQr github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0 h1:0xphMHGMLBrPMfxR2AmVjZKcMEESEgWF8Kru94BNByk= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1 h1:OnJHjoVbY69GG4gclp0ngXfywigLhR6rrgUxmxQRWO4= github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk= github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -104,16 +105,12 @@ github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68m github.com/cockroachdb/cockroach v0.0.0-20170608034007-84bc9597164f/go.mod h1:xeT/CQ0qZHangbYbWShlCGAx31aV4AjGswDUjhKS6HQ= github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/containerd/containerd v1.4.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1 h1:pASeJT3R3YyVn+94qEPk0SnU1OQ20Jd/T+SPKy9xehY= github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.12 h1:V+SHzYmhng/iju6M5nFrpTTusrhidoxKTwdwLw+u4c4= -github.com/containerd/containerd v1.4.12/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -123,15 +120,12 @@ github.com/dgrijalva/jwt-go v3.0.1-0.20161101193935-9ed569b5d1ac+incompatible/go github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bits v0.0.0-20160601073636-2ad8d707cc05/go.mod h1:/9UYwwvZuEgp+mQ4960SHWCU1FS+FgdFX+m5ExFByNs= +github.com/dhui/dktest v0.3.3 h1:DBuH/9GFaWbDRa42qsut/hbQu+srAQ0rPWnUoiGX7CA= github.com/dhui/dktest v0.3.3/go.mod h1:EML9sP4sqJELHn4jV7B0TY8oF6077nk83/tz7M56jcQ= -github.com/dhui/dktest v0.3.4 h1:VbUEcaSP+U2/yUr9d2JhSThXYEnDlGabRSHe2rIE46E= -github.com/dhui/dktest v0.3.4/go.mod h1:4m4n6lmXlmVfESth7mzdcv8nBI5mOb5UROPqjM02csU= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:iWPIG7pWIsCwT6ZtHnTUpoVMnete7O/pzd9HFE3+tn8= github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U= -github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -177,9 +171,8 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78 github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/gogo/protobuf v0.0.0-20171123125729-971cbfd2e72b/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-migrate/migrate/v4 v4.14.1 h1:qmRd/rNGjM1r3Ve5gHd5ZplytrD02UcItYNxJ3iUHHE= github.com/golang-migrate/migrate/v4 v4.14.1/go.mod h1:l7Ks0Au6fYHuUIxUhQ0rcVX1uLlJg54C/VvW7tvxSz0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -378,7 +371,6 @@ github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -421,8 +413,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -479,8 +469,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posthog/posthog-go v0.0.0-20200525173953-e46dc8e6b89b h1:a8lLvAV+8OQXnG18ZOV5ctFQY7jLHa3brA9BBhe1SVs= -github.com/posthog/posthog-go v0.0.0-20200525173953-e46dc8e6b89b/go.mod h1:s7IZAf1WuSPTb/R/agnboYa+gDnoKGdqIk7p2aFHDYs= github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03 h1:hqNopISksxji/N5zEy1xMN7TrnSyVG/LymiwnkXi6/Q= github.com/prometheus/client_golang v0.9.0-pre1.0.20181001174001-0a8115f42e03/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= @@ -507,6 +495,8 @@ github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZj github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/segmentio/backo-go v1.0.0 h1:kbOAtGJY2DqOR0jfRkYEorx/b18RgtepGtY3+Cpe6qA= +github.com/segmentio/backo-go v1.0.0/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/vfsgen v0.0.0-20180711163814-62bca832be04/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= @@ -795,7 +785,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -825,7 +814,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200806022845-90696ccdc692/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -839,7 +827,6 @@ golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -931,7 +918,6 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1004,6 +990,8 @@ gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1 gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/segmentio/analytics-go.v3 v3.1.0 h1:UzxH1uaGZRpMKDhJyBz0pexz6yUoBU3x8bJsRk/HV6U= +gopkg.in/segmentio/analytics-go.v3 v3.1.0/go.mod h1:4QqqlTlSSpVlWA9/9nDcPw+FkM2yv1NQoYjUbL9/JAw= 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.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1018,9 +1006,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/query-service/model/userPreferences.go b/pkg/query-service/model/userPreferences.go new file mode 100644 index 0000000000..0a6ca2d1e4 --- /dev/null +++ b/pkg/query-service/model/userPreferences.go @@ -0,0 +1,27 @@ +package model + +type UserPreferences struct { + Id int `json:"id" db:"id"` + Uuid string `json:"uuid" db:"uuid"` + IsAnonymous bool `json:"isAnonymous" db:"isAnonymous"` + HasOptedUpdates bool `json:"hasOptedUpdates" db:"hasOptedUpdates"` +} + +func (up *UserPreferences) SetIsAnonymous(isAnonymous bool) { + up.IsAnonymous = isAnonymous +} +func (up *UserPreferences) SetHasOptedUpdate(hasOptedUpdates bool) { + up.HasOptedUpdates = hasOptedUpdates +} +func (up *UserPreferences) GetIsAnonymous() bool { + return up.IsAnonymous +} +func (up *UserPreferences) GetHasOptedUpdate() bool { + return up.HasOptedUpdates +} +func (up *UserPreferences) GetId() int { + return up.Id +} +func (up *UserPreferences) GetUUID() string { + return up.Uuid +} diff --git a/pkg/query-service/telemetry/ignoredPaths.go b/pkg/query-service/telemetry/ignoredPaths.go new file mode 100644 index 0000000000..3fc2f1898a --- /dev/null +++ b/pkg/query-service/telemetry/ignoredPaths.go @@ -0,0 +1,9 @@ +package telemetry + +func IgnoredPaths() map[string]struct{} { + ignoredPaths := map[string]struct{}{ + "/api/v1/tags": struct{}{}, + } + + return ignoredPaths +} diff --git a/pkg/query-service/telemetry/telemetry.go b/pkg/query-service/telemetry/telemetry.go new file mode 100644 index 0000000000..90632784e7 --- /dev/null +++ b/pkg/query-service/telemetry/telemetry.go @@ -0,0 +1,155 @@ +package telemetry + +import ( + "io/ioutil" + "net/http" + "sync" + "time" + + "go.signoz.io/query-service/constants" + "go.signoz.io/query-service/model" + "go.signoz.io/query-service/version" + "gopkg.in/segmentio/analytics-go.v3" +) + +const ( + TELEMETRY_EVENT_PATH = "API Call" + TELEMETRY_EVENT_USER = "User" + TELEMETRY_EVENT_INPRODUCT_FEEDBACK = "InProduct Feeback Submitted" + TELEMETRY_EVENT_NUMBER_OF_SERVICES = "Number of Services" + TELEMETRY_EVENT_HEART_BEAT = "Heart Beat" +) + +const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz" + +var telemetry *Telemetry +var once sync.Once + +type Telemetry struct { + operator analytics.Client + ipAddress string + isEnabled bool + isAnonymous bool + distinctId string +} + +func createTelemetry() { + telemetry = &Telemetry{ + operator: analytics.New(api_key), + ipAddress: getOutboundIP(), + } + + data := map[string]interface{}{} + + telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled()) + telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data) + ticker := time.NewTicker(6 * time.Hour) + go func() { + for { + select { + case <-ticker.C: + telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data) + } + } + }() + +} + +// Get preferred outbound ip of this machine +func getOutboundIP() string { + + ip := []byte("NA") + resp, err := http.Get("https://api.ipify.org?format=text") + + 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 == TELEMETRY_EVENT_USER && 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()) + + for k, v := range data { + properties.Set(k, v) + } + + userId := a.ipAddress + if a.isTelemetryAnonymous() { + 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 GetInstance() *Telemetry { + + once.Do(func() { + createTelemetry() + }) + + return telemetry +} diff --git a/pkg/query-service/version/version.go b/pkg/query-service/version/version.go new file mode 100644 index 0000000000..cad1bfa6f0 --- /dev/null +++ b/pkg/query-service/version/version.go @@ -0,0 +1,24 @@ +package version + +import ( + "go.uber.org/zap" +) + +// These fields are set during an official build +// Global vars set from command-line arguments +var ( + version = "--" + buildhash = "--" + buildtime = "--" +) + +//PrintVersionInfo displays the kyverno version - git version +func PrintVersionInfo() { + zap.S().Info("Version: ", version) + zap.S().Info("BuildHash: ", buildhash) + zap.S().Info("BuildTime: ", buildtime) +} + +func GetVersion() string { + return version +}