- Added support for human readable units in -logrotate flag
This commit is contained in:
Toby Chui
2025-09-24 20:31:53 +08:00
parent e9c1d14e23
commit 778df1af0f
4 changed files with 121 additions and 3 deletions

View File

@@ -97,7 +97,7 @@ var (
/* Logging Configuration Flags */
enableLog = flag.Bool("enablelog", true, "Enable system wide logging, set to false for writing log to STDOUT only")
enableLogCompression = flag.Bool("enablelogcompress", true, "Enable log compression for rotated log files")
logRotate = flag.Int("logrotate", 0, "Enable log rotation and set the maximum log file size in KB (e.g. 25 for 25KB), set to 0 for disable")
logRotate = flag.String("logrotate", "0", "Enable log rotation and set the maximum log file size in KB, also support K, M, G suffix (e.g. 200M), set to 0 to disable")
/* Default Configuration Flags */
defaultInboundPort = flag.Int("default_inbound_port", 443, "Default web server listening port")

View File

@@ -22,6 +22,72 @@ func Int64ToString(number int64) string {
return convedNumber
}
func SizeStringToBytes(sizeStr string) (int64, error) {
sizeStr = strings.TrimSpace(sizeStr)
if len(sizeStr) == 0 {
return 0, nil
}
// Extract unit (1 or 2 characters) from the end of the string
var unit string
var sizeValue string
sizeStrLower := strings.ToLower(sizeStr)
if len(sizeStrLower) > 2 && (strings.HasSuffix(sizeStrLower, "kb") || strings.HasSuffix(sizeStrLower, "mb") || strings.HasSuffix(sizeStrLower, "gb") || strings.HasSuffix(sizeStrLower, "tb") || strings.HasSuffix(sizeStrLower, "pb")) {
unit = sizeStrLower[len(sizeStrLower)-2:]
sizeValue = sizeStrLower[:len(sizeStrLower)-2]
} else if len(sizeStrLower) > 1 && (strings.HasSuffix(sizeStrLower, "k") || strings.HasSuffix(sizeStrLower, "m") || strings.HasSuffix(sizeStrLower, "g") || strings.HasSuffix(sizeStrLower, "t") || strings.HasSuffix(sizeStrLower, "p")) {
unit = sizeStrLower[len(sizeStrLower)-1:]
sizeValue = sizeStrLower[:len(sizeStrLower)-1]
} else {
unit = ""
sizeValue = sizeStrLower
}
size, err := strconv.ParseFloat(sizeValue, 64)
if err != nil {
return 0, err
}
switch unit {
case "k", "kb":
size *= 1024
case "m", "mb":
size *= 1024 * 1024
case "g", "gb":
size *= 1024 * 1024 * 1024
case "t", "tb":
size *= 1024 * 1024 * 1024 * 1024
case "p", "pb":
size *= 1024 * 1024 * 1024 * 1024 * 1024
case "":
// No unit, size is already in bytes
default:
return 0, nil // Unknown unit
}
return int64(size), nil
}
func BytesToHumanReadable(bytes int64) string {
const (
KB = 1024
MB = KB * 1024
GB = MB * 1024
TB = GB * 1024
)
switch {
case bytes >= TB:
return strconv.FormatFloat(float64(bytes)/float64(TB), 'f', 2, 64) + " TB"
case bytes >= GB:
return strconv.FormatFloat(float64(bytes)/float64(GB), 'f', 2, 64) + " GB"
case bytes >= MB:
return strconv.FormatFloat(float64(bytes)/float64(MB), 'f', 2, 64) + " MB"
case bytes >= KB:
return strconv.FormatFloat(float64(bytes)/float64(KB), 'f', 2, 64) + " KB"
default:
return strconv.FormatInt(bytes, 10) + " Bytes"
}
}
func ReplaceSpecialCharacters(filename string) string {
replacements := map[string]string{
"#": "%pound%",

View File

@@ -0,0 +1,41 @@
package utils_test
import (
"testing"
"imuslab.com/zoraxy/mod/utils"
"github.com/stretchr/testify/assert"
)
func TestSizeStringToBytes(t *testing.T) {
tests := []struct {
input string
expected int64
hasError bool
}{
{"1024", 1024, false},
{"1k", 1024, false},
{"1K", 1024, false},
{"2kb", 2 * 1024, false},
{"1m", 1024 * 1024, false},
{"3mb", 3 * 1024 * 1024, false},
{"1g", 1024 * 1024 * 1024, false},
{"2gb", 2 * 1024 * 1024 * 1024, false},
{"", 0, false},
{" 5mb ", 5 * 1024 * 1024, false},
{"invalid", 0, true},
{"1tb", 1099511627776, false}, // Unknown unit returns 0, nil
{"1.5mb", int64(1.5 * 1024 * 1024), false},
}
for _, tt := range tests {
got, err := utils.SizeStringToBytes(tt.input)
if tt.hasError {
assert.Error(t, err, "input: %s", tt.input)
} else {
assert.NoError(t, err, "input: %s", tt.input)
assert.Equal(t, tt.expected, got, "input: %s", tt.input)
}
}
}

View File

@@ -12,6 +12,7 @@ import (
"imuslab.com/zoraxy/mod/auth/sso/oauth2"
"imuslab.com/zoraxy/mod/eventsystem"
"imuslab.com/zoraxy/mod/utils"
"github.com/gorilla/csrf"
"imuslab.com/zoraxy/mod/access"
@@ -76,14 +77,24 @@ func startupSequence() {
SystemWideLogger = l
SystemWideLogger.Println("System wide logging is disabled, all logs will be printed to STDOUT only")
} else {
logRotateSize, err := utils.SizeStringToBytes(*logRotate)
if err != nil {
//Default disable
logRotateSize = 0
}
l.SetRotateOption(&logger.RotateOption{
Enabled: *logRotate != 0,
MaxSize: int64(*logRotate) * 1024, //Convert to bytes
Enabled: logRotateSize != 0,
MaxSize: int64(logRotateSize),
MaxBackups: 10,
Compress: *enableLogCompression,
BackupDir: "",
})
SystemWideLogger = l
if logRotateSize == 0 {
SystemWideLogger.Println("Log rotation is disabled")
} else {
SystemWideLogger.Println("Log rotation is enabled, max log file size " + utils.BytesToHumanReadable(int64(logRotateSize)))
}
SystemWideLogger.Println("System wide logging is enabled")
}