MCPcopy Index your code
hub / github.com/coder/coder / startPrometheusServer

Function startPrometheusServer

scripts/develop/main.go:1142–1275  ·  view source on GitHub ↗

startPrometheusServer runs the official Prometheus Docker image with a generated config that scrapes the local Coder metrics endpoint. It uses --net=host so the container can reach the host-bound metrics port directly. Only supported on Linux; returns false without error on other platforms. Returns

(ctx context.Context, logger slog.Logger, cfg *devConfig)

Source from the content-addressed store, hash-verified

1140// returns false without error on other platforms.
1141// Returns true if the server was started or is already running.
1142func startPrometheusServer(ctx context.Context, logger slog.Logger, cfg *devConfig) (bool, error) {
1143 if runtime.GOOS != "linux" {
1144 logger.Warn(ctx, "prometheus server is only supported on Linux, skipping",
1145 slog.F("os", runtime.GOOS))
1146 return false, nil
1147 }
1148
1149 // Verify Docker is available before attempting anything.
1150 if err := exec.CommandContext(ctx, "docker", "info").Run(); err != nil {
1151 logger.Warn(ctx, "docker not available, skipping prometheus server",
1152 slog.Error(err))
1153 return false, nil
1154 }
1155
1156 // If the port is already in use, check whether it's our
1157 // container from a previous run. If so, reuse it.
1158 if isPortBusy(ctx, prometheusServerPort) {
1159 out, err := exec.CommandContext(ctx, "docker", "inspect",
1160 "-f", "{{.State.Running}}",
1161 prometheusContainerName).Output()
1162 if err == nil && strings.TrimSpace(string(out)) == "true" {
1163 logger.Info(ctx, "reusing existing prometheus server",
1164 slog.F("ui", fmt.Sprintf("http://localhost:%d", prometheusServerPort)),
1165 slog.F("note", fmt.Sprintf("scrape target may differ from current --prometheus-port %d; restart to apply", cfg.coderMetricsPort)))
1166 return true, nil
1167 }
1168 logger.Info(ctx, "prometheus server port already in use, skipping",
1169 slog.F("port", prometheusServerPort))
1170 return false, nil
1171 }
1172
1173 // Remove any stopped leftover container from a previous run.
1174 // Failure is fine; it just means the container doesn't exist.
1175 rmCmd := exec.CommandContext(ctx, "docker", "rm", "-f", prometheusContainerName) //nolint:gosec
1176 rmCmd.Stdout = nil
1177 rmCmd.Stderr = nil
1178 _ = rmCmd.Run()
1179
1180 // Persist TSDB data across dev environment restarts. The
1181 // container runs as nobody (UID 65534), so the directory must
1182 // be world-writable. os.MkdirAll applies the umask, so we
1183 // chmod explicitly after creation.
1184 prometheusDataDir := filepath.Join(cfg.configDir, "prometheus")
1185 if err := os.MkdirAll(prometheusDataDir, 0o777); err != nil {
1186 return false, xerrors.Errorf("creating prometheus data directory: %w", err)
1187 }
1188 if err := os.Chmod(prometheusDataDir, 0o777); err != nil {
1189 return false, xerrors.Errorf("chmod prometheus data directory: %w", err)
1190 }
1191
1192 // Write a minimal scrape config to a temp file.
1193 promCfg := fmt.Sprintf(`global:
1194 scrape_interval: 15s
1195
1196scrape_configs:
1197 - job_name: coder
1198 scheme: http
1199 static_configs:

Callers 2

developFunction · 0.85

Calls 15

isPortBusyFunction · 0.85
MkdirAllMethod · 0.80
CommandMethod · 0.80
WriteStringMethod · 0.80
NamedMethod · 0.80
ErrMethod · 0.80
RunMethod · 0.65
CommandContextMethod · 0.65
OutputMethod · 0.65
RemoveMethod · 0.65
NameMethod · 0.65
CloseMethod · 0.65

Tested by 1