summaryrefslogtreecommitdiffstats
path: root/modules/log/level.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--modules/log/level.go136
1 files changed, 136 insertions, 0 deletions
diff --git a/modules/log/level.go b/modules/log/level.go
new file mode 100644
index 0000000..47f7b83
--- /dev/null
+++ b/modules/log/level.go
@@ -0,0 +1,136 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package log
+
+import (
+ "bytes"
+ "strings"
+
+ "code.gitea.io/gitea/modules/json"
+)
+
+// Level is the level of the logger
+type Level int
+
+const (
+ UNDEFINED Level = iota
+ TRACE
+ DEBUG
+ INFO
+ WARN
+ ERROR
+ FATAL
+ NONE
+)
+
+const CRITICAL = ERROR // most logger frameworks doesn't support CRITICAL, and it doesn't seem useful
+
+var toString = map[Level]string{
+ UNDEFINED: "undefined",
+
+ TRACE: "trace",
+ DEBUG: "debug",
+ INFO: "info",
+ WARN: "warn",
+ ERROR: "error",
+
+ FATAL: "fatal",
+ NONE: "none",
+}
+
+// Machine-readable log level prefixes as defined in sd-daemon(3).
+//
+// "If a systemd service definition file is configured with StandardError=journal
+// or StandardError=kmsg (and similar with StandardOutput=), these prefixes can
+// be used to encode a log level in lines printed. <...> To use these prefixes
+// simply prefix every line with one of these strings. A line that is not prefixed
+// will be logged at the default log level SD_INFO."
+var toJournalPrefix = map[Level]string{
+ TRACE: "<7>", // SD_DEBUG
+ DEBUG: "<6>", // SD_INFO
+ INFO: "<5>", // SD_NOTICE
+ WARN: "<4>", // SD_WARNING
+ ERROR: "<3>", // SD_ERR
+ FATAL: "<2>", // SD_CRIT
+}
+
+var toLevel = map[string]Level{
+ "undefined": UNDEFINED,
+
+ "trace": TRACE,
+ "debug": DEBUG,
+ "info": INFO,
+ "warn": WARN,
+ "warning": WARN,
+ "error": ERROR,
+
+ "fatal": FATAL,
+ "none": NONE,
+}
+
+var levelToColor = map[Level][]ColorAttribute{
+ TRACE: {Bold, FgCyan},
+ DEBUG: {Bold, FgBlue},
+ INFO: {Bold, FgGreen},
+ WARN: {Bold, FgYellow},
+ ERROR: {Bold, FgRed},
+ FATAL: {Bold, BgRed},
+ NONE: {Reset},
+}
+
+func (l Level) String() string {
+ s, ok := toString[l]
+ if ok {
+ return s
+ }
+ return "info"
+}
+
+func (l Level) JournalPrefix() string {
+ return toJournalPrefix[l]
+}
+
+func (l Level) ColorAttributes() []ColorAttribute {
+ color, ok := levelToColor[l]
+ if ok {
+ return color
+ }
+ none := levelToColor[NONE]
+ return none
+}
+
+// MarshalJSON takes a Level and turns it into text
+func (l Level) MarshalJSON() ([]byte, error) {
+ buffer := bytes.NewBufferString(`"`)
+ buffer.WriteString(toString[l])
+ buffer.WriteString(`"`)
+ return buffer.Bytes(), nil
+}
+
+// UnmarshalJSON takes text and turns it into a Level
+func (l *Level) UnmarshalJSON(b []byte) error {
+ var tmp any
+ err := json.Unmarshal(b, &tmp)
+ if err != nil {
+ return err
+ }
+
+ switch v := tmp.(type) {
+ case string:
+ *l = LevelFromString(v)
+ case int:
+ *l = LevelFromString(Level(v).String())
+ default:
+ *l = INFO
+ }
+ return nil
+}
+
+// LevelFromString takes a level string and returns a Level
+func LevelFromString(level string) Level {
+ if l, ok := toLevel[strings.ToLower(level)]; ok {
+ return l
+ }
+ return INFO
+}