func()

in confgenerator/otel/modular.go [133:240]


func (c ModularConfig) Generate(ctx context.Context) (string, error) {
	pl := platform.FromContext(ctx)
	receivers := map[string]interface{}{}
	processors := map[string]interface{}{}
	exporters := map[string]interface{}{}
	exporterNames := map[ExporterType]string{}
	pipelines := map[string]interface{}{}
	service := map[string]map[string]interface{}{
		"pipelines": pipelines,
		"telemetry": map[string]interface{}{
			"metrics": map[string]interface{}{
				// TODO: switch to metrics.readers so we can stop binding a port
				"address": fmt.Sprintf("0.0.0.0:%d", MetricsPort),
			},
		},
	}
	if c.DisableMetrics {
		service["telemetry"]["metrics"] = map[string]interface{}{
			"level": "none",
		}
	}
	logs := map[string]any{}
	if c.LogLevel != "info" {
		logs["level"] = "debug"
	}
	if c.JSONLogs {
		logs["encoding"] = "json"
	}
	if len(logs) > 0 {
		service["telemetry"]["logs"] = logs
	}

	configMap := map[string]interface{}{
		"receivers":  receivers,
		"processors": processors,
		"exporters":  exporters,
		"service":    service,
	}

	resourceDetectionProcessors := map[ResourceDetectionMode]Component{
		Override:     GCPResourceDetector(true),
		SetIfMissing: GCPResourceDetector(false),
	}

	if pl.ResourceOverride != nil {
		resourceDetectionProcessors = map[ResourceDetectionMode]Component{
			Override:     ResourceTransform(pl.ResourceOverride.OTelResourceAttributes(), true),
			SetIfMissing: ResourceTransform(pl.ResourceOverride.OTelResourceAttributes(), false),
		}
	}
	resourceDetectionProcessorNames := map[ResourceDetectionMode]string{
		Override:     resourceDetectionProcessors[Override].name("_global_0"),
		SetIfMissing: resourceDetectionProcessors[SetIfMissing].name("_global_1"),
	}

	for prefix, pipeline := range c.Pipelines {
		// Receiver pipelines need to be instantiated once, since they might have more than one type.
		// We do this work more than once if it's in more than one pipeline, but it should just overwrite the same names.
		receiverPipeline := c.ReceiverPipelines[pipeline.ReceiverPipelineName]
		receiverName := receiverPipeline.Receiver.name(pipeline.ReceiverPipelineName)
		var receiverProcessorNames []string
		p, ok := receiverPipeline.Processors[pipeline.Type]
		if !ok {
			// This receiver pipeline isn't for this data type.
			continue
		}
		for i, processor := range p {
			name := processor.name(fmt.Sprintf("%s_%d", pipeline.ReceiverPipelineName, i))
			receiverProcessorNames = append(receiverProcessorNames, name)
			processors[name] = processor.Config
		}
		receivers[receiverName] = receiverPipeline.Receiver.Config

		// Everything else in the pipeline is specific to this Type.
		var processorNames []string
		processorNames = append(processorNames, receiverProcessorNames...)
		for i, processor := range pipeline.Processors {
			name := processor.name(fmt.Sprintf("%s_%d", prefix, i))
			processorNames = append(processorNames, name)
			processors[name] = processor.Config
		}
		rdm := receiverPipeline.ResourceDetectionModes[pipeline.Type]
		if name, ok := resourceDetectionProcessorNames[rdm]; ok {
			processorNames = append(processorNames, name)
			processors[name] = resourceDetectionProcessors[rdm].Config
		}
		exporterType := receiverPipeline.ExporterTypes[pipeline.Type]
		if _, ok := exporterNames[exporterType]; !ok {
			exporter := c.Exporters[exporterType]
			name := exporter.name(exporterType.Name())
			exporterNames[exporterType] = name
			exporters[name] = exporter.Config
		}

		pipelines[pipeline.Type+"/"+prefix] = map[string]interface{}{
			"receivers":  []string{receiverName},
			"processors": processorNames,
			"exporters":  []string{exporterNames[exporterType]},
		}
	}

	out, err := configToYaml(configMap)
	// TODO: Return []byte
	if err != nil {
		return "", err
	}
	return string(out), nil
}