260 lines
5.3 KiB
Go
260 lines
5.3 KiB
Go
/*
|
|
|--------------------------------------------------------------------------
|
|
| Metadata
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Name:
|
|
| - Log
|
|
|
|
|
| Purpose:
|
|
| - Provide framework-level structured logging capabilities.
|
|
| - Persist plaintext log entries using a deterministic and platform-aware storage strategy.
|
|
| - Enable reusable logging functionality for framework and software components.
|
|
|
|
|
| Guideline:
|
|
| - Use ObrimLog() to write structured log entries.
|
|
| - Use labels in the format SERVICENAME/UTILITYNAME or SERVICENAME/FEATURENAME.
|
|
| - Use human-readable messages suitable for operational diagnostics and tracing.
|
|
| - Allow the utility to manage log file creation and storage path resolution.
|
|
| - Use append-only logging to preserve historical log records.
|
|
|
|
|
| Example:
|
|
| - ObrimLog("SYSTEM/LOG", "Log utility initialized.")
|
|
| - ObrimLog("PROJECT/CREATE", "Project created successfully.")
|
|
| - ObrimLog("USER/AUTHENTICATION", "User authentication completed.")
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Credit
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Contributor:
|
|
| - Rajon Ahmed
|
|
| - Blockonite
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
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,
|
|
)
|
|
}
|