Path: blob/main/install/installer/pkg/components/ide-metrics/configmap.go
2501 views
// Copyright (c) 2022 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 ide_metrics56import (7"fmt"8"strconv"910"github.com/gitpod-io/gitpod/ide-metrics-api/config"11"github.com/gitpod-io/gitpod/installer/pkg/common"12"github.com/prometheus/client_golang/prometheus"1314corev1 "k8s.io/api/core/v1"15metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"16"k8s.io/apimachinery/pkg/runtime"17)1819func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {20var statusCodes []string21for statusCode := 100; statusCode < 600; statusCode++ {22statusCodes = append(statusCodes, strconv.Itoa(statusCode))23}24statusCodes = append(statusCodes, "unknown")2526counterMetrics := []config.CounterMetricsConfiguration{27// we could also create a generator later similar to https://github.com/grpc/grpc-go/tree/master/cmd/protoc-gen-go-grpc if there is abuse28{29Name: "grpc_server_handled_total",30Help: "Total number of RPCs completed on the server, regardless of success or failure.",31Labels: []config.LabelAllowList{32{33Name: "grpc_method",34AllowValues: []string{"*"},35},36{37Name: "grpc_service",38AllowValues: []string{"*"},39},40{41Name: "grpc_type",42AllowValues: []string{"*"},43},44{45Name: "grpc_code",46AllowValues: []string{"*"},47},48},49},50{51Name: "grpc_server_msg_received_total",52Help: "Total number of RPC stream messages received on the server.",53Labels: []config.LabelAllowList{54{55Name: "grpc_method",56AllowValues: []string{"*"},57},58{59Name: "grpc_service",60AllowValues: []string{"*"},61},62{63Name: "grpc_type",64AllowValues: []string{"*"},65},66},67},68{69Name: "grpc_server_msg_sent_total",70Help: "Total number of gRPC stream messages sent by the server.",71Labels: []config.LabelAllowList{72{73Name: "grpc_method",74AllowValues: []string{"*"},75},76{77Name: "grpc_service",78AllowValues: []string{"*"},79},80{81Name: "grpc_type",82AllowValues: []string{"*"},83},84},85},86{87Name: "grpc_server_started_total",88Help: "Total number of RPCs started on the server.",89Labels: []config.LabelAllowList{90{91Name: "grpc_method",92AllowValues: []string{"*"},93},94{95Name: "grpc_service",96AllowValues: []string{"*"},97},98{99Name: "grpc_type",100AllowValues: []string{"*"},101},102},103},104{105Name: "gitpod_supervisor_frontend_error_total",106Help: "Total count of supervisor frontend client errors",107Labels: []config.LabelAllowList{108{109Name: "resource",110AllowValues: []string{111"vscode-web-workbench",112"unknown",113},114DefaultValue: "unknown",115},116{117Name: "error",118AllowValues: []string{119"LoadError", // js script style of errors120"Unknown",121},122DefaultValue: "Unknown",123},124},125},126{127Name: "gitpod_vscode_web_load_total",128Help: "Total count of attempts to load VS Code Web workbench",129Labels: []config.LabelAllowList{130{131Name: "status",132AllowValues: []string{"loading", "failed"},133},134},135},136{137Name: "gitpod_supervisor_frontend_client_total",138Help: "Total count of supervisor frontend client",139},140{141Name: "gitpod_vscode_extension_gallery_operation_total",142Help: "Total count of extension operations",143Labels: []config.LabelAllowList{144{145Name: "operation",146AllowValues: []string{"install", "update", "uninstall", "unknown"},147DefaultValue: "unknown",148},149{150Name: "status",151AllowValues: []string{"success", "failure", "unknown"},152DefaultValue: "unknown",153},154{155Name: "galleryHost",156AllowValues: []string{"*"},157},158// TODO(ak) errorCode - we should analyze error codes collect in analytics and categotize them here159},160},161{162Name: "gitpod_vscode_extension_gallery_query_total",163Help: "Total count of extension gallery queries",164Labels: []config.LabelAllowList{165{166Name: "status",167AllowValues: []string{"success", "failure", "unknown"},168DefaultValue: "unknown",169},170{171Name: "statusCode",172AllowValues: statusCodes,173DefaultValue: "unknown",174},175{176Name: "errorCode",177AllowValues: []string{"canceled", "timeout", "failed", "unknown"},178DefaultValue: "unknown",179},180{181Name: "galleryHost",182AllowValues: []string{"*"},183},184},185}, {186Name: "grpc_client_started_total",187Help: "Total number of RPCs started on the client.",188Labels: []config.LabelAllowList{189{190Name: "grpc_method",191AllowValues: []string{"*"},192},193{194Name: "grpc_service",195AllowValues: []string{"*"},196},197{198Name: "grpc_type",199AllowValues: []string{"*"},200},201},202Client: &config.ClientAllowList{203Name: "metric_client",204AllowValues: []string{"dashboard", "vscode-desktop-extension", "supervisor", "unknown"},205DefaultValue: "unknown",206},207}, {208Name: "grpc_client_handled_total",209Help: "Total number of RPCs completed by the client, regardless of success or failure.",210Labels: []config.LabelAllowList{211{212Name: "grpc_method",213AllowValues: []string{"*"},214},215{216Name: "grpc_service",217AllowValues: []string{"*"},218},219{220Name: "grpc_type",221AllowValues: []string{"*"},222},223{224Name: "grpc_code",225AllowValues: []string{"*"},226},227},228Client: &config.ClientAllowList{229Name: "metric_client",230AllowValues: []string{"dashboard", "vscode-desktop-extension", "supervisor", "unknown"},231DefaultValue: "unknown",232},233},234{235Name: "supervisor_client_handled_total",236Help: "Total number of supervisor outgoing services completed by the client, regardless of success or failure.",237Labels: []config.LabelAllowList{238{239Name: "method",240AllowValues: []string{"*"},241},242{243Name: "server",244AllowValues: []string{"*"},245},246{247Name: "err_code",248AllowValues: []string{"*"},249},250},251},252{253Name: "vscode_desktop_local_ssh_config_total",254Help: "Total number of vscode desktop extension config local ssh configuration",255Labels: []config.LabelAllowList{256{257Name: "status",258AllowValues: []string{"success", "failure"},259},260{261Name: "failure_code",262AllowValues: []string{"*"},263DefaultValue: "Unknown",264},265},266Client: &config.ClientAllowList{267Name: "metric_client",268AllowValues: []string{"vscode-desktop-extension"},269DefaultValue: "unknown",270},271},272{273Name: "vscode_desktop_ping_extension_server_total",274Help: "Total number of vscode desktop extension local ssh extension ipc server ping",275Labels: []config.LabelAllowList{276{277Name: "status",278AllowValues: []string{"success", "failure"},279},280},281Client: &config.ClientAllowList{282Name: "metric_client",283AllowValues: []string{"vscode-desktop-extension"},284DefaultValue: "unknown",285},286},287{288Name: "vscode_desktop_local_ssh_total",289Help: "Total number of vscode desktop local ssh proxy connection",290Labels: []config.LabelAllowList{291{292Name: "phase",293AllowValues: []string{"connecting", "connected", "failed"},294},295{296Name: "failure_code",297AllowValues: []string{"*"},298DefaultValue: "Unknown",299},300},301Client: &config.ClientAllowList{302Name: "metric_client",303AllowValues: []string{"vscode-desktop-extension"},304DefaultValue: "unknown",305},306},307{308Name: "websocket_client_total",309Help: "Total number of WebSocket connections by the client",310Labels: []config.LabelAllowList{311{312Name: "origin",313AllowValues: []string{"unknown", "workspace", "gitpod", "localhost"},314DefaultValue: "unknown",315},316{317Name: "instance_phase",318AllowValues: []string{"undefined", "unknown", "preparing", "building", "pending", "creating", "initializing", "running", "interrupted", "stopping", "stopped"},319DefaultValue: "undefined",320},321{322Name: "status",323AllowValues: []string{"unknown", "new", "open", "error", "close"},324DefaultValue: "unknown",325},326{327Name: "code",328AllowValues: []string{"*"},329DefaultValue: "unknown",330},331{332Name: "was_clean",333AllowValues: []string{"unknown", "0", "1"},334DefaultValue: "unknown",335},336},337},338{339Name: "supervisor_ssh_tunnel_opened_total",340Help: "Total number of SSH tunnels opened by the supervisor",341Labels: []config.LabelAllowList{},342},343{344Name: "supervisor_ssh_tunnel_closed_total",345Help: "Total number of SSH tunnels closed by the supervisor",346Labels: []config.LabelAllowList{347{348Name: "code",349AllowValues: []string{"*"},350DefaultValue: "unknown",351},352},353},354}355356histogramMetrics := []config.HistogramMetricsConfiguration{357{358Name: "gitpod_vscode_extension_gallery_operation_duration_seconds",359Help: "Duration of extension operations in seconds",360Labels: []config.LabelAllowList{361{362Name: "operation",363AllowValues: []string{"install", "update", "uninstall", "unknown"},364DefaultValue: "unknown",365},366{367Name: "galleryHost",368AllowValues: []string{"*"},369},370},371Buckets: []float64{0.1, 0.5, 1, 5, 10, 15, 30},372}, {373Name: "gitpod_vscode_extension_gallery_query_duration_seconds",374Help: "Duration of extension gallery query in seconds",375Labels: []config.LabelAllowList{376{377Name: "galleryHost",378AllowValues: []string{"*"},379},380},381Buckets: []float64{0.1, 0.5, 1, 5, 10, 15, 30},382},383}384385aggregatedHistogramMetrics := []config.HistogramMetricsConfiguration{386// we could also create a generator later similar to https://github.com/grpc/grpc-go/tree/master/cmd/protoc-gen-go-grpc if there is abuse387{388Name: "grpc_server_handling_seconds",389Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.",390Labels: []config.LabelAllowList{391{392Name: "grpc_method",393AllowValues: []string{"*"},394},395{396Name: "grpc_service",397AllowValues: []string{"*"},398},399{400Name: "grpc_type",401AllowValues: []string{"*"},402},403},404Buckets: []float64{.005, .025, .05, .1, .5, 1, 2.5, 5, 30, 60, 120, 240, 600},405},406{407Name: "supervisor_ide_ready_duration_total",408Help: "the IDE startup time",409Buckets: []float64{0.1, 0.5, 1, 1.5, 2, 2.5, 5, 10},410Labels: []config.LabelAllowList{411{412Name: "kind",413AllowValues: []string{"web", "desktop"},414},415},416},417{418Name: "supervisor_initializer_bytes_second",419Help: "initializer speed in bytes per second",420Buckets: prometheus.ExponentialBuckets(1024*1024, 2, 12),421Labels: []config.LabelAllowList{422{423Name: "kind",424AllowValues: []string{"*"},425},426},427}, {428Name: "grpc_client_handling_seconds",429Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.",430Labels: []config.LabelAllowList{431{432Name: "grpc_type",433AllowValues: []string{"*"},434},435{436Name: "grpc_service",437AllowValues: []string{"*"},438},439{440Name: "grpc_method",441AllowValues: []string{"*"},442},443},444Buckets: []float64{0.1, 0.2, 0.5, 1, 2, 5, 10},445Client: &config.ClientAllowList{446Name: "metric_client",447AllowValues: []string{"dashboard", "vscode-desktop-extension", "supervisor", "unknown"},448DefaultValue: "unknown",449},450}, {451Name: "supervisor_client_handling_seconds",452Help: "Histogram of response latency (seconds) of the supervisor outgoing services until it is finished by the application.",453Labels: []config.LabelAllowList{454{455Name: "method",456AllowValues: []string{"*"},457},458{459Name: "server",460AllowValues: []string{"*"},461},462{463Name: "err_code",464AllowValues: []string{"*"},465},466},467Buckets: []float64{0.1, 0.2, 0.5, 1, 2, 5, 10},468},469}470471errorReporting := config.ErrorReportingConfiguration{472AllowComponents: []string{473"supervisor-frontend",474// "vscode-workbench",475// "vscode-server",476// "vscode-web",477"gitpod-cli",478"gitpod-web",479"gitpod-remote-ssh",480"vscode-desktop-extension",481"dashboard",482},483}484485cfg := config.ServiceConfiguration{486Server: config.MetricsServerConfiguration{487Port: ContainerPort,488// RateLimits: , // TODO(pd) ratelimit489CounterMetrics: counterMetrics,490HistogramMetrics: histogramMetrics,491AggregatedHistogramMetrics: aggregatedHistogramMetrics,492ErrorReporting: errorReporting,493},494Prometheus: struct {495Addr string `json:"addr"`496}{Addr: common.LocalhostPrometheusAddr()},497}498499fc, err := common.ToJSONString(cfg)500if err != nil {501return nil, fmt.Errorf("failed to marshal ide-metrics config: %w", err)502}503504res := []runtime.Object{505&corev1.ConfigMap{506TypeMeta: common.TypeMetaConfigmap,507ObjectMeta: metav1.ObjectMeta{508Name: Component,509Namespace: ctx.Namespace,510Labels: common.CustomizeLabel(ctx, Component, common.TypeMetaConfigmap),511Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaConfigmap),512},513Data: map[string]string{514"config.json": string(fc),515},516},517}518return res, nil519}520521522