Path: blob/main/components/common-go/analytics/analytics.go
2498 views
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package analytics56import (7"os"8"time"910"github.com/gitpod-io/gitpod/common-go/log"11segment "gopkg.in/segmentio/analytics-go.v3"12)1314// Identity identifies a user15type Identity struct {16UserID string17AnonymousID string18}1920// IdentifyMessage parametrises the Identify call21type IdentifyMessage struct {22Identity2324Traits map[string]interface{}25Timestamp time.Time26}2728// TrackMessage parametrises the Track call29type TrackMessage struct {30Identity3132Event string33Properties map[string]interface{}34Timestamp time.Time35}3637// NewFromEnvironment creates a new analytics writer based on the GITPOD_ANALYTICS_WRITER38// environment variable. This function never returns nil and callers are expected to call39// Close() on the received writer.40func NewFromEnvironment() Writer {41switch os.Getenv("GITPOD_ANALYTICS_WRITER") {42case "log":43log.Debug("log analytics")44return &logAnalyticsWriter{}45case "segment":46log.Debug("segment analytics")47client, err := segment.NewWithConfig(os.Getenv("GITPOD_ANALYTICS_SEGMENT_KEY"), segment.Config{48Endpoint: os.Getenv("GITPOD_ANALYTICS_SEGMENT_ENDPOINT"),49})50if err != nil {51log.WithError(err).Error("cannot create segment client")52return &noAnalyticsWriter{}53}54return &segmentAnalyticsWriter{client}55default:56log.Debug("no analytics")57return &noAnalyticsWriter{}58}59}6061// Writer can write analytics62type Writer interface {63Identify(IdentifyMessage)64Track(TrackMessage)65Close() error66}6768type logAnalyticsWriter struct{}6970func (s *logAnalyticsWriter) Identify(m IdentifyMessage) {71log.WithField("message", m).Debug("analytics identify")72}7374func (s *logAnalyticsWriter) Track(m TrackMessage) {75log.WithField("message", m).Debug("analytics track")76}7778func (s *logAnalyticsWriter) Close() error { return nil }7980type noAnalyticsWriter struct{}8182func (s *noAnalyticsWriter) Identify(m IdentifyMessage) {}83func (s *noAnalyticsWriter) Track(m TrackMessage) {}84func (s *noAnalyticsWriter) Close() error { return nil }8586type segmentAnalyticsWriter struct {87Client segment.Client88}8990func (s *segmentAnalyticsWriter) Identify(m IdentifyMessage) {91defer recover()9293_ = s.Client.Enqueue(segment.Identify{94AnonymousId: m.AnonymousID,95UserId: m.UserID,96Timestamp: m.Timestamp,97Traits: m.Traits,98})99}100101func (s *segmentAnalyticsWriter) Track(m TrackMessage) {102defer recover()103104_ = s.Client.Enqueue(segment.Track{105AnonymousId: m.AnonymousID,106UserId: m.UserID,107Event: m.Event,108Timestamp: m.Timestamp,109Properties: m.Properties,110})111}112113func (s *segmentAnalyticsWriter) Close() error {114defer recover()115116return s.Client.Close()117}118119120