func startProcessMetrics()

in internal/processmetrics/processmetrics.go [161:267]


func startProcessMetrics(ctx context.Context, parameters Parameters) bool {
	cpm := parameters.Config.GetCollectionConfiguration().GetCollectProcessMetrics()
	cf := parameters.Config.GetCollectionConfiguration().GetProcessMetricsFrequency()
	slowPmf := parameters.Config.GetCollectionConfiguration().GetSlowProcessMetricsFrequency()

	log.CtxLogger(ctx).Infow("Configuration option for collect_process_metrics", "collectprocessmetrics", cpm)

	switch {
	case !cpm:
		log.CtxLogger(ctx).Info("Not collecting Process Metrics.")
		return false
	case parameters.OSType == "windows":
		log.CtxLogger(ctx).Info("Process Metrics collection is not supported for windows platform.")
		return false
	case cf < minimumFrequency:
		log.CtxLogger(ctx).Infow("Process metrics frequency is smaller than minimum supported value.", "frequency", cf, "minimumfrequency", minimumFrequency)
		log.CtxLogger(ctx).Info("Not collecting Process Metrics.")
		return false
	case slowPmf < minimumFrequencyForSlowMoving:
		log.CtxLogger(ctx).Infow("Slow process metrics frequency is smaller than minimum supported value.", "frequency", slowPmf, "minimumfrequency", minimumFrequencyForSlowMoving)
		log.CtxLogger(ctx).Info("Not collecting Process Metrics.")
		return false
	}

	ua := fmt.Sprintf("sap-core-eng/%s/%s.%s/processmetrics", configuration.AgentName, configuration.AgentVersion, configuration.AgentBuildChange)
	clientOptions := []option.ClientOption{option.WithUserAgent(ua)}
	mc, err := parameters.MetricClient(ctx, clientOptions...)
	if err != nil {
		log.CtxLogger(ctx).Errorw("Failed to create Cloud Monitoring client", "error", err)
		usagemetrics.Error(usagemetrics.ProcessMetricsMetricClientCreateFailure) // Failed to create Cloud Monitoring client
		return false
	}

	if fileInfo, err := parameters.OSStatReader(metricOverridePath); fileInfo != nil && err == nil {
		log.CtxLogger(ctx).Info("Using override metrics from yaml file ", metricOverridePath)
		p := createDemoCollectors(ctx, parameters, mc, metricoverrides.DemoMetricsReader)
		demoMetricsRoutine = &recovery.RecoverableRoutine{
			Routine: func(ctx context.Context, a any) {
				if pm, ok := a.(Parameters); ok {
					createWorkerPoolForSlowMetrics(ctx, p, pm.BackOffs)
				}
			},
			RoutineArg:          parameters,
			ErrorCode:           usagemetrics.SlowMetricsCollectionFailure,
			UsageLogger:         *usagemetrics.Logger,
			ExpectedMinDuration: time.Minute,
		}
		demoMetricsRoutine.StartRoutine(ctx)
		return true
	}

	sapInstances := instancesWithCredentials(ctx, &parameters)
	if len(sapInstances.GetInstances()) == 0 {
		log.CtxLogger(ctx).Error("No SAP Instances found. Cannot start process metrics collection.")
		usagemetrics.Error(usagemetrics.NoSAPInstancesFound) // NO SAP instances found
		return false
	}
	// Log usagemetric if hdbuserstore key is configured.
	if parameters.Config.GetCollectionConfiguration().GetHanaMetricsConfig().GetHdbuserstoreKey() != "" {
		usagemetrics.Action(usagemetrics.HDBUserstoreKeyConfigured)
	}

	log.CtxLogger(ctx).Info("Starting process metrics collection in background.")

	dailyMetricsRoutine = &recovery.RecoverableRoutine{
		Routine:             func(context.Context, any) { usagemetrics.LogActionDaily(usagemetrics.CollectProcessMetrics) },
		RoutineArg:          nil,
		ErrorCode:           usagemetrics.UsageMetricsDailyLogError,
		UsageLogger:         *usagemetrics.Logger,
		ExpectedMinDuration: 24 * time.Hour,
	}
	dailyMetricsRoutine.StartRoutine(ctx)

	p := createProcessCollectors(ctx, parameters, mc, sapInstances)
	collectAndSendFastMetricsRoutine = &recovery.RecoverableRoutine{
		Routine: func(ctx context.Context, a any) {
			if parameters, ok := a.(Parameters); ok {
				p.collectAndSendFastMovingMetrics(ctx, parameters.BackOffs)
			}
		},
		RoutineArg:          parameters,
		ErrorCode:           usagemetrics.CollectMetricsRoutineFailure,
		UsageLogger:         *usagemetrics.Logger,
		ExpectedMinDuration: time.Minute,
	}
	// NOMUTANTS--will be covered by integration testing
	collectAndSendFastMetricsRoutine.StartRoutine(ctx)

	// createWorkerPool creates a pool of workers to start collecting slow moving metrics in parallel
	// each collector has its own job of collecting and then sending the metrics to cloudmonitoring.
	// So after an error is encountered during metrics collection within a collector, while it retried
	// as per the retry policy, other collectors remain unaffected.
	slowMetricsRoutine = &recovery.RecoverableRoutine{
		Routine: func(ctx context.Context, a any) {
			if parameters, ok := a.(Parameters); ok {
				createWorkerPoolForSlowMetrics(ctx, p, parameters.BackOffs)
			}
		},
		RoutineArg:          parameters,
		ErrorCode:           usagemetrics.SlowMetricsCollectionFailure,
		UsageLogger:         *usagemetrics.Logger,
		ExpectedMinDuration: time.Minute,
	}
	slowMetricsRoutine.StartRoutine(ctx)

	return true
}