Files
zurg/pkg/logutil/factory.go
2024-01-26 09:52:37 +01:00

170 lines
3.7 KiB
Go

package logutil
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
type Logger struct {
*zap.SugaredLogger
logPath string
}
func NewLogger(logPath string) *Logger {
envLogLevel := os.Getenv("LOG_LEVEL")
var zapLevel zapcore.Level
switch envLogLevel {
case "DEBUG":
zapLevel = zapcore.DebugLevel
case "INFO":
zapLevel = zapcore.InfoLevel
case "WARN":
zapLevel = zapcore.WarnLevel
case "ERROR":
zapLevel = zapcore.ErrorLevel
case "FATAL":
zapLevel = zapcore.FatalLevel
default:
zapLevel = zapcore.DebugLevel
}
zapCfg := zap.NewDevelopmentConfig()
zapCfg.Level.SetLevel(zapLevel)
consoleCfg := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
MessageKey: "msg",
CallerKey: "",
StacktraceKey: "",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalColorLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
}
consoleEncoder := zapcore.NewConsoleEncoder(consoleCfg)
fileCfg := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
MessageKey: "msg",
CallerKey: "",
StacktraceKey: "",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
}
fileEncoder := zapcore.NewConsoleEncoder(fileCfg)
// Set up file logging with overwrite mode
logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
panic("cannot open log file: " + err.Error())
}
fmt.Println("Logging to", logPath)
core := zapcore.NewTee(
zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), zapCfg.Level),
zapcore.NewCore(fileEncoder, zapcore.AddSync(logFile), zapCfg.Level),
)
logger := zap.New(core, zap.AddCaller(), zap.Development())
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
zLogger := &Logger{
SugaredLogger: sugar,
logPath: logPath,
}
return zLogger
}
func (l *Logger) Named(name string) *Logger {
return &Logger{
SugaredLogger: l.SugaredLogger.Named(name),
logPath: l.logPath,
}
}
func (l *Logger) GetLogsFromFile() (string, error) {
file, err := os.Open(l.logPath)
if err != nil {
return "", err
}
defer file.Close()
var buffer bytes.Buffer
_, err = io.Copy(&buffer, file)
if err != nil {
return "", err
}
return buffer.String(), nil
}
func (l *Logger) UploadLogFile() (string, error) {
file, err := os.Open(l.logPath)
if err != nil {
return "", err
}
defer file.Close()
// Prepare a form that you will submit to that URL.
var b bytes.Buffer
w := multipart.NewWriter(&b)
fw, err := w.CreateFormFile("file", filepath.Base(l.logPath))
if err != nil {
return "", err
}
// Copy the file into the form file
if _, err = io.Copy(fw, file); err != nil {
return "", err
}
// Close the multipart writer to set the terminating boundary
if err = w.Close(); err != nil {
return "", err
}
// Create a request and add the proper headers.
req, err := http.NewRequest("POST", "https://0x0.st/", &b)
if err != nil {
return "", err
}
req.Header.Set("Content-Type", w.FormDataContentType())
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("failed to upload log file, server responded with status code: %d", resp.StatusCode)
}
// Read the response body
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(responseBody), nil
}