Skip to content

Commit 1139244

Browse files
authored
Add telemetry for deploy and operator init (#1559)
1 parent 3a58a88 commit 1139244

File tree

6 files changed

+288
-8
lines changed

6 files changed

+288
-8
lines changed

cli/local/api.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ import (
2828
"github.com/cortexlabs/cortex/pkg/lib/files"
2929
"github.com/cortexlabs/cortex/pkg/lib/prompt"
3030
"github.com/cortexlabs/cortex/pkg/lib/sets/strset"
31+
"github.com/cortexlabs/cortex/pkg/lib/telemetry"
3132
"github.com/cortexlabs/cortex/pkg/operator/schema"
33+
"github.com/cortexlabs/cortex/pkg/types"
3234
"github.com/cortexlabs/cortex/pkg/types/spec"
3335
"github.com/cortexlabs/cortex/pkg/types/userconfig"
3436
)
3537

3638
var _deploymentID = "local"
3739

3840
func UpdateAPI(apiConfig *userconfig.API, models []spec.CuratedModelResource, configPath string, projectID string, deployDisallowPrompt bool, awsClient *aws.Client) (*schema.APIResponse, string, error) {
41+
telemetry.Event("operator.deploy", apiConfig.TelemetryEvent(types.LocalProviderType))
42+
3943
var incompatibleVersion string
4044
encounteredVersionMismatch := false
4145
prevAPISpec, err := FindAPISpec(apiConfig.Name)

pkg/operator/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func main() {
4141
exit.Error(err)
4242
}
4343

44-
telemetry.Event("operator.init")
44+
telemetry.Event("operator.init", config.Cluster.TelemetryEvent())
4545

4646
_, err := operator.UpdateMemoryCapacityConfigMap()
4747
if err != nil {

pkg/operator/operator/cron.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,17 @@ func InstanceTelemetry() error {
131131
fixedPrice := clusterFixedPrice()
132132

133133
properties := map[string]interface{}{
134-
"region": *config.Cluster.Region,
135-
"instance_count": totalInstances,
136-
"instances": instanceInfos,
137-
"fixed_price": fixedPrice,
138-
"total_price": totalInstancePrice + fixedPrice,
139-
"total_price_if_on_demand": totalInstancePriceIfOnDemand + fixedPrice,
134+
"region": *config.Cluster.Region,
135+
"instance_count": totalInstances,
136+
"instances": instanceInfos,
137+
"fixed_price": fixedPrice,
138+
"workload_price": totalInstancePrice,
139+
"workload_price_if_on_demand": totalInstancePriceIfOnDemand,
140+
"total_price": totalInstancePrice + fixedPrice,
141+
"total_price_if_on_demand": totalInstancePriceIfOnDemand + fixedPrice,
140142
}
141143

142-
telemetry.Event("operator.cron", properties)
144+
telemetry.Event("operator.cron", properties, config.Cluster.TelemetryEvent())
143145

144146
return nil
145147
}

pkg/operator/resources/resources.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ func UpdateAPI(apiConfig *userconfig.API, models []spec.CuratedModelResource, pr
141141
return nil, "", ErrorCannotChangeKindOfDeployedAPI(apiConfig.Name, apiConfig.Kind, deployedResource.Kind)
142142
}
143143

144+
telemetry.Event("operator.deploy", apiConfig.TelemetryEvent(types.AWSProviderType))
145+
144146
var api *spec.API
145147
var msg string
146148
switch apiConfig.Kind {

pkg/types/clusterconfig/clusterconfig.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/cortexlabs/cortex/pkg/lib/prompt"
3838
s "github.com/cortexlabs/cortex/pkg/lib/strings"
3939
"github.com/cortexlabs/cortex/pkg/lib/table"
40+
"github.com/cortexlabs/cortex/pkg/types"
4041
)
4142

4243
const (
@@ -1200,3 +1201,131 @@ func (cc *Config) UserTable() table.KeyValuePairs {
12001201
func (cc *Config) UserStr() string {
12011202
return cc.UserTable().String()
12021203
}
1204+
1205+
func (cc *Config) TelemetryEvent() map[string]interface{} {
1206+
event := map[string]interface{}{
1207+
"provider": types.AWSProviderType,
1208+
}
1209+
1210+
if cc.InstanceType != nil {
1211+
event["instance_type._is_defined"] = true
1212+
event["instance_type"] = *cc.InstanceType
1213+
}
1214+
if cc.MinInstances != nil {
1215+
event["min_instances._is_defined"] = true
1216+
event["min_instances"] = *cc.MinInstances
1217+
}
1218+
if cc.MaxInstances != nil {
1219+
event["max_instances._is_defined"] = true
1220+
event["max_instances"] = *cc.MaxInstances
1221+
}
1222+
event["instance_volume_size"] = cc.InstanceVolumeSize
1223+
event["instance_volume_type"] = cc.InstanceVolumeType
1224+
if cc.InstanceVolumeIOPS != nil {
1225+
event["instance_volume_iops._is_defined"] = true
1226+
event["instance_volume_iops"] = *cc.InstanceVolumeIOPS
1227+
}
1228+
if len(cc.Tags) > 0 {
1229+
event["tags._is_defined"] = true
1230+
event["tags._len"] = len(cc.Tags)
1231+
}
1232+
if cc.ClusterName != "cortex" {
1233+
event["cluster_name._is_custom"] = true
1234+
}
1235+
if cc.Region != nil {
1236+
event["region._is_defined"] = true
1237+
event["region"] = *cc.Region
1238+
}
1239+
if len(cc.AvailabilityZones) > 0 {
1240+
event["availability_zones._is_defined"] = true
1241+
event["availability_zones._len"] = len(cc.AvailabilityZones)
1242+
event["availability_zones"] = cc.AvailabilityZones
1243+
}
1244+
if cc.SSLCertificateARN != nil {
1245+
event["ssl_certificate_arn._is_defined"] = true
1246+
}
1247+
if !strings.HasPrefix(cc.Bucket, cc.ClusterName+"-") {
1248+
event["bucket._is_custom"] = true
1249+
}
1250+
event["subnet_visibility"] = cc.SubnetVisibility
1251+
event["nat_gateway"] = cc.NATGateway
1252+
event["api_load_balancer_scheme"] = cc.APILoadBalancerScheme
1253+
event["operator_load_balancer_scheme"] = cc.OperatorLoadBalancerScheme
1254+
event["api_gateway"] = cc.APIGatewaySetting
1255+
if cc.VPCCIDR != nil {
1256+
event["vpc_cidr._is_defined"] = true
1257+
}
1258+
if !strings.HasPrefix(cc.ImageOperator, "cortexlabs/") {
1259+
event["image_operator._is_custom"] = true
1260+
}
1261+
if !strings.HasPrefix(cc.ImageManager, "cortexlabs/") {
1262+
event["image_manager._is_custom"] = true
1263+
}
1264+
if !strings.HasPrefix(cc.ImageDownloader, "cortexlabs/") {
1265+
event["image_downloader._is_custom"] = true
1266+
}
1267+
if !strings.HasPrefix(cc.ImageRequestMonitor, "cortexlabs/") {
1268+
event["image_request_monitor._is_custom"] = true
1269+
}
1270+
if !strings.HasPrefix(cc.ImageClusterAutoscaler, "cortexlabs/") {
1271+
event["image_cluster_autoscaler._is_custom"] = true
1272+
}
1273+
if !strings.HasPrefix(cc.ImageMetricsServer, "cortexlabs/") {
1274+
event["image_metrics_server._is_custom"] = true
1275+
}
1276+
if !strings.HasPrefix(cc.ImageInferentia, "cortexlabs/") {
1277+
event["image_inferentia._is_custom"] = true
1278+
}
1279+
if !strings.HasPrefix(cc.ImageNeuronRTD, "cortexlabs/") {
1280+
event["image_neuron_rtd._is_custom"] = true
1281+
}
1282+
if !strings.HasPrefix(cc.ImageNvidia, "cortexlabs/") {
1283+
event["image_nvidia._is_custom"] = true
1284+
}
1285+
if !strings.HasPrefix(cc.ImageFluentd, "cortexlabs/") {
1286+
event["image_fluentd._is_custom"] = true
1287+
}
1288+
if !strings.HasPrefix(cc.ImageStatsd, "cortexlabs/") {
1289+
event["image_statsd._is_custom"] = true
1290+
}
1291+
if !strings.HasPrefix(cc.ImageIstioProxy, "cortexlabs/") {
1292+
event["image_istio_proxy._is_custom"] = true
1293+
}
1294+
if !strings.HasPrefix(cc.ImageIstioPilot, "cortexlabs/") {
1295+
event["image_istio_pilot._is_custom"] = true
1296+
}
1297+
if cc.Spot != nil {
1298+
event["spot._is_defined"] = true
1299+
event["spot"] = *cc.Spot
1300+
}
1301+
if cc.SpotConfig != nil {
1302+
event["spot_config._is_defined"] = true
1303+
if len(cc.SpotConfig.InstanceDistribution) > 0 {
1304+
event["spot_config.instance_distribution._is_defined"] = true
1305+
event["spot_config.instance_distribution._len"] = len(cc.SpotConfig.InstanceDistribution)
1306+
event["spot_config.instance_distribution"] = cc.SpotConfig.InstanceDistribution
1307+
}
1308+
if cc.SpotConfig.OnDemandBaseCapacity != nil {
1309+
event["spot_config.on_demand_base_capacity._is_defined"] = true
1310+
event["spot_config.on_demand_base_capacity"] = *cc.SpotConfig.OnDemandBaseCapacity
1311+
}
1312+
if cc.SpotConfig.OnDemandPercentageAboveBaseCapacity != nil {
1313+
event["spot_config.on_demand_percentage_above_base_capacity._is_defined"] = true
1314+
event["spot_config.on_demand_percentage_above_base_capacity"] = *cc.SpotConfig.OnDemandPercentageAboveBaseCapacity
1315+
}
1316+
if cc.SpotConfig.MaxPrice != nil {
1317+
event["spot_config.max_price._is_defined"] = true
1318+
event["spot_config.max_price"] = *cc.SpotConfig.MaxPrice
1319+
}
1320+
if cc.SpotConfig.InstancePools != nil {
1321+
event["spot_config.instance_pools._is_defined"] = true
1322+
event["spot_config.instance_pools"] = *cc.SpotConfig.InstancePools
1323+
}
1324+
if cc.SpotConfig.OnDemandBackup != nil {
1325+
event["spot_config.on_demand_backup._is_defined"] = true
1326+
event["spot_config.on_demand_backup"] = *cc.SpotConfig.OnDemandBackup
1327+
}
1328+
}
1329+
1330+
return event
1331+
}

pkg/types/userconfig/api.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/cortexlabs/cortex/pkg/consts"
2525
"github.com/cortexlabs/cortex/pkg/lib/k8s"
2626
s "github.com/cortexlabs/cortex/pkg/lib/strings"
27+
"github.com/cortexlabs/cortex/pkg/lib/urls"
2728
"github.com/cortexlabs/cortex/pkg/types"
2829
"github.com/cortexlabs/yaml"
2930
kmeta "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -567,3 +568,145 @@ func ZeroCompute() Compute {
567568
GPU: 0,
568569
}
569570
}
571+
572+
func (api *API) TelemetryEvent(provider types.ProviderType) map[string]interface{} {
573+
event := map[string]interface{}{
574+
"provider": provider,
575+
"kind": api.Kind,
576+
}
577+
578+
if len(api.APIs) > 0 {
579+
event["apis._is_defined"] = true
580+
event["apis._len"] = len(api.APIs)
581+
}
582+
583+
if api.Monitoring != nil {
584+
event["monitoring._is_defined"] = true
585+
event["monitoring.model_type"] = api.Monitoring.ModelType
586+
if api.Monitoring.Key != nil {
587+
event["monitoring.key._is_defined"] = true
588+
}
589+
}
590+
591+
if api.Networking != nil {
592+
event["networking._is_defined"] = true
593+
event["networking.api_gateway"] = api.Networking.APIGateway
594+
if api.Networking.Endpoint != nil {
595+
event["networking.endpoint._is_defined"] = true
596+
if urls.CanonicalizeEndpoint(api.Name) != *api.Networking.Endpoint {
597+
event["networking.endpoint._is_custom"] = true
598+
}
599+
}
600+
if api.Networking.LocalPort != nil {
601+
event["networking.local_port._is_defined"] = true
602+
event["networking.local_port"] = *api.Networking.LocalPort
603+
}
604+
}
605+
606+
if api.Compute != nil {
607+
event["compute._is_defined"] = true
608+
if api.Compute.CPU != nil {
609+
event["compute.cpu._is_defined"] = true
610+
event["compute.cpu"] = float64(api.Compute.CPU.MilliValue()) / 1000
611+
}
612+
if api.Compute.Mem != nil {
613+
event["compute.mem._is_defined"] = true
614+
event["compute.mem"] = api.Compute.Mem.Value()
615+
}
616+
event["compute.gpu"] = api.Compute.GPU
617+
event["compute.inf"] = api.Compute.Inf
618+
}
619+
620+
if api.Predictor != nil {
621+
event["predictor._is_defined"] = true
622+
event["predictor.type"] = api.Predictor.Type
623+
event["predictor.processes_per_replica"] = api.Predictor.ProcessesPerReplica
624+
event["predictor.threads_per_process"] = api.Predictor.ThreadsPerProcess
625+
626+
if api.Predictor.ModelPath != nil {
627+
event["predictor.model_path._is_defined"] = true
628+
}
629+
if api.Predictor.SignatureKey != nil {
630+
event["predictor.signature_key._is_defined"] = true
631+
}
632+
if api.Predictor.PythonPath != nil {
633+
event["predictor.python_path._is_defined"] = true
634+
}
635+
if !strings.HasPrefix(api.Predictor.Image, "cortexlabs/") {
636+
event["predictor.image._is_custom"] = true
637+
}
638+
if !strings.HasPrefix(api.Predictor.TensorFlowServingImage, "cortexlabs/") {
639+
event["predictor.tensorflow_serving_image._is_custom"] = true
640+
}
641+
if len(api.Predictor.Config) > 0 {
642+
event["predictor.config._is_defined"] = true
643+
event["predictor.config._len"] = len(api.Predictor.Config)
644+
}
645+
if len(api.Predictor.Env) > 0 {
646+
event["predictor.env._is_defined"] = true
647+
event["predictor.env._len"] = len(api.Predictor.Env)
648+
}
649+
650+
if api.Predictor.Models != nil {
651+
event["predictor.models._is_defined"] = true
652+
if len(api.Predictor.Models.Paths) > 0 {
653+
event["predictor.models.paths._is_defined"] = true
654+
event["predictor.models.paths._len"] = len(api.Predictor.Models.Paths)
655+
var numSignatureKeysDefined int
656+
for _, mmPath := range api.Predictor.Models.Paths {
657+
if mmPath.SignatureKey != nil {
658+
numSignatureKeysDefined++
659+
}
660+
}
661+
event["predictor.models.paths._num_signature_keys_defined"] = numSignatureKeysDefined
662+
}
663+
if api.Predictor.Models.Dir != nil {
664+
event["predictor.models.dir._is_defined"] = true
665+
}
666+
if api.Predictor.Models.CacheSize != nil {
667+
event["predictor.models.cache_size._is_defined"] = true
668+
event["predictor.models.cache_size"] = *api.Predictor.Models.CacheSize
669+
}
670+
if api.Predictor.Models.DiskCacheSize != nil {
671+
event["predictor.models.disk_cache_size._is_defined"] = true
672+
event["predictor.models.disk_cache_size"] = *api.Predictor.Models.DiskCacheSize
673+
}
674+
if api.Predictor.Models.SignatureKey != nil {
675+
event["predictor.models.signature_key._is_defined"] = true
676+
}
677+
}
678+
679+
if api.Predictor.ServerSideBatching != nil {
680+
event["predictor.server_side_batching._is_defined"] = true
681+
event["predictor.server_side_batching.max_batch_size"] = api.Predictor.ServerSideBatching.MaxBatchSize
682+
event["predictor.server_side_batching.batch_interval"] = api.Predictor.ServerSideBatching.BatchInterval.Seconds()
683+
}
684+
}
685+
686+
if api.UpdateStrategy != nil {
687+
event["update_strategy._is_defined"] = true
688+
event["update_strategy.max_surge"] = api.UpdateStrategy.MaxSurge
689+
event["update_strategy.max_unavailable"] = api.UpdateStrategy.MaxUnavailable
690+
}
691+
692+
if api.Autoscaling != nil {
693+
event["autoscaling._is_defined"] = true
694+
event["autoscaling.min_replicas"] = api.Autoscaling.MinReplicas
695+
event["autoscaling.max_replicas"] = api.Autoscaling.MaxReplicas
696+
event["autoscaling.init_replicas"] = api.Autoscaling.InitReplicas
697+
if api.Autoscaling.TargetReplicaConcurrency != nil {
698+
event["autoscaling.target_replica_concurrency._is_defined"] = true
699+
event["autoscaling.target_replica_concurrency"] = *api.Autoscaling.TargetReplicaConcurrency
700+
}
701+
event["autoscaling.max_replica_concurrency"] = api.Autoscaling.MaxReplicaConcurrency
702+
event["autoscaling.window"] = api.Autoscaling.Window.Seconds()
703+
event["autoscaling.downscale_stabilization_period"] = api.Autoscaling.DownscaleStabilizationPeriod.Seconds()
704+
event["autoscaling.upscale_stabilization_period"] = api.Autoscaling.UpscaleStabilizationPeriod.Seconds()
705+
event["autoscaling.max_downscale_factor"] = api.Autoscaling.MaxDownscaleFactor
706+
event["autoscaling.max_upscale_factor"] = api.Autoscaling.MaxUpscaleFactor
707+
event["autoscaling.downscale_tolerance"] = api.Autoscaling.DownscaleTolerance
708+
event["autoscaling.upscale_tolerance"] = api.Autoscaling.UpscaleTolerance
709+
}
710+
711+
return event
712+
}

0 commit comments

Comments
 (0)