obrimbasecli/essential/visible/service/helper/log/log.go

260 lines
5.0 KiB
Go

/*
|--------------------------------------------------------------------------
| Manifest
|--------------------------------------------------------------------------
|
| Name:
| - Log
|
| Purpose:
| - Provide framework-level structured plaintext logging with
| deterministic timestamping and persistent platform-aware storage.
|
| Guideline:
| - Use for framework and software logging.
| - Writes append-only UTF-8 log entries.
| - Preserves existing log content.
| - Uses software metadata to determine storage location.
| - Does not implement rotation, retention, archival, or compression.
|
| Example:
| - ObrimLog("SERVICE/FEATURE", "Operation completed.")
| - ObrimLog("HELPER/LOG", "Log initialized.")
|
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Credit
|--------------------------------------------------------------------------
|
| Contributor:
| - Rajon Ahmed
| - Scionite
|
|--------------------------------------------------------------------------
*/
package log
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"go/module/essential/visible/service/helper/retriever"
)
// ObrimLog writes a structured log entry.
func ObrimLog(label string, message string) {
softwareName := obrimLogSoftwareResolve()
timestamp := obrimLogTimestampGenerate()
entry := obrimLogEntryBuild(
timestamp,
label,
message,
)
logDirectory := obrimLogDirectoryResolve(softwareName)
logFile := obrimLogFileResolve(
logDirectory,
softwareName,
)
if !obrimLogFileEnsure(logDirectory, logFile) {
return
}
obrimLogWrite(logFile, entry)
}
// 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",
timestamp,
label,
message,
)
}
// obrimLogSoftwareResolve resolves the software name.
func obrimLogSoftwareResolve() string {
value := retriever.ObrimRetriever(
"json",
map[string]any{
"resource": "software/metadata",
"path": "software.lower",
},
)
name := strings.TrimSpace(fmt.Sprintf("%v", value))
if name == "" {
return "software"
}
return name
}
// obrimLogDirectoryResolve resolves platform-specific log directory paths.
func obrimLogDirectoryResolve(softwareName string) string {
switch runtime.GOOS {
case "windows":
return obrimLogDirectoryResolveWindows(softwareName)
case "darwin":
return obrimLogDirectoryResolveMacOS(softwareName)
default:
return obrimLogDirectoryResolveLinux(softwareName)
}
}
// obrimLogDirectoryResolveLinux resolves Linux log directory paths.
func obrimLogDirectoryResolveLinux(softwareName string) string {
xdgStateHome := strings.TrimSpace(os.Getenv("XDG_STATE_HOME"))
if xdgStateHome != "" {
return filepath.Join(
xdgStateHome,
"."+softwareName,
"logs",
)
}
homeDirectory, errorValue := os.UserHomeDir()
if errorValue != nil {
return filepath.Join(
".",
"."+softwareName,
"logs",
)
}
return filepath.Join(
homeDirectory,
".local",
"state",
"."+softwareName,
"logs",
)
}
// obrimLogDirectoryResolveWindows resolves Windows log directory paths.
func obrimLogDirectoryResolveWindows(softwareName string) string {
localSoftwareData := strings.TrimSpace(
os.Getenv("LOCALAPPDATA"),
)
if localSoftwareData == "" {
homeDirectory, errorValue := os.UserHomeDir()
if errorValue == nil {
localSoftwareData = homeDirectory
}
}
return filepath.Join(
localSoftwareData,
softwareName,
"Logs",
)
}
// obrimLogDirectoryResolveMacOS resolves macOS log directory paths.
func obrimLogDirectoryResolveMacOS(softwareName string) string {
homeDirectory, errorValue := os.UserHomeDir()
if errorValue != nil {
return filepath.Join(
".",
"."+softwareName,
)
}
return filepath.Join(
homeDirectory,
"Library",
"Logs",
"."+softwareName,
)
}
// obrimLogFileResolve resolves platform-specific log file paths.
func obrimLogFileResolve(
logDirectory string,
softwareName string,
) string {
return filepath.Join(
logDirectory,
softwareName+".log",
)
}
// obrimLogFileEnsure creates and verifies required log directories and files.
func obrimLogFileEnsure(
logDirectory string,
logFile string,
) bool {
errorValue := os.MkdirAll(
logDirectory,
0755,
)
if errorValue != nil {
return false
}
fileHandle, errorValue := os.OpenFile(
logFile,
os.O_CREATE,
0644,
)
if errorValue != nil {
return false
}
_ = fileHandle.Close()
return true
}
// obrimLogWrite persists log entries to the filesystem.
func obrimLogWrite(
logFile string,
entry string,
) {
fileHandle, errorValue := os.OpenFile(
logFile,
os.O_CREATE|os.O_WRONLY|os.O_APPEND,
0644,
)
if errorValue != nil {
return
}
defer fileHandle.Close()
_, _ = fileHandle.WriteString(entry)
}