Added exixting files
This commit is contained in:
parent
55bb9d4560
commit
e509b1ddad
149
console-log.go
Normal file
149
console-log.go
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// console-log.go
|
||||||
|
package logimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"portale-stac.it/packages/logger"
|
||||||
|
"portale-stac.it/packages/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Implementation specific properties
|
||||||
|
const (
|
||||||
|
CONSOLE_LOG_VERBOSE_ENABLE = iota + FULL_LOGGER_DERIVED_BASE_ID
|
||||||
|
CONSOLE_LOG_TTY // read-only
|
||||||
|
CONSOLE_LOG_DERIVED_BASE_ID
|
||||||
|
)
|
||||||
|
|
||||||
|
type consoleLog struct {
|
||||||
|
logImpl
|
||||||
|
TTY utils.TTYContext
|
||||||
|
verboseEnabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConsoleLog(filePath string, maxLevel int) logger.VerboseLogger {
|
||||||
|
log := &consoleLog{
|
||||||
|
logImpl: logImpl{},
|
||||||
|
verboseEnabled: true,
|
||||||
|
}
|
||||||
|
log.logImpl.initLogger(filePath, maxLevel, true)
|
||||||
|
log.TTY.Init()
|
||||||
|
return log
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) SetProperty(propertyId int, value any) (success bool) {
|
||||||
|
var boolValue bool
|
||||||
|
|
||||||
|
switch propertyId {
|
||||||
|
case CONSOLE_LOG_VERBOSE_ENABLE:
|
||||||
|
if boolValue, success = value.(bool); success {
|
||||||
|
log.verboseEnabled = boolValue
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
success = log.logImpl.SetProperty(propertyId, value)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) GetProperty(propertyId int) (value any) {
|
||||||
|
switch propertyId {
|
||||||
|
case CONSOLE_LOG_VERBOSE_ENABLE:
|
||||||
|
value = log.verboseEnabled
|
||||||
|
case CONSOLE_LOG_TTY:
|
||||||
|
value = &log.TTY
|
||||||
|
default:
|
||||||
|
value = log.logImpl.GetProperty(propertyId)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) Msgf(color uint, templ string, args ...any) {
|
||||||
|
if log.TTY.IsTTY(utils.STDERR) {
|
||||||
|
var extTempl string
|
||||||
|
if color != utils.NONE {
|
||||||
|
c := log.TTY.FgColor(utils.STDERR, color)
|
||||||
|
extTempl = c + templ + log.TTY.Reset(utils.STDERR)
|
||||||
|
}
|
||||||
|
if len(extTempl) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, extTempl+"\n", args...)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stderr, templ+"\n", args...)
|
||||||
|
// os.Stderr.Sync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) MsgItalicf(color uint, templ string, args ...any) {
|
||||||
|
var extTempl string
|
||||||
|
if log.TTY.IsTTY(utils.STDERR) {
|
||||||
|
if color != utils.NONE {
|
||||||
|
c := log.TTY.FgColor(utils.STDERR, color)
|
||||||
|
extTempl = c + log.TTY.Italic(utils.STDERR) + templ + log.TTY.Reset(utils.STDERR)
|
||||||
|
} else {
|
||||||
|
extTempl = log.TTY.Italic(utils.STDERR) + templ + log.TTY.Reset(utils.STDERR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(extTempl) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, extTempl+"\n", args...)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stderr, templ+"\n", args...)
|
||||||
|
// os.Stderr.Sync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) Alertf(prefix string, upstack int, templ string, args ...any) (text string) {
|
||||||
|
var extTempl string
|
||||||
|
if log.TTY.IsTTY(utils.STDERR) {
|
||||||
|
var color string = log.TTY.RedFg(utils.STDERR)
|
||||||
|
|
||||||
|
if prefix == "" {
|
||||||
|
extTempl = color + templ + log.TTY.Reset(utils.STDERR)
|
||||||
|
} else {
|
||||||
|
extTempl = color + log.TTY.Bold(utils.STDERR) + prefix + log.TTY.BoldOff(utils.STDERR) + templ + log.TTY.Reset(utils.STDERR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(extTempl) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, extTempl+"\n", args...)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stderr, templ+"\n", args...)
|
||||||
|
// os.Stderr.Sync()
|
||||||
|
}
|
||||||
|
text = log.logImpl.Logf(LOG_ERROR, 1+upstack, templ, args...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) Verbosef(color uint, templ string, args ...any) string {
|
||||||
|
if log.verboseEnabled {
|
||||||
|
log.Msgf(color, templ, args...)
|
||||||
|
}
|
||||||
|
return log.Logf(LOG_INFO, 2, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) VerboseItalicf(color uint, templ string, args ...any) string {
|
||||||
|
if log.verboseEnabled {
|
||||||
|
log.MsgItalicf(color, templ, args...)
|
||||||
|
}
|
||||||
|
return log.Logf(LOG_INFO, 2, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) VerboseNoColorf(templ string, args ...any) string {
|
||||||
|
return log.Verbosef(utils.NONE, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) VerboseRedf(templ string, args ...any) string {
|
||||||
|
return log.Verbosef(utils.RED, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) VerboseGreenf(templ string, args ...any) string {
|
||||||
|
return log.Verbosef(utils.GREEN, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) VerboseBluef(templ string, args ...any) string {
|
||||||
|
return log.Verbosef(utils.BLUE, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *consoleLog) VerboseBrownf(templ string, args ...any) string {
|
||||||
|
return log.VerboseItalicf(utils.BROWN, templ, args...)
|
||||||
|
}
|
57
contextual-log.go
Normal file
57
contextual-log.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// contextual-log.go
|
||||||
|
package logimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"portale-stac.it/packages/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ContextualLog struct {
|
||||||
|
log logger.FullLogger
|
||||||
|
tag string
|
||||||
|
baseStackOffset int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clog ContextualLog) Init(log logger.FullLogger, template string, args ...any) {
|
||||||
|
clog.log = log
|
||||||
|
clog.tag = fmt.Sprintf(template, args...)
|
||||||
|
clog.baseStackOffset, _ = log.GetProperty(FULL_LOGGER_STACK_OFFSET).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCtxLog(log logger.FullLogger, template string, args ...any) (clog *ContextualLog) {
|
||||||
|
offset, _ := log.GetProperty(FULL_LOGGER_STACK_OFFSET).(int)
|
||||||
|
return &ContextualLog{
|
||||||
|
log: log,
|
||||||
|
tag: fmt.Sprintf(template, args...),
|
||||||
|
baseStackOffset: offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clog *ContextualLog) Logger() logger.FullLogger {
|
||||||
|
return clog.log
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clog *ContextualLog) Debugf(templ string, args ...any) {
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset+1)
|
||||||
|
clog.log.Debugf(clog.tag+templ, args...)
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clog *ContextualLog) Infof(templ string, args ...any) {
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset+1)
|
||||||
|
clog.log.Infof(clog.tag+templ, args...)
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clog *ContextualLog) Warnf(templ string, args ...any) {
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset+1)
|
||||||
|
clog.log.Warnf(clog.tag+templ, args...)
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clog *ContextualLog) Errorf(templ string, args ...any) {
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset+1)
|
||||||
|
clog.log.Errorf(clog.tag+templ, args...)
|
||||||
|
clog.log.SetProperty(FULL_LOGGER_STACK_OFFSET, clog.baseStackOffset)
|
||||||
|
}
|
17
go.mod
Normal file
17
go.mod
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module portale-stac.it/packages/logimpl
|
||||||
|
|
||||||
|
go 1.21.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
portale-stac.it/packages/golang v0.0.0
|
||||||
|
portale-stac.it/packages/logger v0.0.0
|
||||||
|
portale-stac.it/packages/utils v0.0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require golang.org/x/text v0.3.7 // indirect
|
||||||
|
|
||||||
|
replace (
|
||||||
|
portale-stac.it/packages/golang => ../golang
|
||||||
|
portale-stac.it/packages/logger => ../logger
|
||||||
|
portale-stac.it/packages/utils => ../utils
|
||||||
|
)
|
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
447
logimpl.go
Normal file
447
logimpl.go
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
// logimpl.go
|
||||||
|
package logimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"portale-stac.it/packages/golang"
|
||||||
|
"portale-stac.it/packages/logger"
|
||||||
|
"portale-stac.it/packages/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Implementation specific properties
|
||||||
|
const (
|
||||||
|
// Max log file size that triggers the log rotation process
|
||||||
|
// Rotation-Size == 0 means no rotation at all
|
||||||
|
FULL_LOGGER_ROTATION_SIZE = int(iota + logger.IMPLEMENTATION_PROPERTY_BASE_ID)
|
||||||
|
|
||||||
|
// Number of most recent files to keep
|
||||||
|
FULL_LOGGER_RETENTION_NUMBER
|
||||||
|
|
||||||
|
// Calling function offset in the process call stack
|
||||||
|
FULL_LOGGER_STACK_OFFSET
|
||||||
|
|
||||||
|
// Enable raw data dump into log file. See Dumpf() function.
|
||||||
|
FULL_LOGGER_DUMPER_ENABLED
|
||||||
|
|
||||||
|
// ATTENTION: Add new property id above this line
|
||||||
|
FULL_LOGGER_DERIVED_BASE_ID
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log levels
|
||||||
|
const (
|
||||||
|
LOG_NOLOG = int(iota) - 1
|
||||||
|
LOG_OOB
|
||||||
|
LOG_FATAL
|
||||||
|
LOG_ERROR
|
||||||
|
LOG_WARN
|
||||||
|
LOG_INFO
|
||||||
|
LOG_DEBUG
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MIN_LOG_ROTATE_SIZE = int64(5000)
|
||||||
|
LOG_NO_SIZE_LIMIT = int64(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
oobOffset = 1000
|
||||||
|
defaultMaxMessageLength = 1024
|
||||||
|
baseStackOffset = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var LOG_CLASS_COLOR = []uint{utils.BLACK, utils.RED, utils.RED, utils.MAGENTA, utils.BROWN, utils.CYAN}
|
||||||
|
var logClassLabel = []string{"OOB", "FATAL", "ERROR", "WARN", "INFO", "DEBUG"}
|
||||||
|
|
||||||
|
type logImpl struct {
|
||||||
|
// TTY utils.TTYContext
|
||||||
|
appendMode bool
|
||||||
|
enabled bool //Variabile di controllo per bloccare la creazione del log prima che i suoi parametri siano acquisiti
|
||||||
|
filePath string
|
||||||
|
flags int
|
||||||
|
rotateNumber int
|
||||||
|
maxSize int64
|
||||||
|
size int64
|
||||||
|
stream *os.File
|
||||||
|
maxLevel int
|
||||||
|
debugOnStderr bool
|
||||||
|
maxMessageLength int
|
||||||
|
stackOffset int
|
||||||
|
dumperEnabled bool
|
||||||
|
customProperties map[int]any
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAppendLogger(fileName string, maxLevel int) logger.FullLogger {
|
||||||
|
return newLogger(fileName, maxLevel, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(fileName string, maxLevel int) logger.FullLogger {
|
||||||
|
return newLogger(fileName, maxLevel, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLogger(filePath string, maxLevel int, appendMode bool) logger.FullLogger {
|
||||||
|
return (&logImpl{}).initLogger(filePath, maxLevel, appendMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) initLogger(filePath string, maxLevel int, appendMode bool) *logImpl {
|
||||||
|
log.filePath = filePath
|
||||||
|
log.maxSize = LOG_NO_SIZE_LIMIT
|
||||||
|
log.size = 0
|
||||||
|
log.stream = nil
|
||||||
|
log.maxLevel = maxLevel
|
||||||
|
log.appendMode = appendMode
|
||||||
|
log.maxMessageLength = defaultMaxMessageLength
|
||||||
|
log.stackOffset = baseStackOffset
|
||||||
|
log.dumperEnabled = false
|
||||||
|
log.customProperties = make(map[int]any)
|
||||||
|
// log.TTY.Init()
|
||||||
|
return log
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) SetProperty(propertyId int, value any) (success bool) {
|
||||||
|
var intValue int
|
||||||
|
var int64Value int64
|
||||||
|
var boolValue bool
|
||||||
|
|
||||||
|
switch propertyId {
|
||||||
|
case FULL_LOGGER_STACK_OFFSET:
|
||||||
|
if intValue, success = value.(int); success {
|
||||||
|
if intValue < baseStackOffset {
|
||||||
|
intValue = baseStackOffset
|
||||||
|
success = false
|
||||||
|
}
|
||||||
|
log.stackOffset = intValue
|
||||||
|
}
|
||||||
|
case logger.LOGGER_MAX_MESSAGE_LENGTH:
|
||||||
|
if intValue, success = value.(int); success {
|
||||||
|
log.maxMessageLength = intValue
|
||||||
|
}
|
||||||
|
case FULL_LOGGER_ROTATION_SIZE:
|
||||||
|
if int64Value, success = value.(int64); success {
|
||||||
|
log.maxSize = int64Value
|
||||||
|
}
|
||||||
|
case FULL_LOGGER_RETENTION_NUMBER:
|
||||||
|
if intValue, success = value.(int); success {
|
||||||
|
log.rotateNumber = intValue
|
||||||
|
}
|
||||||
|
case FULL_LOGGER_DUMPER_ENABLED:
|
||||||
|
if boolValue, success = value.(bool); success {
|
||||||
|
log.dumperEnabled = boolValue
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.customProperties[propertyId] = value
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) GetProperty(propertyId int) (value any) {
|
||||||
|
switch propertyId {
|
||||||
|
case FULL_LOGGER_STACK_OFFSET:
|
||||||
|
value = log.stackOffset
|
||||||
|
case logger.LOGGER_MAX_MESSAGE_LENGTH:
|
||||||
|
value = log.maxMessageLength
|
||||||
|
case FULL_LOGGER_ROTATION_SIZE:
|
||||||
|
value = log.maxSize
|
||||||
|
case FULL_LOGGER_RETENTION_NUMBER:
|
||||||
|
value = log.rotateNumber
|
||||||
|
default:
|
||||||
|
if v, ok := log.customProperties[propertyId]; ok {
|
||||||
|
value = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) GetPropertyBool(propertyId int) (value bool, ok bool) {
|
||||||
|
if rawValue := log.GetProperty(propertyId); rawValue != nil {
|
||||||
|
value, ok = rawValue.(bool)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Finalize() {
|
||||||
|
if log.stream != nil {
|
||||||
|
log.stream.Sync()
|
||||||
|
log.stream = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Label2Level(label string) (level int, found bool) {
|
||||||
|
label = strings.ToUpper(label)
|
||||||
|
for i, lab := range logClassLabel {
|
||||||
|
if lab == label {
|
||||||
|
level = i
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func LogClassLabel(level int) (label string) {
|
||||||
|
if level >= 0 && level < len(logClassLabel) {
|
||||||
|
label = logClassLabel[level]
|
||||||
|
} else {
|
||||||
|
label = "unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) SetRotation(maxSize int64, rotateNumber int) {
|
||||||
|
log.maxSize = maxSize
|
||||||
|
log.rotateNumber = rotateNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Logf(logClass int, upStack int, templ string, args ...any) (text string) {
|
||||||
|
if logClass >= oobOffset {
|
||||||
|
logClass = logClass - oobOffset
|
||||||
|
} else if logClass > log.maxLevel {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stream := log.getLog()
|
||||||
|
if stream != nil {
|
||||||
|
source, line, _ := golang.Trace(upStack + log.stackOffset)
|
||||||
|
now := time.Now()
|
||||||
|
// stamp := now.Format("2006-01-02 15:04:05.999")
|
||||||
|
stamp := now.Format("2006-01-02 15:04:05")
|
||||||
|
// label := logimpl.LOG_CLASS_LABEL[logClass]
|
||||||
|
label := LogClassLabel(logClass)
|
||||||
|
header := fmt.Sprintf("%v [%-5s] %s::%d -- ", stamp, label, path.Base(source), line)
|
||||||
|
// templ = header + templ
|
||||||
|
msg := fmt.Sprintf(templ, args...)
|
||||||
|
text = msg
|
||||||
|
msgLen := len(msg) + len(header) + 1
|
||||||
|
if msgLen > log.maxMessageLength {
|
||||||
|
msg = msg[0 : log.maxMessageLength-len(header)-1]
|
||||||
|
msgLen = len(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotazione
|
||||||
|
log.rotateLogFiles(msgLen)
|
||||||
|
|
||||||
|
n, _ := log.stream.WriteString(header)
|
||||||
|
n, _ = log.stream.WriteString(msg)
|
||||||
|
log.stream.Write([]byte{'\n'})
|
||||||
|
log.size += int64(n)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Rawb(logClass int, msg []byte) {
|
||||||
|
if logClass >= oobOffset {
|
||||||
|
logClass = logClass - oobOffset
|
||||||
|
} else if logClass > log.maxLevel {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stream := log.getLog()
|
||||||
|
if stream != nil {
|
||||||
|
msgLen := len(msg)
|
||||||
|
|
||||||
|
// Rotazione
|
||||||
|
log.rotateLogFiles(msgLen)
|
||||||
|
|
||||||
|
n, _ := log.stream.Write(msg)
|
||||||
|
log.size += int64(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Rawf(logClass int, templ string, args ...any) {
|
||||||
|
if logClass >= oobOffset {
|
||||||
|
logClass = logClass - oobOffset
|
||||||
|
} else if logClass > log.maxLevel {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stream := log.getLog()
|
||||||
|
if stream != nil {
|
||||||
|
msg := fmt.Sprintf(templ, args...)
|
||||||
|
msgLen := len(msg)
|
||||||
|
|
||||||
|
// Rotazione
|
||||||
|
log.rotateLogFiles(msgLen)
|
||||||
|
|
||||||
|
n, _ := log.stream.Write([]byte(msg))
|
||||||
|
log.size += int64(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Dumpf(data []byte, perm fs.FileMode, templ string, args ...any) (dumpFilePath string) {
|
||||||
|
if log.dumperEnabled {
|
||||||
|
dirPath := path.Dir(log.filePath)
|
||||||
|
dumpFilePath = path.Join(dirPath, fmt.Sprintf(templ, args...))
|
||||||
|
os.WriteFile(dumpFilePath, data, perm)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) OobLogf(templ string, args ...any) {
|
||||||
|
log.Logf(oobOffset, 1, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) IsDebugEnabled() bool {
|
||||||
|
return log.maxLevel >= LOG_DEBUG
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) IsInfoEnabled() bool {
|
||||||
|
return log.maxLevel >= LOG_INFO
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Debugf(templ string, args ...any) {
|
||||||
|
// Se la variabile d'ambiente <prefix>_DEBUG è impostata
|
||||||
|
// i messaggi di debug sono mostrati anche su stderr
|
||||||
|
if log.debugOnStderr {
|
||||||
|
// var extTempl string
|
||||||
|
|
||||||
|
source, line, _ := golang.Trace(3)
|
||||||
|
header := fmt.Sprintf("[%5s] %s::%d -- ", logClassLabel[LOG_DEBUG], path.Base(source), line)
|
||||||
|
// fd := uint(os.Stderr.Fd())
|
||||||
|
// if log.TTY.IsTTY(fd) {
|
||||||
|
// c := log.TTY.FgColor(fd, utils.CYAN)
|
||||||
|
// extTempl = c + header + templ + log.TTY.Reset(fd) + "\n"
|
||||||
|
// } else {
|
||||||
|
// extTempl = header + templ + "\n"
|
||||||
|
// }
|
||||||
|
extTempl := header + templ + "\n"
|
||||||
|
|
||||||
|
fmt.Fprintf(os.Stderr, extTempl, args...)
|
||||||
|
}
|
||||||
|
log.Logf(LOG_DEBUG, 1, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) DebugRawb(msg []byte) {
|
||||||
|
// Se la variabile d'ambiente <prefix>_DEBUG è impostata
|
||||||
|
// i messaggi di debug sono mostrati anche su stderr
|
||||||
|
if log.debugOnStderr {
|
||||||
|
os.Stderr.Write(msg)
|
||||||
|
}
|
||||||
|
log.Rawb(LOG_DEBUG, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) DebugRawf(templ string, args ...any) {
|
||||||
|
// Se la variabile d'ambiente <prefix>_DEBUG è impostata
|
||||||
|
// i messaggi di debug sono mostrati anche su stderr
|
||||||
|
if log.debugOnStderr {
|
||||||
|
fmt.Fprintf(os.Stderr, templ, args...)
|
||||||
|
}
|
||||||
|
log.Rawf(LOG_DEBUG, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Infof(templ string, args ...any) {
|
||||||
|
log.Logf(LOG_INFO, 1, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) InfoRawf(templ string, args ...any) {
|
||||||
|
log.Rawf(LOG_INFO, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Warnf(templ string, args ...any) {
|
||||||
|
log.Logf(LOG_WARN, 1, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) WarnRawf(templ string, args ...any) {
|
||||||
|
log.Rawf(LOG_WARN, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) Errorf(templ string, args ...any) {
|
||||||
|
log.Logf(LOG_ERROR, 1, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) ErrorRawf(templ string, args ...any) {
|
||||||
|
log.Rawf(LOG_ERROR, templ, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) getLog() *os.File {
|
||||||
|
if log.maxLevel == LOG_OOB {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if log.stream == nil && len(log.filePath) > 0 {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
log.flags = os.O_CREATE | os.O_RDWR
|
||||||
|
if log.appendMode {
|
||||||
|
log.flags |= os.O_APPEND
|
||||||
|
} else {
|
||||||
|
log.flags |= os.O_TRUNC
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = utils.MakeParentDir(log.filePath); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.stream, err = os.OpenFile(log.filePath, log.flags, 0644)
|
||||||
|
if err == nil {
|
||||||
|
log.size = utils.FileSize(log.filePath)
|
||||||
|
// self.Logf(1000+LOG_INFO, 0, VERSION)
|
||||||
|
} else {
|
||||||
|
utils.ExitErrorf(1, "Can't open log file %#v: %v", log.filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.reduceLogStock()
|
||||||
|
}
|
||||||
|
return log.stream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) rotateLogFiles(msgLen int) {
|
||||||
|
|
||||||
|
if log.maxSize != LOG_NO_SIZE_LIMIT && (log.size+int64(msgLen)) >= log.maxSize {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Rotazione
|
||||||
|
now := time.Now()
|
||||||
|
stamp := now.Format("2006-01-02_15-04-05")
|
||||||
|
rotFile := log.filePath + "." + stamp
|
||||||
|
_, err = utils.MoveFile(log.filePath, rotFile)
|
||||||
|
if err != nil {
|
||||||
|
utils.ExitErrorf(1, "Unable to rotate current log file: %v", err)
|
||||||
|
}
|
||||||
|
log.stream, err = os.OpenFile(log.filePath, log.flags, 0644)
|
||||||
|
if err != nil {
|
||||||
|
utils.ExitErrorf(1, "Can't open log file %#v after rotation: %v", log.filePath, err)
|
||||||
|
}
|
||||||
|
log.size = 0
|
||||||
|
|
||||||
|
// Sfoltimento
|
||||||
|
log.reduceLogStock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (log *logImpl) reduceLogStock() {
|
||||||
|
if log.rotateNumber > 0 {
|
||||||
|
dirPath := path.Dir(log.filePath)
|
||||||
|
logName := path.Base(log.filePath)
|
||||||
|
entries, err := os.ReadDir(dirPath)
|
||||||
|
if err != nil {
|
||||||
|
utils.ExitErrorf(1, "Can't read program's log directory %#v: %v", dirPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logFiles := make([]string, 0)
|
||||||
|
rotatedNameSize := len(logName) + 20
|
||||||
|
for _, e := range entries {
|
||||||
|
if !e.IsDir() {
|
||||||
|
name := e.Name()
|
||||||
|
if len(name) == rotatedNameSize && strings.HasPrefix(name, logName) {
|
||||||
|
logFiles = append(logFiles, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.Sort(logFiles)
|
||||||
|
remainingRotatedCount := len(logFiles)
|
||||||
|
if remainingRotatedCount > log.rotateNumber {
|
||||||
|
for i := 0; i < len(logFiles) && remainingRotatedCount > log.rotateNumber; i++ {
|
||||||
|
filePath := path.Join(dirPath, logFiles[i])
|
||||||
|
os.Remove(filePath)
|
||||||
|
remainingRotatedCount--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
report.go
Normal file
105
report.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// report.go
|
||||||
|
package logimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"portale-stac.it/packages/logger"
|
||||||
|
"portale-stac.it/packages/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Report params
|
||||||
|
const (
|
||||||
|
DOT_PAD = "."
|
||||||
|
VALUE_TEMPL = ": %#v"
|
||||||
|
NAME_FIELD_SIZE = 30
|
||||||
|
TOTAL_FIELD_SIZE = 34
|
||||||
|
)
|
||||||
|
|
||||||
|
type Report struct {
|
||||||
|
pad string
|
||||||
|
valueTempl string
|
||||||
|
nameFieldSize int
|
||||||
|
totalFieldSize int
|
||||||
|
log logger.VerboseLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReport(log logger.VerboseLogger) (report *Report) {
|
||||||
|
report = &Report{
|
||||||
|
pad: DOT_PAD,
|
||||||
|
valueTempl: VALUE_TEMPL,
|
||||||
|
nameFieldSize: NAME_FIELD_SIZE,
|
||||||
|
totalFieldSize: TOTAL_FIELD_SIZE,
|
||||||
|
log: log,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) Log() logger.VerboseLogger {
|
||||||
|
return rep.log
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutBrownWithPad(name string, value any, fieldSize int) {
|
||||||
|
name = strings.Title(name)
|
||||||
|
name = utils.PadStringRight(name, rep.pad, fieldSize, rep.valueTempl)
|
||||||
|
rep.log.VerboseBrownf(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutBlueWithPad(name string, value any, fieldSize int) {
|
||||||
|
name = strings.Title(name)
|
||||||
|
name = utils.PadStringRight(name, rep.pad, fieldSize, rep.valueTempl)
|
||||||
|
rep.log.VerboseBluef(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutParam(name string, value any) {
|
||||||
|
rep.PutBrownWithPad(name, value, rep.nameFieldSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutParamWithError(name string, err error, value any) {
|
||||||
|
if err != nil {
|
||||||
|
tty, _ := rep.log.GetProperty(CONSOLE_LOG_TTY).(*utils.TTYContext)
|
||||||
|
value = fmt.Sprintf("%v -- %s%v%s", value, tty.RedFg(utils.STDERR), err, tty.Reset(utils.STDERR))
|
||||||
|
}
|
||||||
|
rep.PutBrownWithPad(name, value, rep.nameFieldSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutTotal(name string, value any) {
|
||||||
|
rep.PutBlueWithPad(name, value, rep.totalFieldSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutTotalCond(name string, good bool, value any) {
|
||||||
|
var styledValue string
|
||||||
|
tty, _ := rep.log.GetProperty(CONSOLE_LOG_TTY).(*utils.TTYContext)
|
||||||
|
name = utils.PadStringRight(name, DOT_PAD, TOTAL_FIELD_SIZE, rep.valueTempl)
|
||||||
|
if good {
|
||||||
|
styledValue = fmt.Sprintf("%s%v%s", tty.GreenFg(utils.STDERR), value, tty.Reset(utils.STDERR))
|
||||||
|
} else {
|
||||||
|
styledValue = fmt.Sprintf("%s%v%s", tty.RedFg(utils.STDERR), value, tty.Reset(utils.STDERR))
|
||||||
|
}
|
||||||
|
rep.log.VerboseBluef(name, styledValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rep *Report) PutVars(vars map[string]string, sortKeys bool) {
|
||||||
|
if vars != nil {
|
||||||
|
if sortKeys {
|
||||||
|
keys := make([]string, len(vars))
|
||||||
|
i := 0
|
||||||
|
for key := range vars {
|
||||||
|
keys[i] = key
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
slices.Sort(keys)
|
||||||
|
for _, key := range keys {
|
||||||
|
name := utils.PadStringRight(key, rep.pad, rep.nameFieldSize, rep.valueTempl)
|
||||||
|
rep.log.VerboseBrownf(name, vars[key])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for key, value := range vars {
|
||||||
|
name := utils.PadStringRight(key, rep.pad, rep.nameFieldSize, rep.valueTempl)
|
||||||
|
rep.log.VerboseBrownf(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user