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

260 lines
5.1 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 application 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) {
applicationName := obrimLogApplicationResolve()
timestamp := obrimLogTimestampGenerate()
entry := obrimLogEntryBuild(
timestamp,
label,
message,
)
logDirectory := obrimLogDirectoryResolve(applicationName)
logFile := obrimLogFileResolve(
logDirectory,
applicationName,
)
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,
)
}
// obrimLogApplicationResolve resolves the application name.
func obrimLogApplicationResolve() string {
value := retriever.ObrimRetriever(
"json",
map[string]any{
"resource": "application/metadata",
"path": "application.lower",
},
)
name := strings.TrimSpace(fmt.Sprintf("%v", value))
if name == "" {
return "application"
}
return name
}
// obrimLogDirectoryResolve resolves platform-specific log directory paths.
func obrimLogDirectoryResolve(applicationName string) string {
switch runtime.GOOS {
case "windows":
return obrimLogDirectoryResolveWindows(applicationName)
case "darwin":
return obrimLogDirectoryResolveMacOS(applicationName)
default:
return obrimLogDirectoryResolveLinux(applicationName)
}
}
// obrimLogDirectoryResolveLinux resolves Linux log directory paths.
func obrimLogDirectoryResolveLinux(applicationName string) string {
xdgStateHome := strings.TrimSpace(os.Getenv("XDG_STATE_HOME"))
if xdgStateHome != "" {
return filepath.Join(
xdgStateHome,
"."+applicationName,
"logs",
)
}
homeDirectory, errorValue := os.UserHomeDir()
if errorValue != nil {
return filepath.Join(
".",
"."+applicationName,
"logs",
)
}
return filepath.Join(
homeDirectory,
".local",
"state",
"."+applicationName,
"logs",
)
}
// obrimLogDirectoryResolveWindows resolves Windows log directory paths.
func obrimLogDirectoryResolveWindows(applicationName string) string {
localApplicationData := strings.TrimSpace(
os.Getenv("LOCALAPPDATA"),
)
if localApplicationData == "" {
homeDirectory, errorValue := os.UserHomeDir()
if errorValue == nil {
localApplicationData = homeDirectory
}
}
return filepath.Join(
localApplicationData,
applicationName,
"Logs",
)
}
// obrimLogDirectoryResolveMacOS resolves macOS log directory paths.
func obrimLogDirectoryResolveMacOS(applicationName string) string {
homeDirectory, errorValue := os.UserHomeDir()
if errorValue != nil {
return filepath.Join(
".",
"."+applicationName,
)
}
return filepath.Join(
homeDirectory,
"Library",
"Logs",
"."+applicationName,
)
}
// obrimLogFileResolve resolves platform-specific log file paths.
func obrimLogFileResolve(
logDirectory string,
applicationName string,
) string {
return filepath.Join(
logDirectory,
applicationName+".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)
}