type LogLevel int
const (
General LogLevel = 0
Alert LogLevel = 1
Warning LogLevel = 2
Debug LogLevel = 3
Error LogLevel = 4
Fatal LogLevel = 5
Panic LogLevel = 6
)
func writeToStderr(msg string) {
syscall.Write(2, *(*[]byte)(unsafe.Pointer(&msg)))
}
func DirAndFilename(path string) string {
result := strings.LastIndex(path, "/")
if result == -1 {
return path
}
result2 := strings.LastIndex(path[:result], "/")
if result == -1 {
return path
}
return path[result2 + 1 : ]
}
func detailWriteLog(level LogLevel, format string, args ... interface{}) {
now := time.Now()
_, file, line, ok := runtime.Caller(2)
if !ok {
file = "???"
line = 0
}
prefix := fmt.Sprintf("[%s] %%s: %s:%d: ", now.Format("2006-01-02T15:04:05"), DirAndFilename(file), line)
suffix := fmt.Sprintf(format, args...)
switch (level) {
case General:
writeToStderr(TERM_PLAIN + fmt.Sprintf(prefix, "General") + suffix + TERM_EOR)
case Alert:
writeToStderr(TERM_ALERT + fmt.Sprintf(prefix, "Alert") + suffix + TERM_EOR)
case Warning:
writeToStderr(TERM_WARNING + fmt.Sprintf(prefix, "Warning") + suffix + TERM_EOR)
case Debug:
writeToStderr(TERM_DEBUG + fmt.Sprintf(prefix, "Debug") + suffix + TERM_EOR)
case Error:
writeToStderr(TERM_ERROR + fmt.Sprintf(prefix, "Error ") + suffix + TERM_EOR)
case Fatal:
writeToStderr(TERM_FATAL + fmt.Sprintf(prefix, "Fatal") + suffix + TERM_EOR)
os.Exit(1)
case Panic:
writeToStderr(TERM_PANIC + fmt.Sprintf(prefix, "Panic") + suffix + TERM_EOR)
panic("")
}
}
func WriteLog(level LogLevel, fmt string, args ... interface{}) {
detailWriteLog(level, fmt, args...)
}
func WriteLogKV(level LogLevel, kernelVersion, fmt string, args ... interface{}) {
detailWriteLog(level, kernelVersion + ": " + fmt, args...)
}
func ReportError(err error, format string, args ... interface{}) {
prefix := "";
if (len(format) > 0) {
prefix = ": "
}
switch v := err.(type) {
case *errors.Error:
detailWriteLog(Error, format + prefix + fmt.Sprintf("Got error of type %s: %v\nStacktrace:\n%s", reflect.TypeOf(v.Err).String(), v.Error(), v.Stack()), args...)
default:
detailWriteLog(Error, format + prefix + fmt.Sprintf("Got error of type %s: %v", reflect.TypeOf(err).String(), err), args...)
}
}
func ReportErrorNoTrace(err error, format string, args ... interface{}) {
prefix := "";
if (len(format) > 0) {
prefix = ": "
}
switch v := err.(type) {
case *errors.Error:
detailWriteLog(Error, format + prefix + fmt.Sprintf("Got error of type %s: %v", reflect.TypeOf(v.Err).String(), v.Error()), args...)
default:
detailWriteLog(Error, format + prefix + fmt.Sprintf("Got error of type %s: %v", reflect.TypeOf(err).String(), err), args...)
}
}
func ReportPanic(err error, format string, args ... interface{}) {
prefix := "";
if (len(format) > 0) {
prefix = ": "
}
switch v := err.(type) {
case *errors.Error:
detailWriteLog(Error, format + prefix + fmt.Sprintf("%v\nStacktrace:\n%v", err, v.ErrorStack()), args...)
default:
detailWriteLog(Error, format + prefix + fmt.Sprintf("%v", err), args...)
}
panic(err)
}