github.com/kubeshop/testkube@v1.17.23/pkg/telemetry/sender_sio.go (about)

     1  package telemetry
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"os"
     7  
     8  	"github.com/segmentio/analytics-go/v3"
     9  
    10  	"github.com/kubeshop/testkube/pkg/log"
    11  	"github.com/kubeshop/testkube/pkg/utils"
    12  )
    13  
    14  const SegmentioEnvVariableName = "TESTKUBE_SEGMENTIO_KEY"
    15  const CloudEnvVariableName = "TESTKUBE_CLOUD_API_KEY"
    16  const ProEnvVariableName = "TESTKUBE_PRO_API_KEY"
    17  
    18  // Brew builds can't be parametrized so we are embedding this one
    19  var SegmentioKey = "jELokNFNcLeQhxdpGF47PcxCtOLpwVuu"
    20  var CloudSegmentioKey = ""
    21  
    22  func StdLogger() analytics.Logger {
    23  	return stdLogger{}
    24  }
    25  
    26  type stdLogger struct {
    27  }
    28  
    29  func (l stdLogger) Logf(format string, args ...interface{}) {
    30  	log.DefaultLogger.Debugw("sending telemetry data", "info", fmt.Sprintf(format, args...))
    31  }
    32  
    33  func (l stdLogger) Errorf(format string, args ...interface{}) {
    34  	log.DefaultLogger.Debugw("sending telemetry data", "error", fmt.Sprintf(format, args...))
    35  }
    36  
    37  // SegmentioSender sends ananymous telemetry data to segment.io
    38  // TODO refactor Sender func as out is not needed (use debug loggers to log output)
    39  func SegmentioSender(client *http.Client, payload Payload) (out string, err error) {
    40  
    41  	// TODO consider removing this as CLI has fixed key and API overrides it in build time
    42  	if key, ok := os.LookupEnv(SegmentioEnvVariableName); ok {
    43  		SegmentioKey = key
    44  	}
    45  	key := utils.GetEnvVarWithDeprecation(ProEnvVariableName, CloudEnvVariableName, "")
    46  	if key != "" {
    47  		SegmentioKey = CloudSegmentioKey
    48  	}
    49  
    50  	segmentio, err := analytics.NewWithConfig(SegmentioKey, analytics.Config{Logger: StdLogger()})
    51  	if err != nil {
    52  		return out, err
    53  	}
    54  	defer segmentio.Close()
    55  
    56  	for _, event := range payload.Events {
    57  		err := segmentio.Enqueue(mapEvent(payload.UserID, event))
    58  		if err != nil {
    59  			return out, err
    60  		}
    61  	}
    62  
    63  	return
    64  }
    65  
    66  // TODO refactor Event model to be more generic not GA4 like after removoing debug and GA4
    67  func mapEvent(userID string, event Event) analytics.Track {
    68  	return analytics.Track{
    69  		Event:      event.Name,
    70  		UserId:     userID,
    71  		Properties: mapProperties(event.Params),
    72  	}
    73  }
    74  
    75  func mapProperties(params Params) analytics.Properties {
    76  	properties := analytics.NewProperties().
    77  		Set("name", params.AppName).
    78  		Set("version", params.AppVersion).
    79  		Set("arch", params.Architecture).
    80  		Set("os", params.OperatingSystem).
    81  		Set("clusterId", params.ClusterID).
    82  		Set("eventCategory", params.EventCategory).
    83  		Set("host", params.Host).
    84  		Set("contextType", params.Context.Type).
    85  		Set("cloudOrganizationId", params.Context.OrganizationId).
    86  		Set("cloudEnvironmentId", params.Context.EnvironmentId).
    87  		Set("machineId", params.MachineID).
    88  		Set("clusterType", params.ClusterType).
    89  		Set("errorType", params.ErrorType).
    90  		Set("errorStackTrace", params.ErrorStackTrace)
    91  
    92  	if params.DataSource != "" {
    93  		properties = properties.Set("dataSource", params.DataSource)
    94  	}
    95  
    96  	if params.TestType != "" {
    97  		properties = properties.Set("testType", params.TestType)
    98  	}
    99  
   100  	if params.DurationMs != 0 {
   101  		properties = properties.Set("durationMs", params.DurationMs)
   102  	}
   103  
   104  	if params.Status != "" {
   105  		properties = properties.Set("status", params.Status)
   106  	}
   107  
   108  	if params.TestSource != "" {
   109  		properties = properties.Set("testSource", params.TestSource)
   110  	}
   111  
   112  	if params.TestSuiteSteps != 0 {
   113  		properties = properties.Set("testSuiteSteps", params.TestSuiteSteps)
   114  	}
   115  
   116  	return properties
   117  }