func()

in internal/pkg/api/handleStatus.go [80:146]


func (st StatusT) handleStatus(zlog zerolog.Logger, r *http.Request, w http.ResponseWriter) error {
	authed := true
	if _, aerr := st.authfn(r); aerr != nil {
		zlog.Debug().Err(aerr).Msg("unauthenticated status request, return short status response only")
		authed = false
	}

	span, ctx := apm.StartSpan(r.Context(), "getState", "process")
	state := st.sm.State()
	resp := StatusAPIResponse{
		Name:   build.ServiceName,
		Status: StatusResponseStatus(state.String()), // TODO try to make the oapi codegen less verbose here
	}

	if authed {
		sSpan, _ := apm.StartSpan(ctx, "getVersion", "process")
		bt := st.bi.BuildTime.Format(time.RFC3339)
		resp.Version = &StatusResponseVersion{
			Number:    &st.bi.Version,
			BuildHash: &st.bi.Commit,
			BuildTime: &bt,
		}
		sSpan.End()
	}
	span.End()

	span, _ = apm.StartSpan(r.Context(), "response", "write")
	defer span.End()

	// If the request context has been cancelled, such as the case when the server is stopping we should return a 503
	// Note that the API server uses Shutdown, so no new requests should be accepted and this edge case will be rare.
	if errors.Is(r.Context().Err(), context.Canceled) {
		state = client.UnitStateStopping
	}

	data, err := json.Marshal(&resp)
	if err != nil {
		return err
	}

	code := http.StatusServiceUnavailable
	if state == client.UnitStateHealthy {
		code = http.StatusOK
	}
	w.WriteHeader(code)

	ts, ok := logger.CtxStartTime(r.Context())
	nWritten, err := w.Write(data)
	if err != nil {
		if !errors.Is(err, context.Canceled) {
			e := zlog.Error().Err(err).Int(ECSHTTPResponseCode, code)
			if ok {
				e = e.Int64(ECSEventDuration, time.Since(ts).Nanoseconds())
			}
			e.Msg("fail status")
		}
	}

	cntStatus.bodyOut.Add(uint64(nWritten)) //nolint:gosec // disable G115
	e := zlog.Debug().Int(ECSHTTPResponseBodyBytes, nWritten)
	if ok {
		e = e.Int64(ECSEventDuration, time.Since(ts).Nanoseconds())
	}
	e.Msg("ok status")

	return nil
}