summaryrefslogtreecommitdiff
path: root/internal/log/log.go
blob: f8326eb9d143f50b720a2e254b6fcb0fa0c7ba94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package log

import (
	"fmt"
	"io"
	"log"
	"os"
	"path"

	"github.com/eduvpn/eduvpn-common/internal/util"
	"github.com/eduvpn/eduvpn-common/types"
)

type FileLogger struct {
	Level LogLevel
	File  *os.File
}

type LogLevel int8

const (
	// No level set, not allowed
	LOG_NOTSET LogLevel = iota
	// Log debug, this message is not an error but is there for debugging
	LOG_DEBUG
	// Log info, this message is not an error but is there for additional information
	LOG_INFO
	// Log only to provide a warning, the app still functions
	LOG_WARNING
	// Log to provide a generic error, the app still functions but some functionality might not work
	LOG_ERROR
	// Log to provide a fatal error, the app cannot function correctly when such an error occurs
	LOG_FATAL
)

func (e LogLevel) String() string {
	switch e {
	case LOG_NOTSET:
		return "NOTSET"
	case LOG_DEBUG:
		return "DEBUG"
	case LOG_INFO:
		return "INFO"
	case LOG_WARNING:
		return "WARNING"
	case LOG_ERROR:
		return "ERROR"
	case LOG_FATAL:
		return "FATAL"
	default:
		return "UNKNOWN"
	}
}

func (logger *FileLogger) Init(level LogLevel, directory string) error {
	errorMessage := "failed creating log"

	configDirErr := util.EnsureDirectory(directory)
	if configDirErr != nil {
		return types.NewWrappedError(errorMessage, configDirErr)
	}
	logFile, logOpenErr := os.OpenFile(
		logger.getFilename(directory),
		os.O_RDWR|os.O_CREATE|os.O_APPEND,
		0o666,
	)
	if logOpenErr != nil {
		return types.NewWrappedError(errorMessage, logOpenErr)
	}
	multi := io.MultiWriter(os.Stdout, logFile)
	log.SetOutput(multi)
	logger.File = logFile
	logger.Level = level
	return nil
}

func (logger *FileLogger) Inherit(label string, err error) {
	level := types.GetErrorLevel(err)

	msg := fmt.Sprintf("%s with err: %s", label, types.GetErrorTraceback(err))
	switch level {
	case types.ERR_INFO:
		logger.Info(msg)
	case types.ERR_WARNING:
		logger.Warning(msg)
	case types.ERR_OTHER:
		logger.Error(msg)
	case types.ERR_FATAL:
		logger.Fatal(msg)
	}
}

func (logger *FileLogger) Debug(msg string) {
	logger.log(LOG_DEBUG, msg)
}

func (logger *FileLogger) Info(msg string) {
	logger.log(LOG_INFO, msg)
}

func (logger *FileLogger) Warning(msg string) {
	logger.log(LOG_WARNING, msg)
}

func (logger *FileLogger) Error(msg string) {
	logger.log(LOG_ERROR, msg)
}

func (logger *FileLogger) Fatal(msg string) {
	logger.log(LOG_FATAL, msg)
}

func (logger *FileLogger) Close() {
	logger.File.Close()
}

func (logger *FileLogger) getFilename(directory string) string {
	pathString := path.Join(directory, "go")
	return fmt.Sprintf("%s.log", pathString)
}

func (logger *FileLogger) log(level LogLevel, str string) {
	if level >= logger.Level && logger.Level != LOG_NOTSET {
		msg := fmt.Sprintf("- Go - %s - %s", level.String(), str)
		// To log file
		log.Println(msg)
	}
}