mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 00:13:46 +01:00
add lumberjack log rotation (#5696)
* [logging] add UI and graphql for maximum log size * [logger] set default size to 0MB and don't rotate
This commit is contained in:
parent
2f65a1da3e
commit
78aeb06f20
11 changed files with 64 additions and 19 deletions
|
|
@ -110,7 +110,7 @@ func main() {
|
|||
// Logs only error level message to stderr.
|
||||
func initLogTemp() *log.Logger {
|
||||
l := log.NewLogger()
|
||||
l.Init("", true, "Error")
|
||||
l.Init("", true, "Error", 0)
|
||||
logger.Logger = l
|
||||
|
||||
return l
|
||||
|
|
@ -118,7 +118,7 @@ func initLogTemp() *log.Logger {
|
|||
|
||||
func initLog(cfg *config.Config) *log.Logger {
|
||||
l := log.NewLogger()
|
||||
l.Init(cfg.GetLogFile(), cfg.GetLogOut(), cfg.GetLogLevel())
|
||||
l.Init(cfg.GetLogFile(), cfg.GetLogOut(), cfg.GetLogLevel(), cfg.GetLogFileMaxSize())
|
||||
logger.Logger = l
|
||||
|
||||
return l
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -63,6 +63,7 @@ require (
|
|||
golang.org/x/text v0.25.0
|
||||
golang.org/x/time v0.10.0
|
||||
gopkg.in/guregu/null.v4 v4.0.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -1122,6 +1122,8 @@ gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||
gopkg.in/ini.v1 v1.66.3/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
|
|||
|
|
@ -155,6 +155,8 @@ input ConfigGeneralInput {
|
|||
logLevel: String
|
||||
"Whether to log http access"
|
||||
logAccess: Boolean
|
||||
"Maximum log size"
|
||||
logFileMaxSize: Int
|
||||
"True if galleries should be created from folders with images"
|
||||
createGalleriesFromFolders: Boolean
|
||||
"Regex used to identify images as gallery covers"
|
||||
|
|
@ -279,6 +281,8 @@ type ConfigGeneralResult {
|
|||
logLevel: String!
|
||||
"Whether to log http access"
|
||||
logAccess: Boolean!
|
||||
"Maximum log size"
|
||||
logFileMaxSize: Int!
|
||||
"Array of video file extensions"
|
||||
videoExtensions: [String!]!
|
||||
"Array of image file extensions"
|
||||
|
|
|
|||
|
|
@ -334,6 +334,10 @@ func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input ConfigGen
|
|||
logger.SetLogLevel(*input.LogLevel)
|
||||
}
|
||||
|
||||
if input.LogFileMaxSize != nil && *input.LogFileMaxSize != c.GetLogFileMaxSize() {
|
||||
c.SetInt(config.LogFileMaxSize, *input.LogFileMaxSize)
|
||||
}
|
||||
|
||||
if input.Excludes != nil {
|
||||
for _, r := range input.Excludes {
|
||||
_, err := regexp.Compile(r)
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ func makeConfigGeneralResult() *ConfigGeneralResult {
|
|||
LogOut: config.GetLogOut(),
|
||||
LogLevel: config.GetLogLevel(),
|
||||
LogAccess: config.GetLogAccess(),
|
||||
LogFileMaxSize: config.GetLogFileMaxSize(),
|
||||
VideoExtensions: config.GetVideoExtensions(),
|
||||
ImageExtensions: config.GetImageExtensions(),
|
||||
GalleryExtensions: config.GetGalleryExtensions(),
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ package log
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
type LogItem struct {
|
||||
|
|
@ -41,8 +43,8 @@ func NewLogger() *Logger {
|
|||
}
|
||||
|
||||
// Init initialises the logger based on a logging configuration
|
||||
func (log *Logger) Init(logFile string, logOut bool, logLevel string) {
|
||||
var file *os.File
|
||||
func (log *Logger) Init(logFile string, logOut bool, logLevel string, logFileMaxSize int) {
|
||||
var logger io.WriteCloser
|
||||
customFormatter := new(logrus.TextFormatter)
|
||||
customFormatter.TimestampFormat = "2006-01-02 15:04:05"
|
||||
customFormatter.ForceColors = true
|
||||
|
|
@ -57,30 +59,38 @@ func (log *Logger) Init(logFile string, logOut bool, logLevel string) {
|
|||
// the access log colouring not being applied
|
||||
_, _ = customFormatter.Format(logrus.NewEntry(log.logger))
|
||||
|
||||
// if size is 0, disable rotation
|
||||
if logFile != "" {
|
||||
var err error
|
||||
file, err = os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Could not open '%s' for log output due to error: %s\n", logFile, err.Error())
|
||||
if logFileMaxSize == 0 {
|
||||
var err error
|
||||
logger, err = os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to open log file %s: %v\n", logFile, err)
|
||||
}
|
||||
} else {
|
||||
logger = &lumberjack.Logger{
|
||||
Filename: logFile,
|
||||
MaxSize: logFileMaxSize, // Megabytes
|
||||
Compress: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if file != nil {
|
||||
if logger != nil {
|
||||
if logOut {
|
||||
// log to file separately disabling colours
|
||||
fileFormatter := new(logrus.TextFormatter)
|
||||
fileFormatter.TimestampFormat = customFormatter.TimestampFormat
|
||||
fileFormatter.FullTimestamp = customFormatter.FullTimestamp
|
||||
log.logger.AddHook(&fileLogHook{
|
||||
Writer: file,
|
||||
Writer: logger,
|
||||
Formatter: fileFormatter,
|
||||
})
|
||||
} else {
|
||||
// logging to file only
|
||||
// turn off the colouring for the file
|
||||
customFormatter.ForceColors = false
|
||||
log.logger.Out = file
|
||||
log.logger.Out = logger
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -252,13 +252,15 @@ const (
|
|||
DLNAPortDefault = 1338
|
||||
|
||||
// Logging options
|
||||
LogFile = "logfile"
|
||||
LogOut = "logout"
|
||||
defaultLogOut = true
|
||||
LogLevel = "loglevel"
|
||||
defaultLogLevel = "Info"
|
||||
LogAccess = "logaccess"
|
||||
defaultLogAccess = true
|
||||
LogFile = "logfile"
|
||||
LogOut = "logout"
|
||||
defaultLogOut = true
|
||||
LogLevel = "loglevel"
|
||||
defaultLogLevel = "Info"
|
||||
LogAccess = "logaccess"
|
||||
defaultLogAccess = true
|
||||
LogFileMaxSize = "logfile_max_size"
|
||||
defaultLogFileMaxSize = 0 // megabytes, default disabled
|
||||
|
||||
// Default settings
|
||||
DefaultScanSettings = "defaults.scan_task"
|
||||
|
|
@ -1636,6 +1638,16 @@ func (i *Config) GetLogAccess() bool {
|
|||
return i.getBoolDefault(LogAccess, defaultLogAccess)
|
||||
}
|
||||
|
||||
// GetLogFileMaxSize returns the maximum size of the log file in megabytes for lumberjack to rotate
|
||||
func (i *Config) GetLogFileMaxSize() int {
|
||||
value := i.getInt(LogFileMaxSize)
|
||||
if value < 0 {
|
||||
value = defaultLogFileMaxSize
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
// Max allowed graphql upload size in megabytes
|
||||
func (i *Config) GetMaxUploadSize() int64 {
|
||||
i.RLock()
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ fragment ConfigGeneralData on ConfigGeneralResult {
|
|||
logOut
|
||||
logLevel
|
||||
logAccess
|
||||
logFileMaxSize
|
||||
createGalleriesFromFolders
|
||||
galleryCoverRegex
|
||||
videoExtensions
|
||||
|
|
|
|||
|
|
@ -465,6 +465,14 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||
checked={general.logAccess ?? false}
|
||||
onChange={(v) => saveGeneral({ logAccess: v })}
|
||||
/>
|
||||
|
||||
<NumberSetting
|
||||
id="log-file-max-size"
|
||||
headingID="config.general.auth.log_file_max_size"
|
||||
subHeadingID="config.general.auth.log_file_max_size_desc"
|
||||
value={general.logFileMaxSize ?? 10}
|
||||
onChange={(v) => saveGeneral({ logFileMaxSize: v })}
|
||||
/>
|
||||
</SettingSection>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -301,6 +301,8 @@
|
|||
"log_http_desc": "Logs http access to the terminal. Requires restart.",
|
||||
"log_to_terminal": "Log to terminal",
|
||||
"log_to_terminal_desc": "Logs to the terminal in addition to a file. Always true if file logging is disabled. Requires restart.",
|
||||
"log_file_max_size": "Maximum log size",
|
||||
"log_file_max_size_desc": "Maximum size in megabytes of the log file before it is compressed. 0MB is disabled. Requires restart.",
|
||||
"maximum_session_age": "Maximum Session Age",
|
||||
"maximum_session_age_desc": "Maximum idle time before a login session is expired, in seconds. Requires restart.",
|
||||
"password": "Password",
|
||||
|
|
|
|||
Loading…
Reference in a new issue