-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
logging.go
175 lines (149 loc) · 5.06 KB
/
logging.go
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package core
/* License: GPLv3
Authors:
Mirko Brombin <mirko@fabricators.ltd>
Vanilla OS Contributors <https://github.com/vanilla-os/>
Copyright: 2024
Description:
ABRoot is utility which provides full immutability and
atomicity to a Linux system, by transacting between
two root filesystems. Updates are performed using OCI
images, to ensure that the system is always in a
consistent state.
*/
import (
"fmt"
"log"
"os"
"path/filepath"
"time"
"github.com/vanilla-os/orchid/cmdr"
)
// logFile is a file handle for the log file
var logFile *os.File
// printLog is a logger to Stdout for verbose information
var printLog = log.New(os.Stdout, "(Verbose) ", 0)
// init initializes the log file and sets up logging
func init() {
PrintVerboseInfo("NewLogFile", "running...")
// Incremental value to append to log file name
incremental := 0
// Check for existing log files
logFiles, err := filepath.Glob("/var/log/abroot.log.*")
if err != nil {
// If there are no log files, start with incremental 1
incremental = 1
} else {
allIncrementals := []int{}
// Extract incremental values from existing log file names
for _, logFile := range logFiles {
_, err := fmt.Sscanf(logFile, "/var/log/abroot.log.%d", &incremental)
if err != nil {
continue
}
allIncrementals = append(allIncrementals, incremental)
}
// Set incremental to the next available value
if len(allIncrementals) == 0 {
incremental = 1
} else {
incremental = allIncrementals[len(allIncrementals)-1] + 1
}
}
// Open or create the log file
logFile, err = os.OpenFile(
fmt.Sprintf("/var/log/abroot.log.%d", incremental),
os.O_RDWR|os.O_CREATE|os.O_APPEND,
0666,
)
if err != nil {
PrintVerboseErrNoLog("NewLogFile", 0, "failed to open log file", err)
}
}
// IsVerbose checks if verbose mode is enabled
func IsVerbose() bool {
flag := cmdr.FlagValBool("verbose")
_, arg := os.LookupEnv("ABROOT_VERBOSE")
return flag || arg
}
// formatMessage formats log messages based on prefix, level, and depth
func formatMessage(prefix, level string, depth float32, args ...interface{}) string {
if prefix == "" && level == "" && depth == -1 {
return fmt.Sprint(args...)
}
if depth > -1 {
level = fmt.Sprintf("%s(%f)", level, depth)
}
return fmt.Sprintf("%s:%s:%s", prefix, level, fmt.Sprint(args...))
}
// printFormattedMessage prints formatted log messages to Stdout
func printFormattedMessage(formattedMsg string) {
printLog.Printf("%s\n", formattedMsg)
}
// logToFileIfEnabled logs messages to the file if logging is enabled
func logToFileIfEnabled(formattedMsg string) {
if logFile != nil {
LogToFile(formattedMsg)
}
}
// PrintVerboseNoLog prints verbose messages without logging to the file
func PrintVerboseNoLog(prefix, level string, depth float32, args ...interface{}) {
if IsVerbose() {
formattedMsg := formatMessage(prefix, level, depth, args...)
printFormattedMessage(formattedMsg)
}
}
// PrintVerbose prints verbose messages and logs to the file if enabled
func PrintVerbose(prefix, level string, depth float32, args ...interface{}) {
PrintVerboseNoLog(prefix, level, depth, args...)
logToFileIfEnabled(formatMessage(prefix, level, depth, args...))
}
// PrintVerboseSimpleNoLog prints simple verbose messages without logging to the file
func PrintVerboseSimpleNoLog(args ...interface{}) {
PrintVerboseNoLog("", "", -1, args...)
}
// PrintVerboseSimple prints simple verbose messages and logs to the file if enabled
func PrintVerboseSimple(args ...interface{}) {
PrintVerbose("", "", -1, args...)
}
// PrintVerboseErrNoLog prints verbose error messages without logging to the file
func PrintVerboseErrNoLog(prefix string, depth float32, args ...interface{}) {
PrintVerboseNoLog(prefix, "err", depth, args...)
}
// PrintVerboseErr prints verbose error messages and logs to the file if enabled
func PrintVerboseErr(prefix string, depth float32, args ...interface{}) {
PrintVerbose(prefix, "err", depth, args...)
}
// PrintVerboseWarnNoLog prints verbose warning messages without logging to the file
func PrintVerboseWarnNoLog(prefix string, depth float32, args ...interface{}) {
PrintVerboseNoLog(prefix, "warn", depth, args...)
}
// PrintVerboseWarn prints verbose warning messages and logs to the file if enabled
func PrintVerboseWarn(prefix string, depth float32, args ...interface{}) {
PrintVerbose(prefix, "warn", depth, args...)
}
// PrintVerboseInfoNoLog prints verbose info messages without logging to the file
func PrintVerboseInfoNoLog(prefix string, args ...interface{}) {
PrintVerboseNoLog(prefix, "info", -1, args...)
}
// PrintVerboseInfo prints verbose info messages and logs to the file if enabled
func PrintVerboseInfo(prefix string, args ...interface{}) {
PrintVerbose(prefix, "info", -1, args...)
}
// LogToFile writes messages to the log file
func LogToFile(msg string, args ...interface{}) error {
if logFile != nil {
_, err := fmt.Fprintf(
logFile,
"%s: %s\n",
time.Now().Format("2006-01-02 1 15:04:05"),
fmt.Sprintf(msg, args...),
)
return err
}
return nil
}
// GetLogFile returns the log file handle
func GetLogFile() *os.File {
return logFile
}