cashless2ecash

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

logger.go (2793B)


      1 // This file is part of taler-cashless2ecash.
      2 // Copyright (C) 2024 Joel Häberli
      3 //
      4 // taler-cashless2ecash is free software: you can redistribute it and/or modify it
      5 // under the terms of the GNU Affero General Public License as published
      6 // by the Free Software Foundation, either version 3 of the License,
      7 // or (at your option) any later version.
      8 //
      9 // taler-cashless2ecash is distributed in the hope that it will be useful, but
     10 // WITHOUT ANY WARRANTY; without even the implied warranty of
     11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 // Affero General Public License for more details.
     13 //
     14 // You should have received a copy of the GNU Affero General Public License
     15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 //
     17 // SPDX-License-Identifier: AGPL3.0-or-later
     18 
     19 package internal_utils
     20 
     21 import (
     22 	"fmt"
     23 	"net/http"
     24 	"os"
     25 	"time"
     26 )
     27 
     28 const LOG_PATH = "c2ec-log.txt"
     29 
     30 // LEVEL | TIME | SRC | MESSAGE
     31 const LOG_PATTERN = "level=%d | time=%s | src=%s | %s"
     32 const TIME_FORMAT = "yyyy-MM-dd hh:mm:ss"
     33 
     34 type LogLevel int
     35 
     36 const (
     37 	INFO LogLevel = iota
     38 	WARN
     39 	ERROR
     40 )
     41 
     42 var lastResponseStatus = 0
     43 
     44 func LoggingHandler(next http.Handler) http.Handler {
     45 
     46 	return http.HandlerFunc(
     47 		func(w http.ResponseWriter, r *http.Request) {
     48 
     49 			LogRequest("http-logger", r)
     50 
     51 			next.ServeHTTP(w, r)
     52 
     53 			LogResponse("http-logger", r)
     54 		},
     55 	)
     56 }
     57 
     58 func SetLastResponseCodeForLogger(s int) {
     59 	lastResponseStatus = s
     60 }
     61 
     62 func LogRequest(src string, req *http.Request) {
     63 
     64 	LogInfo(src, fmt.Sprintf("%s - %s (origin=%s)", req.Method, req.URL, req.RemoteAddr))
     65 }
     66 
     67 func LogResponse(src string, req *http.Request) {
     68 
     69 	LogInfo(src, fmt.Sprintf("code=%d: responding to %s (destination=%s)", lastResponseStatus, req.RequestURI, req.RemoteAddr))
     70 }
     71 
     72 func LogError(src string, err error) {
     73 
     74 	go logAppendError(src, ERROR, err)
     75 }
     76 
     77 func LogWarn(src string, msg string) {
     78 
     79 	go logAppend(src, WARN, msg)
     80 }
     81 
     82 func LogInfo(src string, msg string) {
     83 
     84 	go logAppend(src, INFO, msg)
     85 }
     86 
     87 func logAppendError(src string, level LogLevel, err error) {
     88 
     89 	if err == nil {
     90 		fmt.Println("wanted to log from " + src + " but err was nil")
     91 		return
     92 	}
     93 	logAppend(src, level, err.Error())
     94 }
     95 
     96 func logAppend(src string, level LogLevel, msg string) {
     97 
     98 	openAppendClose(fmt.Sprintf(LOG_PATTERN, level, time.Now().Format(time.UnixDate), src, msg))
     99 }
    100 
    101 func openAppendClose(s string) {
    102 
    103 	// first try opening only append
    104 	f, err := os.OpenFile(LOG_PATH, os.O_APPEND|os.O_WRONLY, 0600)
    105 	if err != nil || f == nil {
    106 		// if file does not yet exist, open with create flag.
    107 		f, err = os.OpenFile(LOG_PATH, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
    108 		if err != nil || f == nil {
    109 			fmt.Println("error: ", err.Error())
    110 			panic("failed opening or creating log file")
    111 		}
    112 	}
    113 	f.WriteString(s + "\n")
    114 	f.Close()
    115 }