1
0
mirror of https://gitea.com/gitea/log synced 2025-10-05 16:32:46 +02:00

Make flags marshallable (#2)

This commit is contained in:
Andrew Thornton
2019-06-03 07:59:42 +00:00
committed by Gitea
parent 0560851a16
commit 5ae8320ede
3 changed files with 121 additions and 31 deletions

104
flags.go
View File

@@ -4,7 +4,13 @@
package log
import "strings"
import (
"encoding/json"
"strings"
)
// Flags represents the logging flags for a logger
type Flags int
// These flags define which text to prefix to each log entry generated
// by the Logger. Bits are or'ed together to control what's printed.
@@ -16,16 +22,16 @@ import "strings"
// The standard is:
// 2009/01/23 01:23:23 ...a/logger/c/d.go:23:runtime.Caller() [I]: message
const (
Ldate = 1 << iota // the date in the local time zone: 2009/01/23
Ltime // the time in the local time zone: 01:23:23
Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
Llongfile // full file name and line number: /a/logger/c/d.go:23
Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
Lfuncname // function name of the caller: runtime.Caller()
Lshortfuncname // last part of the function name
LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
Llevelinitial // Initial character of the provided level in brackets eg. [I] for info
Llevel // Provided level in brackets [INFO]
Ldate Flags = 1 << iota // the date in the local time zone: 2009/01/23
Ltime // the time in the local time zone: 01:23:23
Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
Llongfile // full file name and line number: /a/logger/c/d.go:23
Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
Lfuncname // function name of the caller: runtime.Caller()
Lshortfuncname // last part of the function name
LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
Llevelinitial // Initial character of the provided level in brackets eg. [I] for info
Llevel // Provided level in brackets [INFO]
// Last 20 characters of the filename
Lmedfile = Lshortfile | Llongfile
@@ -34,30 +40,68 @@ const (
LstdFlags = Ldate | Ltime | Lmedfile | Lshortfuncname | Llevelinitial
)
var flagFromString = map[string]int{
"none": 0,
"date": Ldate,
"time": Ltime,
"microseconds": Lmicroseconds,
"longfile": Llongfile,
"shortfile": Lshortfile,
"funcname": Lfuncname,
"shortfuncname": Lshortfuncname,
"utc": LUTC,
"levelinitial": Llevelinitial,
"level": Llevel,
"medfile": Lmedfile,
"stdflags": LstdFlags,
var flagOrder = []string{
"date",
"time",
"microseconds",
"longfile",
"shortfile",
"funcname",
"shortfuncname",
"utc",
"levelinitial",
"level",
}
// UnmarshalJSON converts a series of bytes to a flag
func (f *Flags) UnmarshalJSON(b []byte) error {
// OK first of all try an int
var i int
if err := json.Unmarshal(b, &i); err == nil {
*f = Flags(i)
return nil
}
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
*f = FlagsFromString(s)
return nil
}
// MarshalJSON converts Flags to JSON
func (f Flags) MarshalJSON() ([]byte, error) {
stringFlags := []string{}
w := f
if w&LstdFlags == LstdFlags {
stringFlags = append(stringFlags, "stdflags")
w = w ^ LstdFlags
}
if w&Lmedfile == Lmedfile {
stringFlags = append(stringFlags, "medfile")
w = w ^ Lmedfile
}
for i, k := range flagOrder {
v := Flags(1 << uint64(i))
if w&v == v && v != 0 {
stringFlags = append(stringFlags, k)
}
}
if len(stringFlags) == 0 {
stringFlags = append(stringFlags, "none")
}
return json.Marshal(strings.Join(stringFlags, ", "))
}
// FlagsFromString takes a comma separated list of flags and returns
// the flags for this string
func FlagsFromString(from string) int {
flags := 0
func FlagsFromString(from string) Flags {
flags := Flags(0)
for _, flag := range strings.Split(strings.ToLower(from), ",") {
f, ok := flagFromString[strings.TrimSpace(flag)]
if ok {
flags = flags | f
for f, k := range flagOrder {
if k == strings.TrimSpace(flag) {
flags = flags | Flags(1<<uint64(f))
}
}
}
return flags

46
flags_test.go Normal file
View File

@@ -0,0 +1,46 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package log
import (
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
type testFlags struct {
Flags Flags `json:"flags"`
}
func TestFlagsMarshalUnmarshalJSON(t *testing.T) {
flagsBytes, err := json.Marshal(testFlags{
Flags: LstdFlags,
})
assert.NoError(t, err)
assert.Equal(t, string(makeTestFlagsBytes("stdflags")), string(flagsBytes))
var testFlags testFlags
err = json.Unmarshal(makeTestFlagsBytes(`XAXAXA`), &testFlags)
assert.NoError(t, err)
assert.Equal(t, Flags(0), testFlags.Flags)
err = json.Unmarshal([]byte(fmt.Sprintf(`{"flags":%d}`, LstdFlags)), &testFlags)
assert.NoError(t, err)
assert.Equal(t, LstdFlags, testFlags.Flags)
flagString := "date, shortfile, levelinitial"
err = json.Unmarshal(makeTestFlagsBytes(flagString), &testFlags)
assert.NoError(t, err)
assert.Equal(t, FlagsFromString(flagString), testFlags.Flags)
flagsBytes, err = json.Marshal(testFlags)
assert.NoError(t, err)
assert.Equal(t, string(makeTestFlagsBytes(flagString)), string(flagsBytes))
}
func makeTestFlagsBytes(flagsString string) []byte {
return []byte(fmt.Sprintf(`{"flags":"%s"}`, flagsString))
}

View File

@@ -27,7 +27,7 @@ type WriterLogger struct {
Level Level `json:"level"`
StacktraceLevel Level `json:"stacktraceLevel"`
Flags int `json:"flags"`
Flags Flags `json:"flags"`
Prefix string `json:"prefix"`
Colorize bool `json:"colorize"`
Expression string `json:"expression"`