feature/adding-log-file #1

Merged
iratusmachina merged 4 commits from feature/adding-log-file into main 2024-05-06 07:23:52 +00:00
2 changed files with 200 additions and 0 deletions
Showing only changes of commit c2bfb55852 - Show all commits

52
conf.go Normal file
View File

@ -0,0 +1,52 @@
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
const CONFIG_LOG string = "/var/lib/gocustomurls/"
type ConfigFile struct {
Mappings []struct {
Protocol string `json:"protocol"`
VanityUrl string `json:"vanity_url"`
RealUrl string `json:"real_url"`
} `json:"mappings"`
}
// isFile - check if fp is a valid file
func isFile(fp string) bool {
info, err := os.Stat(fp)
if os.IsNotExist(err) || !info.Mode().IsRegular() {
return false
}
return true
}
// load mapping file
func LoadFile() (ConfigFile, error) {
var mapping ConfigFile
dirname, err := os.UserConfigDir()
if err != nil {
return mapping, err
}
configFilePath := filepath.Join(dirname, "gocustomurls/config.json")
ok := isFile(configFilePath)
if !ok {
return mapping, fmt.Errorf("%s/gocustomurls/config.json file is not found", dirname)
}
configFile, err := os.Open(configFilePath)
if err != nil {
return mapping, err
}
defer configFile.Close()
err = json.NewDecoder(configFile).Decode(&mapping)
if err != nil {
return mapping, err
}
return mapping, nil
}

148
logger.go Normal file
View File

@ -0,0 +1,148 @@
package main
import (
"encoding/json"
"log"
"net/http"
"os"
"strings"
)
// some headers not worth logging
var (
hdrsToNotLog = []string{
"Accept-Language",
"Cache-Control",
"Cf-Ray",
"CF-Visitor",
"CF-Connecting-IP",
"Cdn-Loop",
"Cookie",
"Connection",
"Dnt",
"If-Modified-Since",
"Sec-Fetch-Dest",
"Sec-Ch-Ua-Mobile",
// "Sec-Ch-Ua",
"Sec-Ch-Ua-Platform",
"Sec-Fetch-Site",
"Sec-Fetch-Mode",
"Sec-Fetch-User",
"Upgrade-Insecure-Requests",
"X-Request-Start",
"X-Forwarded-For",
"X-Forwarded-Proto",
"X-Forwarded-Host",
}
hdrsToNotLogMap map[string]bool
)
type LogFile struct {
handle *os.File
logger *log.Logger
path string
}
type LogFileRec struct {
Method string `json:"method"`
IpAddr string `json:"ipAddr"`
Url string `json:"url"`
}
func newFileLogger(path string) (*LogFile, error) {
f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
return nil, err
}
return &LogFile{
handle: f,
logger: log.New(f, "", 0),
path: path,
}, nil
}
func (f *LogFile) Close() error {
if f == nil {
return nil
}
err := f.handle.Close()
f.handle = nil
return err
}
func extractFirstFragment(header *http.Header, headerName string) string {
s := header.Get(headerName)
if len(strings.TrimSpace(s)) == 0 {
return s
}
fragments := strings.Split(s, ",")
return strings.TrimSpace(fragments[0])
}
// Get Ip Address of the client
func extractIpAddress(r *http.Request) string {
var ipAddr string
if r == nil {
return ""
}
possibleIpHeaders := []string{"CF-Connecting-IP", "X-Real-Ip", "X-Forwarded-For"}
for _, header := range possibleIpHeaders {
ipAddr = extractFirstFragment(&r.Header, header)
if len(strings.TrimSpace(ipAddr)) != 0 {
return ipAddr
}
}
// pull ip from Request.RemoteAddr
if len(strings.TrimSpace(r.RemoteAddr)) != 0 {
index := strings.LastIndex(r.RemoteAddr, ";")
if index == -1 {
return r.RemoteAddr
}
ipAddr = r.RemoteAddr[:index]
}
return ipAddr
}
func canSkipExtraHeaders(r *http.Request) bool {
ref := r.Header.Get("Referer")
if len(strings.TrimSpace(ref)) == 0 {
return false
}
return strings.Contains(ref, r.Host)
}
func shouldLogHeader(s string) bool {
if hdrsToNotLogMap == nil {
hdrsToNotLogMap = map[string]bool{}
for _, h := range hdrsToNotLog {
h = strings.ToLower(h)
hdrsToNotLogMap[h] = true
}
}
s = strings.ToLower(s)
return !hdrsToNotLogMap[s]
}
func (f *LogFile) WriteLog(r *http.Request) error {
if f == nil {
return nil
}
var rec = make(map[string]string)
rec["method"] = r.Method
rec["requestUri"] = r.RequestURI
rec["Host"] = r.Host
rec["ipAddr"] = extractIpAddress(r)
if !canSkipExtraHeaders(r) {
for key, val := range r.Header {
if shouldLogHeader(key) && len(val) > 0 {
rec[key] = val[0]
}
}
}
b, err := json.Marshal(rec)
if err != nil {
return err
}
f.logger.Println(string(b))
return nil
}