func()

in internal/pkg/agent/application/coordinator/coordinator.go [789:1049]


func (c *Coordinator) DiagnosticHooks() diagnostics.Hooks {
	hooks := diagnostics.Hooks{
		{
			Name:        "agent-info",
			Filename:    "agent-info.yaml",
			Description: "current state of the agent information of the running Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				meta, err := c.agentInfo.ECSMetadata(c.logger)
				if err != nil {
					c.logger.Errorw("Error getting ECS metadata", "error.message", err)
				}

				output := struct {
					Headers     map[string]string `yaml:"headers"`
					LogLevel    string            `yaml:"log_level"`
					RawLogLevel string            `yaml:"log_level_raw"`
					Metadata    *info.ECSMeta     `yaml:"metadata"`
				}{
					Headers:     c.agentInfo.Headers(),
					LogLevel:    c.agentInfo.LogLevel(),
					RawLogLevel: c.agentInfo.RawLogLevel(),
					Metadata:    meta,
				}
				o, err := yaml.Marshal(output)
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "local-config",
			Filename:    "local-config.yaml",
			Description: "current local configuration of the running Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				if c.cfg == nil {
					return []byte("error: failed no local configuration")
				}
				o, err := yaml.Marshal(c.cfg)
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "pre-config",
			Filename:    "pre-config.yaml",
			Description: "current pre-configuration of the running Elastic Agent before variable substitution",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				if c.ast == nil {
					return []byte("error: failed no configuration by the coordinator")
				}
				cfg, err := c.ast.Map()
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				o, err := yaml.Marshal(cfg)
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "variables",
			Filename:    "variables.yaml",
			Description: "current variable contexts of the running Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				if c.vars == nil {
					return []byte("error: failed no variables by the coordinator")
				}
				vars := make([]map[string]interface{}, 0, len(c.vars))
				for _, v := range c.vars {
					m, err := v.Map()
					if err != nil {
						return []byte(fmt.Sprintf("error: %q", err))
					}
					vars = append(vars, m)
				}
				o, err := yaml.Marshal(struct {
					Variables []map[string]interface{} `yaml:"variables"`
				}{
					Variables: vars,
				})
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "computed-config",
			Filename:    "computed-config.yaml",
			Description: "current computed configuration of the running Elastic Agent after variable substitution",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				cfg := c.derivedConfig
				o, err := yaml.Marshal(cfg)
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "components-expected",
			Filename:    "components-expected.yaml",
			Description: "current expected components model of the running Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				comps := c.componentModel
				o, err := yaml.Marshal(struct {
					Components []component.Component `yaml:"components"`
				}{
					Components: comps,
				})
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "components-actual",
			Filename:    "components-actual.yaml",
			Description: "actual components model of the running Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				components := c.State().Components

				componentConfigs := make([]component.Component, len(components))
				for i := 0; i < len(components); i++ {
					componentConfigs[i] = components[i].Component
				}
				o, err := yaml.Marshal(struct {
					Components []component.Component `yaml:"components"`
				}{
					Components: componentConfigs,
				})
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "state",
			Filename:    "state.yaml",
			Description: "current state of running components by the Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				type StateComponentOutput struct {
					ID    string                 `yaml:"id"`
					State runtime.ComponentState `yaml:"state"`
				}
				type StateCollectorStatus struct {
					Status     componentstatus.Status           `yaml:"status"`
					Err        string                           `yaml:"error,omitempty"`
					Timestamp  string                           `yaml:"timestamp"`
					Components map[string]*StateCollectorStatus `yaml:"components,omitempty"`
				}
				type StateHookOutput struct {
					State          agentclient.State      `yaml:"state"`
					Message        string                 `yaml:"message"`
					FleetState     agentclient.State      `yaml:"fleet_state"`
					FleetMessage   string                 `yaml:"fleet_message"`
					LogLevel       logp.Level             `yaml:"log_level"`
					Components     []StateComponentOutput `yaml:"components"`
					Collector      *StateCollectorStatus  `yaml:"collector,omitempty"`
					UpgradeDetails *details.Details       `yaml:"upgrade_details,omitempty"`
				}

				var toCollectorStatus func(status *status.AggregateStatus) *StateCollectorStatus
				toCollectorStatus = func(status *status.AggregateStatus) *StateCollectorStatus {
					s := &StateCollectorStatus{
						Status:    status.Status(),
						Timestamp: status.Timestamp().Format(time.RFC3339Nano),
					}
					statusErr := status.Err()
					if statusErr != nil {
						s.Err = statusErr.Error()
					}
					if len(status.ComponentStatusMap) > 0 {
						s.Components = make(map[string]*StateCollectorStatus, len(status.ComponentStatusMap))
						for k, v := range status.ComponentStatusMap {
							s.Components[k] = toCollectorStatus(v)
						}
					}
					return s
				}

				s := c.State()
				n := len(s.Components)
				compStates := make([]StateComponentOutput, n)
				for i := 0; i < n; i++ {
					compStates[i] = StateComponentOutput{
						ID:    s.Components[i].Component.ID,
						State: s.Components[i].State,
					}
				}
				var collectorStatus *StateCollectorStatus
				if s.Collector != nil {
					collectorStatus = toCollectorStatus(s.Collector)
				}
				output := StateHookOutput{
					State:          s.State,
					Message:        s.Message,
					FleetState:     s.FleetState,
					FleetMessage:   s.FleetMessage,
					LogLevel:       s.LogLevel,
					Components:     compStates,
					Collector:      collectorStatus,
					UpgradeDetails: s.UpgradeDetails,
				}
				o, err := yaml.Marshal(output)
				if err != nil {
					return []byte(fmt.Sprintf("error: %q", err))
				}
				return o
			},
		},
		{
			Name:        "otel",
			Filename:    "otel.yaml",
			Description: "current otel configuration used by the Elastic Agent",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				if c.otelCfg == nil {
					return []byte("no active OTel configuration")
				}
				o, err := yaml.Marshal(c.otelCfg.ToStringMap())
				if err != nil {
					return []byte(fmt.Sprintf("error: failed to convert to yaml: %v", err))
				}
				return o
			},
		},
		diagnostics.Hook{
			Name:        "otel-final",
			Filename:    "otel-final.yaml",
			Description: "Final otel configuration used by the Elastic Agent. Includes hybrid mode config and component config.",
			ContentType: "application/yaml",
			Hook: func(_ context.Context) []byte {
				if c.finalOtelCfg == nil {
					return []byte("no active OTel configuration")
				}
				o, err := yaml.Marshal(c.finalOtelCfg.ToStringMap())
				if err != nil {
					return []byte(fmt.Sprintf("error: failed to convert to yaml: %v", err))
				}
				return o
			},
		},
	}
	return hooks
}