Evan Reichard
9792a6ff19
All checks were successful
continuous-integration/drone/push Build is passing
157 lines
3.8 KiB
Go
157 lines
3.8 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type Config struct {
|
|
// Server Config
|
|
Version string
|
|
ListenPort string
|
|
|
|
// DB Configuration
|
|
DBType string
|
|
DBName string
|
|
|
|
// Data Paths
|
|
ConfigPath string
|
|
DataPath string
|
|
|
|
// Miscellaneous Settings
|
|
RegistrationEnabled bool
|
|
SearchEnabled bool
|
|
DemoMode bool
|
|
LogLevel string
|
|
|
|
// Cookie Settings
|
|
CookieAuthKey string
|
|
CookieEncKey string
|
|
CookieSecure bool
|
|
CookieHTTPOnly bool
|
|
}
|
|
|
|
type customFormatter struct {
|
|
log.Formatter
|
|
}
|
|
|
|
// Force UTC & Set type (app)
|
|
func (cf customFormatter) Format(e *log.Entry) ([]byte, error) {
|
|
if e.Data["type"] == nil {
|
|
e.Data["type"] = "app"
|
|
}
|
|
e.Time = e.Time.UTC()
|
|
return cf.Formatter.Format(e)
|
|
}
|
|
|
|
// Set at runtime
|
|
var version string = "develop"
|
|
|
|
func Load() *Config {
|
|
c := &Config{
|
|
Version: version,
|
|
ConfigPath: getEnv("CONFIG_PATH", "/config"),
|
|
DataPath: getEnv("DATA_PATH", "/data"),
|
|
ListenPort: getEnv("LISTEN_PORT", "8585"),
|
|
DBType: trimLowerString(getEnv("DATABASE_TYPE", "SQLite")),
|
|
DBName: trimLowerString(getEnv("DATABASE_NAME", "antholume")),
|
|
RegistrationEnabled: trimLowerString(getEnv("REGISTRATION_ENABLED", "false")) == "true",
|
|
DemoMode: trimLowerString(getEnv("DEMO_MODE", "false")) == "true",
|
|
SearchEnabled: trimLowerString(getEnv("SEARCH_ENABLED", "false")) == "true",
|
|
CookieAuthKey: trimLowerString(getEnv("COOKIE_AUTH_KEY", "")),
|
|
CookieEncKey: trimLowerString(getEnv("COOKIE_ENC_KEY", "")),
|
|
LogLevel: trimLowerString(getEnv("LOG_LEVEL", "info")),
|
|
CookieSecure: trimLowerString(getEnv("COOKIE_SECURE", "true")) == "true",
|
|
CookieHTTPOnly: trimLowerString(getEnv("COOKIE_HTTP_ONLY", "true")) == "true",
|
|
}
|
|
|
|
// Parse log level
|
|
logLevel, err := log.ParseLevel(c.LogLevel)
|
|
if err != nil {
|
|
logLevel = log.InfoLevel
|
|
}
|
|
|
|
// Create custom formatter
|
|
logFormatter := &customFormatter{&log.JSONFormatter{
|
|
CallerPrettyfier: prettyCaller,
|
|
}}
|
|
|
|
// Create log rotator
|
|
rotateFileHook, err := NewRotateFileHook(RotateFileConfig{
|
|
Filename: path.Join(c.ConfigPath, "logs/antholume.log"),
|
|
MaxSize: 50,
|
|
MaxBackups: 3,
|
|
MaxAge: 30,
|
|
Level: logLevel,
|
|
Formatter: logFormatter,
|
|
})
|
|
if err != nil {
|
|
log.Fatal("Unable to initialize file rotate hook")
|
|
}
|
|
|
|
// Rotate now
|
|
rotateFileHook.Rotate()
|
|
|
|
// Set logger settings
|
|
log.SetLevel(logLevel)
|
|
log.SetFormatter(logFormatter)
|
|
log.SetReportCaller(true)
|
|
log.AddHook(rotateFileHook)
|
|
|
|
// Ensure directories exist
|
|
c.EnsureDirectories()
|
|
|
|
return c
|
|
}
|
|
|
|
// Ensures needed directories exist
|
|
func (c *Config) EnsureDirectories() {
|
|
os.Mkdir(c.ConfigPath, 0755)
|
|
os.Mkdir(c.DataPath, 0755)
|
|
|
|
docDir := filepath.Join(c.DataPath, "documents")
|
|
coversDir := filepath.Join(c.DataPath, "covers")
|
|
backupDir := filepath.Join(c.DataPath, "backups")
|
|
os.Mkdir(docDir, 0755)
|
|
os.Mkdir(coversDir, 0755)
|
|
os.Mkdir(backupDir, 0755)
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
if value, ok := os.LookupEnv(key); ok {
|
|
return value
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func trimLowerString(val string) string {
|
|
return strings.ToLower(strings.TrimSpace(val))
|
|
}
|
|
|
|
func prettyCaller(f *runtime.Frame) (function string, file string) {
|
|
purgePrefix := "reichard.io/antholume/"
|
|
|
|
pathName := strings.Replace(f.Func.Name(), purgePrefix, "", 1)
|
|
parts := strings.Split(pathName, ".")
|
|
|
|
filepath, line := f.Func.FileLine(f.PC)
|
|
splitFilePath := strings.Split(filepath, "/")
|
|
|
|
fileName := fmt.Sprintf("%s/%s@%d", parts[0], splitFilePath[len(splitFilePath)-1], line)
|
|
functionName := strings.Replace(pathName, parts[0]+".", "", 1)
|
|
|
|
// Exclude GIN Logger
|
|
if functionName == "NewApi.apiLogger.func1" {
|
|
fileName = ""
|
|
functionName = ""
|
|
}
|
|
|
|
return functionName, fileName
|
|
}
|