Compare commits

...

3 Commits

Author SHA1 Message Date
0ebafa2e99 Prevent archiving already archived files 2025-08-21 13:39:52 +02:00
d95182f187 Add some logs 2025-08-21 13:34:45 +02:00
2274829eda Configure log rotation for cleaner services
They were like 90G big...
2025-08-18 21:48:55 +02:00
2 changed files with 54 additions and 11 deletions

45
main.go
View File

@@ -80,6 +80,10 @@ func loadConfig() Constants {
archive := filepath.ToSlash(strings.TrimSpace(getenv("ROOT_ARCHIVE", root+"/archive"))) archive := filepath.ToSlash(strings.TrimSpace(getenv("ROOT_ARCHIVE", root+"/archive")))
_ = os.MkdirAll(archive, os.ModePerm) _ = os.MkdirAll(archive, os.ModePerm)
// TODO: This just doesn't really work or do what it says it does
// Fix it...
// Right now we don't care because we're not using it
// But we might want to...
ignored := []string{} ignored := []string{}
if ig := strings.TrimSpace(getenv("IGNORED_DIRECTORIES", "")); ig != "" { if ig := strings.TrimSpace(getenv("IGNORED_DIRECTORIES", "")); ig != "" {
for _, s := range strings.Split(ig, ",") { for _, s := range strings.Split(ig, ",") {
@@ -88,9 +92,6 @@ func loadConfig() Constants {
} }
} }
} }
// Always ignore ROOT and ROOT_ARCHIVE themselves
ignored = append(ignored, filepath.ToSlash(archive))
ignored = append(ignored, filepath.ToSlash(root))
archiveMs := parseDurationMS(getenv("ARCHIVE_THRESHOLD", "1d")) archiveMs := parseDurationMS(getenv("ARCHIVE_THRESHOLD", "1d"))
deleteMs := parseDurationMS(getenv("DELETE_THRESHOLD", "12h")) deleteMs := parseDurationMS(getenv("DELETE_THRESHOLD", "12h"))
@@ -118,15 +119,18 @@ func loadConfig() Constants {
} }
func shouldIgnore(path string) bool { func shouldIgnore(path string) bool {
log := logger.Default.WithPrefix("shouldIgnore").WithPrefix(path)
// Match against slash-normalized full path // Match against slash-normalized full path
path = filepath.ToSlash(path) path = filepath.ToSlash(path)
for _, pat := range constants.IGNORED_DIRECTORIES { for _, pat := range constants.IGNORED_DIRECTORIES {
patLog := log.WithPrefix(pat)
ok, err := doublestar.Match(pat, path) ok, err := doublestar.Match(pat, path)
if err != nil { if err != nil {
logger.Warning("Ignore pattern error %q vs %q: %v", pat, path, err) patLog.Warning("Ignore pattern error %q vs %q: %v", pat, path, err)
continue continue
} }
if ok || path == pat { if ok {
patLog.Debug("ignore due to doublestar %q", pat)
return true return true
} }
} }
@@ -143,50 +147,63 @@ func fileTime(info os.FileInfo) int64 {
} }
func archiveCandidate(path string, info os.FileInfo) { func archiveCandidate(path string, info os.FileInfo) {
log := logger.Default.WithPrefix("archiveCandidate")
if info.IsDir() { if info.IsDir() {
return return
} }
now := time.Now().UnixMilli() now := time.Now().UnixMilli()
ft := fileTime(info) ft := fileTime(info)
log.Debug("now %s filetime %s", time.UnixMilli(now).Format(time.RFC3339), time.UnixMilli(ft).Format(time.RFC3339))
if now-ft <= constants.ARCHIVE_THRESHOLD { if now-ft <= constants.ARCHIVE_THRESHOLD {
log.Debug("skip")
return return
} }
rel, err := filepath.Rel(constants.ROOT, path) rel, err := filepath.Rel(constants.ROOT, path)
if err != nil { if err != nil {
logger.Warning("rel ROOT->%s: %v", path, err) log.Warning("rel ROOT->%s: %v", path, err)
return return
} }
if strings.HasPrefix(rel, "archive") {
log.Debug("refusing to archive a file that's already archived")
return
}
log.Debug("rel %q", rel)
dst := filepath.Join(constants.ROOT_ARCHIVE, rel) dst := filepath.Join(constants.ROOT_ARCHIVE, rel)
log.Debug("dst %q", dst)
if err := os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil { if err := os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil {
logger.Error("mkdir %s: %v", filepath.Dir(dst), err) log.Error("mkdir %s: %v", filepath.Dir(dst), err)
return return
} }
if err := os.Rename(path, dst); err != nil { if err := os.Rename(path, dst); err != nil {
logger.Error("archive %s -> %s: %v", path, dst, err) log.Error("archive %s -> %s: %v", path, dst, err)
return return
} }
numFilesArchived++ numFilesArchived++
logger.Info("Archived: %s -> %s", path, dst) log.Info("Archived: %s -> %s", path, dst)
} }
func deleteCandidate(path string, info os.FileInfo) { func deleteCandidate(path string, info os.FileInfo) {
log := logger.Default.WithPrefix("deleteCandidate").WithPrefix(path)
if info.IsDir() { if info.IsDir() {
return return
} }
now := time.Now().UnixMilli() now := time.Now().UnixMilli()
ft := fileTime(info) ft := fileTime(info)
log.Debug("now %s filetime %s", time.UnixMilli(now).Format(time.RFC3339), time.UnixMilli(ft).Format(time.RFC3339))
if now-ft <= constants.DELETE_THRESHOLD { if now-ft <= constants.DELETE_THRESHOLD {
log.Debug("skip")
return return
} }
log.Debug("delete")
if err := os.Remove(path); err != nil { if err := os.Remove(path); err != nil {
logger.Error("delete %s: %v", path, err) log.Error("delete %s: %v", path, err)
return return
} }
numFilesDeleted++ numFilesDeleted++
logger.Info("Deleted: %s", path) log.Info("Deleted: %s", path)
} }
func scanRoot() { func scanRoot() {
@@ -194,17 +211,23 @@ func scanRoot() {
root := constants.ROOT root := constants.ROOT
// doublestar.Glob with os.DirFS(root) returns relative paths // doublestar.Glob with os.DirFS(root) returns relative paths
log.Debug("glob %s", root)
paths, err := doublestar.Glob(os.DirFS(root), "**") paths, err := doublestar.Glob(os.DirFS(root), "**")
if err != nil { if err != nil {
log.Error("glob %s: %v", root, err) log.Error("glob %s: %v", root, err)
return return
} }
log.Info("Found %d files in root", len(paths))
for _, rel := range paths { for _, rel := range paths {
pathLog := log.WithPrefix(rel)
full := filepath.Join(root, rel) full := filepath.Join(root, rel)
pathLog.Debug("full %s", full)
if shouldIgnore(full) { if shouldIgnore(full) {
pathLog.Debug("ignore")
continue continue
} }
info, err := os.Stat(full) info, err := os.Stat(full)
pathLog.Trace("stat %+v", info)
if err != nil { if err != nil {
log.Warning("stat %s: %v", full, err) log.Warning("stat %s: %v", full, err)
continue continue

View File

@@ -7,7 +7,12 @@ nssm set DirectoryCleanerTmp AppEnvironmentExtra ARCHIVE_THRESHOLD=12h DELETE_TH
nssm set DirectoryCleanerTmp AppDirectory C:\\tmp nssm set DirectoryCleanerTmp AppDirectory C:\\tmp
nssm set DirectoryCleanerTmp AppExit Default Restart nssm set DirectoryCleanerTmp AppExit Default Restart
nssm set DirectoryCleanerTmp AppStdout C:\\tmp\\cleaner.log nssm set DirectoryCleanerTmp AppStdout C:\\tmp\\cleaner.log
nssm set DirectoryCleanerTmp AppStdoutCreationDisposition 2
nssm set DirectoryCleanerTmp AppStderr C:\\tmp\\cleaner.log nssm set DirectoryCleanerTmp AppStderr C:\\tmp\\cleaner.log
nssm set DirectoryCleanerTmp AppStderrCreationDisposition 2
nssm set DirectoryCleanerTmp AppRotateFiles 1
nssm set DirectoryCleanerTmp AppRotateOnline 1
nssm set DirectoryCleanerTmp AppRotateBytes 104857600
nssm set DirectoryCleanerTmp DisplayName DirectoryCleanerTmp nssm set DirectoryCleanerTmp DisplayName DirectoryCleanerTmp
nssm set DirectoryCleanerTmp ObjectName LocalSystem nssm set DirectoryCleanerTmp ObjectName LocalSystem
nssm set DirectoryCleanerTmp Start SERVICE_AUTO_START nssm set DirectoryCleanerTmp Start SERVICE_AUTO_START
@@ -19,7 +24,12 @@ nssm set DirectoryCleanerTmpE AppEnvironmentExtra ARCHIVE_THRESHOLD=1d DELETE_TH
nssm set DirectoryCleanerTmpE AppDirectory E:\\tmp nssm set DirectoryCleanerTmpE AppDirectory E:\\tmp
nssm set DirectoryCleanerTmpE AppExit Default Restart nssm set DirectoryCleanerTmpE AppExit Default Restart
nssm set DirectoryCleanerTmpE AppStdout E:\\tmp\\cleaner.log nssm set DirectoryCleanerTmpE AppStdout E:\\tmp\\cleaner.log
nssm set DirectoryCleanerTmpE AppStdoutCreationDisposition 2
nssm set DirectoryCleanerTmpE AppStderr E:\\tmp\\cleaner.log nssm set DirectoryCleanerTmpE AppStderr E:\\tmp\\cleaner.log
nssm set DirectoryCleanerTmpE AppStderrCreationDisposition 2
nssm set DirectoryCleanerTmpE AppRotateFiles 1
nssm set DirectoryCleanerTmpE AppRotateOnline 1
nssm set DirectoryCleanerTmpE AppRotateBytes 104857600
nssm set DirectoryCleanerTmpE DisplayName DirectoryCleanerTmpE nssm set DirectoryCleanerTmpE DisplayName DirectoryCleanerTmpE
nssm set DirectoryCleanerTmpE ObjectName LocalSystem nssm set DirectoryCleanerTmpE ObjectName LocalSystem
nssm set DirectoryCleanerTmpE Start SERVICE_AUTO_START nssm set DirectoryCleanerTmpE Start SERVICE_AUTO_START
@@ -31,7 +41,12 @@ nssm set DirectoryCleanerDownloads AppEnvironmentExtra ARCHIVE_THRESHOLD=6h DELE
nssm set DirectoryCleanerDownloads AppDirectory "C:\\Users\\Administrator\\Downloads" nssm set DirectoryCleanerDownloads AppDirectory "C:\\Users\\Administrator\\Downloads"
nssm set DirectoryCleanerDownloads AppExit Default Restart nssm set DirectoryCleanerDownloads AppExit Default Restart
nssm set DirectoryCleanerDownloads AppStdout "C:\\Users\\Administrator\\Downloads\\cleaner.log" nssm set DirectoryCleanerDownloads AppStdout "C:\\Users\\Administrator\\Downloads\\cleaner.log"
nssm set DirectoryCleanerDownloads AppStdoutCreationDisposition 2
nssm set DirectoryCleanerDownloads AppStderr "C:\\Users\\Administrator\\Downloads\\cleaner.log" nssm set DirectoryCleanerDownloads AppStderr "C:\\Users\\Administrator\\Downloads\\cleaner.log"
nssm set DirectoryCleanerDownloads AppStderrCreationDisposition 2
nssm set DirectoryCleanerDownloads AppRotateFiles 1
nssm set DirectoryCleanerDownloads AppRotateOnline 1
nssm set DirectoryCleanerDownloads AppRotateBytes 104857600
nssm set DirectoryCleanerDownloads DisplayName DirectoryCleanerDownloads nssm set DirectoryCleanerDownloads DisplayName DirectoryCleanerDownloads
nssm set DirectoryCleanerDownloads ObjectName LocalSystem nssm set DirectoryCleanerDownloads ObjectName LocalSystem
nssm set DirectoryCleanerDownloads Start SERVICE_AUTO_START nssm set DirectoryCleanerDownloads Start SERVICE_AUTO_START
@@ -43,7 +58,12 @@ nssm set DirectoryCleanerTemp AppEnvironmentExtra ARCHIVE_THRESHOLD=6h DELETE_TH
nssm set DirectoryCleanerTemp AppDirectory "C:\\Users\\Administrator\\AppData\\Local\\Temp" nssm set DirectoryCleanerTemp AppDirectory "C:\\Users\\Administrator\\AppData\\Local\\Temp"
nssm set DirectoryCleanerTemp AppExit Default Restart nssm set DirectoryCleanerTemp AppExit Default Restart
nssm set DirectoryCleanerTemp AppStdout "C:\\Users\\Administrator\\AppData\\Local\\Temp\\cleaner.log" nssm set DirectoryCleanerTemp AppStdout "C:\\Users\\Administrator\\AppData\\Local\\Temp\\cleaner.log"
nssm set DirectoryCleanerTemp AppStdoutCreationDisposition 2
nssm set DirectoryCleanerTemp AppStderr "C:\\Users\\Administrator\\AppData\\Local\\Temp\\cleaner.log" nssm set DirectoryCleanerTemp AppStderr "C:\\Users\\Administrator\\AppData\\Local\\Temp\\cleaner.log"
nssm set DirectoryCleanerTemp AppStderrCreationDisposition 2
nssm set DirectoryCleanerTemp AppRotateFiles 1
nssm set DirectoryCleanerTemp AppRotateOnline 1
nssm set DirectoryCleanerTemp AppRotateBytes 104857600
nssm set DirectoryCleanerTemp DisplayName DirectoryCleanerTemp nssm set DirectoryCleanerTemp DisplayName DirectoryCleanerTemp
nssm set DirectoryCleanerTemp ObjectName LocalSystem nssm set DirectoryCleanerTemp ObjectName LocalSystem
nssm set DirectoryCleanerTemp Start SERVICE_AUTO_START nssm set DirectoryCleanerTemp Start SERVICE_AUTO_START