~xenrox/ntfy-alertmanager

6d64c21549055c18a1789b551f940db2603a0b22 — Thorben Günther 8 months ago dab77f6
Use Logger.With to create child loggers for the handlers

With that it will be easier to check on which endpoint a failure
happened.
2 files changed, 25 insertions(+), 20 deletions(-)

M main.go
M silence.go
M main.go => main.go +12 -9
@@ 352,27 352,29 @@ func (br *bridge) publish(n *notification) error {
func (br *bridge) handleWebhooks(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	logger := br.logger.With(slog.String("handler", "/"))

	if r.Method != http.MethodPost {
		http.Error(w, "Only POST allowed", http.StatusMethodNotAllowed)
		br.logger.Debug(fmt.Sprintf("Illegal HTTP method: expected %q, got %q", "POST", r.Method))
		logger.Debug(fmt.Sprintf("Illegal HTTP method: expected %q, got %q", "POST", r.Method))
		return
	}

	contentType := r.Header.Get("Content-Type")
	if contentType != "application/json" {
		http.Error(w, "Only application/json allowed", http.StatusUnsupportedMediaType)
		br.logger.Debug(fmt.Sprintf("Illegal content type: %s", contentType))
		logger.Debug(fmt.Sprintf("Illegal content type: %s", contentType))
		return
	}

	var event payload
	if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
		br.logger.Debug("Failed to decode payload",
		logger.Debug("Failed to decode payload",
			slog.String("error", err.Error()))
		return
	}

	br.logger.Debug("Received alert",
	logger.Debug("Received alert",
		slog.Any("payload", event))

	if br.cfg.AlertMode == config.Single {


@@ 380,11 382,11 @@ func (br *bridge) handleWebhooks(w http.ResponseWriter, r *http.Request) {
		for _, n := range notifications {
			err := br.publish(n)
			if err != nil {
				br.logger.Error("Failed to publish notification",
				logger.Error("Failed to publish notification",
					slog.String("error", err.Error()))
			} else {
				if err := br.cache.Set(n.fingerprint, n.status); err != nil {
					br.logger.Error("Failed to cache alert",
					logger.Error("Failed to cache alert",
						slog.String("fingerprint", n.fingerprint),
						slog.String("error", err.Error()))
				}


@@ 394,7 396,7 @@ func (br *bridge) handleWebhooks(w http.ResponseWriter, r *http.Request) {
		notification := br.multiAlertNotification(&event)
		err := br.publish(notification)
		if err != nil {
			br.logger.Error("Failed to publish notification",
			logger.Error("Failed to publish notification",
				slog.String("error", err.Error()))
		}
	}


@@ 402,9 404,10 @@ func (br *bridge) handleWebhooks(w http.ResponseWriter, r *http.Request) {

func (br *bridge) authMiddleware(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logger := br.logger.With(slog.String("url", r.URL.String()))
		user, pass, ok := r.BasicAuth()
		if !ok {
			br.logger.Debug("basic auth failure")
			logger.Debug("basic auth failure")
			return
		}



@@ 418,7 421,7 @@ func (br *bridge) authMiddleware(handler http.Handler) http.Handler {

		if validUser != 1 || validPass != 1 {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			br.logger.Debug("basic auth: wrong user or password")
			logger.Debug("basic auth: wrong user or password")
			return
		}


M silence.go => silence.go +13 -11
@@ 40,22 40,24 @@ type silenceResponse struct {
func (br *bridge) handleSilences(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	logger := br.logger.With(slog.String("handler", "/silences"))

	if r.Method != http.MethodPost {
		http.Error(w, "Only POST allowed", http.StatusMethodNotAllowed)
		br.logger.Debug(fmt.Sprintf("Silences: Illegal HTTP method: expected %q, got %q", "POST", r.Method))
		logger.Debug(fmt.Sprintf("Illegal HTTP method: expected %q, got %q", "POST", r.Method))
		return
	}

	b, err := io.ReadAll(r.Body)
	if err != nil {
		br.logger.Error("Silences: Failed to read body",
		logger.Error("Failed to read body",
			slog.String("error", err.Error()))
		return
	}

	b, err = base64.StdEncoding.DecodeString(string(b))
	if err != nil {
		br.logger.Error("Silences: Failed to decode",
		logger.Error("Failed to decode",
			slog.String("error", err.Error()))
		return
	}


@@ 63,7 65,7 @@ func (br *bridge) handleSilences(w http.ResponseWriter, r *http.Request) {
	var sb silenceBody
	err = json.Unmarshal(b, &sb)
	if err != nil {
		br.logger.Error("Silences: Failed to unmarshal",
		logger.Error("Failed to unmarshal",
			slog.String("error", err.Error()))
		return
	}


@@ 90,7 92,7 @@ func (br *bridge) handleSilences(w http.ResponseWriter, r *http.Request) {

	b, err = json.Marshal(silence)
	if err != nil {
		br.logger.Error("Silences: Failed to marshal",
		logger.Error("Failed to marshal",
			slog.String("error", err.Error()))
		return
	}


@@ 103,7 105,7 @@ func (br *bridge) handleSilences(w http.ResponseWriter, r *http.Request) {

	req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(b))
	if err != nil {
		br.logger.Error("Silences: Failed to create request",
		logger.Error("Failed to create request",
			slog.String("error", err.Error()))
		return
	}


@@ 116,7 118,7 @@ func (br *bridge) handleSilences(w http.ResponseWriter, r *http.Request) {
	req.Header.Add("Content-Type", "application/json")
	resp, err := br.client.Do(req)
	if err != nil {
		br.logger.Error("Silences: Failed to POST request",
		logger.Error("Failed to POST request",
			slog.String("error", err.Error()))
		return
	}


@@ 124,24 126,24 @@ func (br *bridge) handleSilences(w http.ResponseWriter, r *http.Request) {

	b, err = io.ReadAll(resp.Body)
	if err != nil {
		br.logger.Error("Silences: Failed to read response body",
		logger.Error("Failed to read response body",
			slog.String("error", err.Error()))
		return
	}

	if resp.StatusCode != http.StatusOK {
		br.logger.Error("Silences: Received non-200 status code",
		logger.Error("Received non-200 status code",
			slog.Int("status", resp.StatusCode))
		return
	}

	var id silenceResponse
	if err := json.Unmarshal(b, &id); err != nil {
		br.logger.Error("Silences: Failed to unmarshal response",
		logger.Error("Failed to unmarshal response",
			slog.String("error", err.Error()))
		return
	}

	br.logger.Info("Silences: Created new silence",
	logger.Info("Created new silence",
		slog.String("ID", id.ID))
}