cashless2ecash

cashless2ecash: pay with cards for digital cash (experimental)
Log | Files | Refs | README

commit c5dff4ec42a205df278836e485f6c6878323009d
parent 70277d3870b20d788ea08cb62b0b88c3cb28b1cb
Author: Joel-Haeberli <haebu@rubigen.ch>
Date:   Wed, 29 May 2024 13:55:37 +0200

logging: add status code to logs

Diffstat:
Mc2ec/api-bank-integration.go | 17+++++++++++++++++
Mc2ec/api-terminals.go | 25+++++++++++++++++++++++++
Mc2ec/api-wire-gateway.go | 26++++++++++++++++++++++++++
Mc2ec/http-util.go | 2++
Mc2ec/logger.go | 8+++++++-
5 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/c2ec/api-bank-integration.go b/c2ec/api-bank-integration.go @@ -78,11 +78,13 @@ func bankIntegrationConfig(res http.ResponseWriter, req *http.Request) { serializedCfg, err := encoder.EncodeToBytes(&cfg) if err != nil { LogInfo("bank-integration-api", fmt.Sprintf("failed serializing config: %s", err.Error())) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } res.Header().Add(CONTENT_TYPE_HEADER, encoder.HttpApplicationContentHeader()) + setLastResponseCodeForLogger(HTTP_OK) res.WriteHeader(HTTP_OK) res.Write(serializedCfg) } @@ -93,6 +95,7 @@ func handleParameterRegistration(res http.ResponseWriter, req *http.Request) { registration, err := ReadStructFromBody(req, jsonCodec) if err != nil { LogWarn("bank-integration-api", fmt.Sprintf("invalid body for withdrawal registration error=%s", err.Error())) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -102,12 +105,14 @@ func handleParameterRegistration(res http.ResponseWriter, req *http.Request) { wpd, err := ParseWopid(wopid) if err != nil { LogWarn("bank-integration-api", "wopid "+wopid+" not valid") + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } if _, err = DB.GetWithdrawalByWopid(wpd); err != nil { LogError("bank-integration-api", err) + setLastResponseCodeForLogger(HTTP_NOT_FOUND) res.WriteHeader(HTTP_NOT_FOUND) return } @@ -117,6 +122,7 @@ func handleParameterRegistration(res http.ResponseWriter, req *http.Request) { registration.ReservePubKey, ); err != nil { LogError("bank-integration-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -124,6 +130,7 @@ func handleParameterRegistration(res http.ResponseWriter, req *http.Request) { withdrawal, err := DB.GetWithdrawalByWopid(wpd) if err != nil { LogError("bank-integration-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) } @@ -137,6 +144,7 @@ func handleParameterRegistration(res http.ResponseWriter, req *http.Request) { resbyts, err := encoder.EncodeToBytes(resbody) if err != nil { LogError("bank-integration-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) } @@ -184,6 +192,7 @@ func handleWithdrawalStatus(res http.ResponseWriter, req *http.Request) { wpd, err := ParseWopid(wopid) if err != nil { LogWarn("bank-integration-api", "wopid "+wopid+" not valid") + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -251,11 +260,13 @@ func handleWithdrawalStatus(res http.ResponseWriter, req *http.Request) { select { case <-timeoutCtx.Done(): LogInfo("bank-integration-api", "long poll time exceeded") + setLastResponseCodeForLogger(HTTP_NO_CONTENT) res.WriteHeader(HTTP_NO_CONTENT) return case <-notifications: wthdrl, stat := getWithdrawalOrError(wpd) if stat != 200 { + setLastResponseCodeForLogger(stat) res.WriteHeader(stat) } else { res.Header().Add(CONTENT_TYPE_HEADER, "application/json") @@ -267,6 +278,7 @@ func handleWithdrawalStatus(res http.ResponseWriter, req *http.Request) { res.Write(wthdrl) return case status := <-errStat: + setLastResponseCodeForLogger(status) res.WriteHeader(status) return } @@ -280,6 +292,7 @@ func handleWithdrawalAbort(res http.ResponseWriter, req *http.Request) { wpd, err := ParseWopid(wopid) if err != nil { LogWarn("bank-integration-api", "wopid "+wopid+" not valid") + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -287,11 +300,13 @@ func handleWithdrawalAbort(res http.ResponseWriter, req *http.Request) { withdrawal, err := DB.GetWithdrawalByWopid(wpd) if err != nil { LogError("bank-integration-api", err) + setLastResponseCodeForLogger(HTTP_NOT_FOUND) res.WriteHeader(HTTP_NOT_FOUND) return } if withdrawal.WithdrawalStatus == CONFIRMED { + setLastResponseCodeForLogger(HTTP_CONFLICT) res.WriteHeader(HTTP_CONFLICT) return } @@ -299,10 +314,12 @@ func handleWithdrawalAbort(res http.ResponseWriter, req *http.Request) { err = DB.FinaliseWithdrawal(int(withdrawal.WithdrawalRowId), ABORTED, make([]byte, 0)) if err != nil { LogError("bank-integration-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } + setLastResponseCodeForLogger(HTTP_NO_CONTENT) res.WriteHeader(HTTP_NO_CONTENT) } diff --git a/c2ec/api-terminals.go b/c2ec/api-terminals.go @@ -45,12 +45,14 @@ func handleTerminalConfig(res http.ResponseWriter, req *http.Request) { p, auth, err := authAndParseProvider(req) if !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } if err != nil || p == nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -65,11 +67,13 @@ func handleTerminalConfig(res http.ResponseWriter, req *http.Request) { }) if err != nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } res.Header().Add(CONTENT_TYPE_HEADER, encoder.HttpApplicationContentHeader()) + setLastResponseCodeForLogger(HTTP_OK) res.WriteHeader(HTTP_OK) res.Write(cfg) } @@ -78,11 +82,13 @@ func handleWithdrawalSetup(res http.ResponseWriter, req *http.Request) { p, auth, err := authAndParseProvider(req) if !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } if err != nil || p == nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -91,11 +97,13 @@ func handleWithdrawalSetup(res http.ResponseWriter, req *http.Request) { setup, err := ReadStructFromBody(req, jsonCodec) if err != nil { LogWarn("terminals-api", fmt.Sprintf("invalid body for withdrawal registration error=%s", err.Error())) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } if hasConflict(setup) { + setLastResponseCodeForLogger(HTTP_CONFLICT) res.WriteHeader(HTTP_CONFLICT) return } @@ -103,6 +111,7 @@ func handleWithdrawalSetup(res http.ResponseWriter, req *http.Request) { terminalId := parseTerminalId(req) if terminalId == -1 { LogWarn("terminals-api", "terminal id could not be read from authorization header") + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -113,21 +122,25 @@ func handleWithdrawalSetup(res http.ResponseWriter, req *http.Request) { if err != nil { LogWarn("terminals-api", "unable to generate correct wopid") LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) } suggstdAmnt, err := parseAmount(setup.SuggestedAmount) if err != nil { + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } amnt, err := parseAmount(setup.Amount) if err != nil { + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } fees, err := parseAmount(setup.TerminalFees) if err != nil { + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -144,6 +157,7 @@ func handleWithdrawalSetup(res http.ResponseWriter, req *http.Request) { if err != nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -156,6 +170,7 @@ func handleWithdrawalSetup(res http.ResponseWriter, req *http.Request) { ) if err != nil { LogError("terminal-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -168,12 +183,14 @@ func handleWithdrawalCheck(res http.ResponseWriter, req *http.Request) { p, auth, err := authAndParseProvider(req) if !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } if err != nil || p == nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -183,6 +200,7 @@ func handleWithdrawalCheck(res http.ResponseWriter, req *http.Request) { if err != nil { LogWarn("terminals-api", "wopid "+wopid+" not valid") if wopid == "" { + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -192,6 +210,7 @@ func handleWithdrawalCheck(res http.ResponseWriter, req *http.Request) { paymentNotification, err := ReadStructFromBody(req, jsonCodec) if err != nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -201,6 +220,7 @@ func handleWithdrawalCheck(res http.ResponseWriter, req *http.Request) { terminalId := parseTerminalId(req) if terminalId == -1 { LogWarn("terminals-api", "terminal id could not be read from authorization header") + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -208,6 +228,7 @@ func handleWithdrawalCheck(res http.ResponseWriter, req *http.Request) { trmlFees, err := ParseAmount(paymentNotification.TerminalFees) if err != nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -221,10 +242,12 @@ func handleWithdrawalCheck(res http.ResponseWriter, req *http.Request) { ) if err != nil { LogError("terminals-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } + setLastResponseCodeForLogger(HTTP_NO_CONTENT) res.WriteHeader(HTTP_NO_CONTENT) } @@ -232,6 +255,7 @@ func handleWithdrawalStatusTerminal(res http.ResponseWriter, req *http.Request) _, auth, err := authAndParseProvider(req) if err != nil || !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } @@ -243,6 +267,7 @@ func handleWithdrawalAbortTerminal(res http.ResponseWriter, req *http.Request) { _, auth, err := authAndParseProvider(req) if err != nil || !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } diff --git a/c2ec/api-wire-gateway.go b/c2ec/api-wire-gateway.go @@ -138,10 +138,12 @@ func wireGatewayConfig(res http.ResponseWriter, req *http.Request) { serializedCfg, err := NewJsonCodec[WireConfig]().EncodeToBytes(&cfg) if err != nil { log.Default().Printf("failed serializing config: %s", err.Error()) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } + setLastResponseCodeForLogger(HTTP_OK) res.WriteHeader(HTTP_OK) res.Write(serializedCfg) } @@ -150,6 +152,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { auth := AuthenticateWirewatcher(req) if !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } @@ -158,12 +161,14 @@ func transfer(res http.ResponseWriter, req *http.Request) { transfer, err := ReadStructFromBody(req, jsonCodec) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } if transfer.Amount == "" || transfer.CreditAccount == "" || transfer.RequestUid == "" { LogError("wire-gateway-api", errors.New("invalid request")) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -171,6 +176,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { paytoTargetType, tid, err := ParsePaytoWalleeTransaction(transfer.CreditAccount) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -178,6 +184,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { p, err := DB.GetTerminalProviderByPaytoTargetType(paytoTargetType) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -185,6 +192,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { decodedRequestUid, err := talerBinaryDecode(string(transfer.RequestUid)) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return } @@ -192,6 +200,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { t, err := DB.GetTransferById(decodedRequestUid) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -201,6 +210,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { amount, err := ParseAmount(transfer.Amount) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -213,6 +223,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { ) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -221,6 +232,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { ta, err := ToAmount(t.Amount) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -230,6 +242,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { transfer.CreditAccount != t.CreditAccount { LogWarn("wire-gateway-api", "idempotency violation") + setLastResponseCodeForLogger(HTTP_CONFLICT) res.WriteHeader(HTTP_CONFLICT) return } @@ -237,6 +250,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { w, err := DB.GetWithdrawalByProviderTransactionId(tid) if err != nil || w == nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -244,6 +258,7 @@ func transfer(res http.ResponseWriter, req *http.Request) { refundClient := PROVIDER_CLIENTS[p.Name] if refundClient == nil { LogError("wire-gateway-api", errors.New("client for provider "+p.Name+" not initialized")) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -270,6 +285,7 @@ func historyIncoming(res http.ResponseWriter, req *http.Request) { auth := AuthenticateWirewatcher(req) if !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } @@ -322,11 +338,13 @@ func historyIncoming(res http.ResponseWriter, req *http.Request) { if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } if len(withdrawals) < 1 { + setLastResponseCodeForLogger(HTTP_NO_CONTENT) res.WriteHeader(HTTP_NO_CONTENT) return } @@ -348,11 +366,13 @@ func historyIncoming(res http.ResponseWriter, req *http.Request) { enc, err := encoder.EncodeToBytes(&hist) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } res.Header().Add(CONTENT_TYPE_HEADER, encoder.HttpApplicationContentHeader()) + setLastResponseCodeForLogger(HTTP_OK) res.WriteHeader(HTTP_OK) res.Write(enc) } @@ -361,6 +381,7 @@ func historyOutgoing(res http.ResponseWriter, req *http.Request) { auth := AuthenticateWirewatcher(req) if !auth { + setLastResponseCodeForLogger(HTTP_UNAUTHORIZED) res.WriteHeader(HTTP_UNAUTHORIZED) return } @@ -416,6 +437,7 @@ func historyOutgoing(res http.ResponseWriter, req *http.Request) { if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } @@ -429,6 +451,7 @@ func historyOutgoing(res http.ResponseWriter, req *http.Request) { } if len(filtered) < 1 { + setLastResponseCodeForLogger(HTTP_NO_CONTENT) res.WriteHeader(HTTP_NO_CONTENT) return } @@ -446,11 +469,13 @@ func historyOutgoing(res http.ResponseWriter, req *http.Request) { enc, err := encoder.EncodeToBytes(&outgoingHistory) if err != nil { LogError("wire-gateway-api", err) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return } res.Header().Add(CONTENT_TYPE_HEADER, encoder.HttpApplicationContentHeader()) + setLastResponseCodeForLogger(HTTP_OK) res.WriteHeader(HTTP_OK) res.Write(enc) } @@ -459,5 +484,6 @@ func historyOutgoing(res http.ResponseWriter, req *http.Request) { func adminAddIncoming(res http.ResponseWriter, req *http.Request) { // not implemented, because not used + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) } diff --git a/c2ec/http-util.go b/c2ec/http-util.go @@ -39,6 +39,7 @@ func AcceptOptionalParamOrWriteResponse[T any]( ptr, err := OptionalQueryParamOrError(name, transform, req) if err != nil { + setLastResponseCodeForLogger(HTTP_BAD_REQUEST) res.WriteHeader(HTTP_BAD_REQUEST) return nil, false } @@ -52,6 +53,7 @@ func AcceptOptionalParamOrWriteResponse[T any]( assertedObj, ok := any(obj).(T) if !ok { // this should generally not happen (due to the implementation) + setLastResponseCodeForLogger(HTTP_INTERNAL_SERVER_ERROR) res.WriteHeader(HTTP_INTERNAL_SERVER_ERROR) return nil, false } diff --git a/c2ec/logger.go b/c2ec/logger.go @@ -21,6 +21,8 @@ const ( ERROR ) +var lastResponseStatus = 0 + func LoggingHandler(next http.Handler) http.Handler { return http.HandlerFunc( @@ -35,6 +37,10 @@ func LoggingHandler(next http.Handler) http.Handler { ) } +func setLastResponseCodeForLogger(s int) { + lastResponseStatus = s +} + func LogRequest(src string, req *http.Request) { LogInfo(src, fmt.Sprintf("%s - %s (origin=%s)", req.Method, req.URL, req.RemoteAddr)) @@ -42,7 +48,7 @@ func LogRequest(src string, req *http.Request) { func LogResponse(src string, req *http.Request) { - LogInfo(src, fmt.Sprintf("responding to %s (destination=%s)", req.RequestURI, req.RemoteAddr)) + LogInfo(src, fmt.Sprintf("code=%d: responding to %s (destination=%s)", lastResponseStatus, req.RequestURI, req.RemoteAddr)) } func LogError(src string, err error) {