226 lines
5.5 KiB
Go
226 lines
5.5 KiB
Go
/*
|
|
|--------------------------------------------------------------------------
|
|
| Description
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Name:
|
|
| - Log
|
|
|
|
|
| Purpose:
|
|
| - Provide a framework-level logging utility that records structured
|
|
| plaintext log entries to a persistent filesystem location using a
|
|
| deterministic and platform-aware storage strategy.
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Instruction
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Guideline:
|
|
| - Use to write standardized log messages from framework services and
|
|
| software features.
|
|
| - Provide a logical source identifier using the SERVICENAME/UTILITYNAME
|
|
| or SERVICENAME/FEATURENAME format.
|
|
| - Provide the human-readable log message as plain, formatted, or any
|
|
| UTF-8 string.
|
|
| - Log entries are stored in the platform-specific persistent log
|
|
| directory using the software name as the directory name.
|
|
| - Log entries are appended as complete UTF-8 plaintext lines without
|
|
| overwriting existing content.
|
|
|
|
|
| Example:
|
|
| - ObrimLog(
|
|
| "SERVICENAME/UTILITYNAME",
|
|
| "Utility operation completed",
|
|
| )
|
|
| - ObrimLog(
|
|
| "SERVICENAME/FEATURENAME",
|
|
| "Feature execution started",
|
|
| )
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Credit
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Contributor:
|
|
| - Rajon Ahmed
|
|
| - Blockonite
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
package log
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// obrimLogSoftwareName identifies the software owning the log directory.
|
|
const obrimLogSoftwareName = "software"
|
|
|
|
// ObrimLog writes a standardized log message.
|
|
func ObrimLog(label, message string) {
|
|
obrimLogLabel, obrimLogMessage, obrimLogValid := obrimLogValidateInput(label, message)
|
|
if !obrimLogValid {
|
|
return
|
|
}
|
|
|
|
obrimLogName := obrimLogResolveName()
|
|
if obrimLogName == "" {
|
|
return
|
|
}
|
|
|
|
obrimLogDirectory, obrimLogDirectoryValid := obrimLogResolveDirectory(obrimLogName)
|
|
if !obrimLogDirectoryValid {
|
|
return
|
|
}
|
|
|
|
obrimLogFile, obrimLogFileValid := obrimLogResolveFile(obrimLogDirectory)
|
|
if !obrimLogFileValid {
|
|
return
|
|
}
|
|
|
|
obrimLogTimestamp := obrimLogGetTimestamp()
|
|
obrimLogEntry := obrimLogBuildEntry(obrimLogTimestamp, obrimLogLabel, obrimLogMessage)
|
|
|
|
obrimLogWriteEntry(obrimLogFile, obrimLogEntry)
|
|
}
|
|
|
|
// obrimLogValidateInput normalizes and validates the log input.
|
|
func obrimLogValidateInput(label, message string) (string, string, bool) {
|
|
label = strings.TrimSpace(label)
|
|
message = strings.ReplaceAll(message, "\r\n", "\n")
|
|
message = strings.ReplaceAll(message, "\r", "\n")
|
|
message = strings.ReplaceAll(message, "\n", " ")
|
|
|
|
if label == "" || message == "" {
|
|
return "", "", false
|
|
}
|
|
|
|
return label, message, true
|
|
}
|
|
|
|
// obrimLogResolveName retrieves the software name from the local constant.
|
|
func obrimLogResolveName() string {
|
|
return strings.TrimSpace(obrimLogSoftwareName)
|
|
}
|
|
|
|
// obrimLogResolveDirectory resolves and creates the platform-specific log directory.
|
|
func obrimLogResolveDirectory(softwareName string) (string, bool) {
|
|
var obrimLogDirectory string
|
|
|
|
switch runtime.GOOS {
|
|
case "linux":
|
|
obrimLogHome, obrimLogHomeError := os.UserHomeDir()
|
|
if obrimLogHomeError != nil {
|
|
return "", false
|
|
}
|
|
|
|
obrimLogDirectory = filepath.Join(
|
|
obrimLogHome,
|
|
".local",
|
|
"state",
|
|
softwareName,
|
|
"log",
|
|
"main",
|
|
)
|
|
|
|
case "windows":
|
|
obrimLogLocalAppData := strings.TrimSpace(os.Getenv("LOCALAPPDATA"))
|
|
if obrimLogLocalAppData == "" {
|
|
return "", false
|
|
}
|
|
|
|
obrimLogDirectory = filepath.Join(
|
|
obrimLogLocalAppData,
|
|
softwareName,
|
|
"log",
|
|
"main",
|
|
)
|
|
|
|
case "darwin":
|
|
obrimLogHome, obrimLogHomeError := os.UserHomeDir()
|
|
if obrimLogHomeError != nil {
|
|
return "", false
|
|
}
|
|
|
|
obrimLogDirectory = filepath.Join(
|
|
obrimLogHome,
|
|
"Library",
|
|
"Logs",
|
|
softwareName,
|
|
"log",
|
|
"main",
|
|
)
|
|
|
|
default:
|
|
return "", false
|
|
}
|
|
|
|
if obrimLogDirectory == "" {
|
|
return "", false
|
|
}
|
|
|
|
if obrimLogMkdirError := os.MkdirAll(obrimLogDirectory, 0o755); obrimLogMkdirError != nil {
|
|
return "", false
|
|
}
|
|
|
|
return obrimLogDirectory, true
|
|
}
|
|
|
|
// obrimLogResolveFile resolves and creates the main log file.
|
|
func obrimLogResolveFile(directory string) (string, bool) {
|
|
obrimLogFile := filepath.Join(directory, "main.log")
|
|
|
|
obrimLogHandle, obrimLogOpenError := os.OpenFile(
|
|
obrimLogFile,
|
|
os.O_CREATE|os.O_APPEND|os.O_WRONLY,
|
|
0o644,
|
|
)
|
|
if obrimLogOpenError != nil {
|
|
return "", false
|
|
}
|
|
|
|
if obrimLogCloseError := obrimLogHandle.Close(); obrimLogCloseError != nil {
|
|
return "", false
|
|
}
|
|
|
|
return obrimLogFile, true
|
|
}
|
|
|
|
// obrimLogGetTimestamp gets the timestamp for a log entry.
|
|
func obrimLogGetTimestamp() string {
|
|
return time.Now().Format(time.RFC3339Nano)
|
|
}
|
|
|
|
// obrimLogBuildEntry builds a complete formatted log entry.
|
|
func obrimLogBuildEntry(timestamp, label, message string) string {
|
|
return "[" + timestamp + "] [" + label + "] " + message + "\n"
|
|
}
|
|
|
|
// obrimLogWriteEntry appends a complete log entry to the log file.
|
|
func obrimLogWriteEntry(file, entry string) {
|
|
obrimLogHandle, obrimLogOpenError := os.OpenFile(
|
|
file,
|
|
os.O_APPEND|os.O_WRONLY,
|
|
0o644,
|
|
)
|
|
if obrimLogOpenError != nil {
|
|
return
|
|
}
|
|
defer obrimLogHandle.Close()
|
|
|
|
_, _ = obrimLogHandle.WriteString(entry)
|
|
}
|