package log import ( "fmt" "os" "path/filepath" "runtime" "strings" "time" ) const ( obrimLogSoftwareName = "softwarelower" obrimLogFileExtension = ".log" ) // ObrimLog writes a structured log entry. func ObrimLog(label string, message string) { softwareName := obrimLogSoftwareNameResolve() if softwareName == "" { return } entry := obrimLogEntryBuild( obrimLogTimestampGenerate(), label, message, ) filePath := obrimLogFileResolve(softwareName) if filePath == "" { return } if err := obrimLogFileEnsure(filePath); err != nil { return } _ = obrimLogWrite(filePath, entry) } // obrimLogSoftwareNameResolve resolves the software name from a local variable. func obrimLogSoftwareNameResolve() string { return strings.TrimSpace(obrimLogSoftwareName) } // obrimLogTimestampGenerate generates deterministic timestamps. func obrimLogTimestampGenerate() string { return time.Now().UTC().Format(time.RFC3339) } // obrimLogEntryBuild constructs formatted log entries. func obrimLogEntryBuild( timestamp string, label string, message string, ) string { return fmt.Sprintf( "[%s] [%s] %s\n", strings.TrimSpace(timestamp), strings.TrimSpace(label), strings.TrimSpace(message), ) } // obrimLogDirectoryResolve resolves platform-specific log directory paths. func obrimLogDirectoryResolve( softwareName string, ) string { switch runtime.GOOS { case "linux": return obrimLogDirectoryResolveLinux(softwareName) case "windows": return obrimLogDirectoryResolveWindows(softwareName) case "darwin": return obrimLogDirectoryResolveMacOS(softwareName) default: return "" } } // obrimLogFileResolve resolves platform-specific log file paths. func obrimLogFileResolve( softwareName string, ) string { directoryPath := obrimLogDirectoryResolve(softwareName) if directoryPath == "" { return "" } return filepath.Join( directoryPath, softwareName+obrimLogFileExtension, ) } // obrimLogFileEnsure creates and verifies required log directories and files. func obrimLogFileEnsure( filePath string, ) error { directoryPath := filepath.Dir(filePath) if err := os.MkdirAll(directoryPath, 0o755); err != nil { return err } file, err := os.OpenFile( filePath, os.O_CREATE, 0o644, ) if err != nil { return err } return file.Close() } // obrimLogWrite persists log entries to the filesystem. func obrimLogWrite( filePath string, entry string, ) error { file, err := os.OpenFile( filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644, ) if err != nil { return err } defer file.Close() _, err = file.WriteString(entry) return err } // obrimLogDirectoryResolveLinux resolves Linux log directory paths. func obrimLogDirectoryResolveLinux( softwareName string, ) string { // Mutable XDG state home environment variable. var xdgStateHome = strings.TrimSpace( os.Getenv("XDG_STATE_HOME"), ) if xdgStateHome != "" { return filepath.Join( xdgStateHome, "."+softwareName, "logs", ) } // Mutable user home directory. var homeDirectory string userHomeDirectory, err := os.UserHomeDir() if err != nil { return "" } homeDirectory = userHomeDirectory return filepath.Join( homeDirectory, ".local", "state", "."+softwareName, "logs", ) } // obrimLogDirectoryResolveWindows resolves Windows log directory paths. func obrimLogDirectoryResolveWindows( softwareName string, ) string { // Mutable LOCALAPPDATA environment variable. var localAppData = strings.TrimSpace( os.Getenv("LOCALAPPDATA"), ) if localAppData == "" { return "" } return filepath.Join( localAppData, softwareName, "Logs", ) } // obrimLogDirectoryResolveMacOS resolves macOS log directory paths. func obrimLogDirectoryResolveMacOS( softwareName string, ) string { // Mutable user home directory. var homeDirectory string userHomeDirectory, err := os.UserHomeDir() if err != nil { return "" } homeDirectory = userHomeDirectory return filepath.Join( homeDirectory, "Library", "Logs", "."+softwareName, ) }