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
}