code.gitea.io/gitea@v1.22.3/modules/log/flags.go (about)

     1  // Copyright 2023 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package log
     5  
     6  import (
     7  	"sort"
     8  	"strings"
     9  
    10  	"code.gitea.io/gitea/modules/json"
    11  )
    12  
    13  // These flags define which text to prefix to each log entry generated
    14  // by the Logger. Bits are or'ed together to control what's printed.
    15  // There is no control over the order they appear (the order listed
    16  // here) or the format they present (as described in the comments).
    17  // The prefix is followed by a colon only if more than time is stated
    18  // is specified. For example, flags Ldate | Ltime
    19  // produce, 2009/01/23 01:23:23 message.
    20  // The standard is:
    21  // 2009/01/23 01:23:23 ...a/logger/c/d.go:23:runtime.Caller() [I]: message
    22  const (
    23  	Ldate          uint32 = 1 << iota // the date in the local time zone: 2009/01/23
    24  	Ltime                             // the time in the local time zone: 01:23:23
    25  	Lmicroseconds                     // microsecond resolution: 01:23:23.123123.  assumes Ltime.
    26  	Llongfile                         // full file name and line number: /a/logger/c/d.go:23
    27  	Lshortfile                        // final file name element and line number: d.go:23. overrides Llongfile
    28  	Lfuncname                         // function name of the caller: runtime.Caller()
    29  	Lshortfuncname                    // last part of the function name
    30  	LUTC                              // if Ldate or Ltime is set, use UTC rather than the local time zone
    31  	Llevelinitial                     // Initial character of the provided level in brackets, eg. [I] for info
    32  	Llevel                            // Provided level in brackets [INFO]
    33  	Lgopid                            // the Goroutine-PID of the context
    34  
    35  	Lmedfile  = Lshortfile | Llongfile                                    // last 20 characters of the filename
    36  	LstdFlags = Ldate | Ltime | Lmedfile | Lshortfuncname | Llevelinitial // default
    37  )
    38  
    39  const Ldefault = LstdFlags
    40  
    41  type Flags struct {
    42  	defined bool
    43  	flags   uint32
    44  }
    45  
    46  var flagFromString = map[string]uint32{
    47  	"date":          Ldate,
    48  	"time":          Ltime,
    49  	"microseconds":  Lmicroseconds,
    50  	"longfile":      Llongfile,
    51  	"shortfile":     Lshortfile,
    52  	"funcname":      Lfuncname,
    53  	"shortfuncname": Lshortfuncname,
    54  	"utc":           LUTC,
    55  	"levelinitial":  Llevelinitial,
    56  	"level":         Llevel,
    57  	"gopid":         Lgopid,
    58  
    59  	"medfile":  Lmedfile,
    60  	"stdflags": LstdFlags,
    61  }
    62  
    63  var flagComboToString = []struct {
    64  	flag uint32
    65  	name string
    66  }{
    67  	// name with more bits comes first
    68  	{LstdFlags, "stdflags"},
    69  	{Lmedfile, "medfile"},
    70  
    71  	{Ldate, "date"},
    72  	{Ltime, "time"},
    73  	{Lmicroseconds, "microseconds"},
    74  	{Llongfile, "longfile"},
    75  	{Lshortfile, "shortfile"},
    76  	{Lfuncname, "funcname"},
    77  	{Lshortfuncname, "shortfuncname"},
    78  	{LUTC, "utc"},
    79  	{Llevelinitial, "levelinitial"},
    80  	{Llevel, "level"},
    81  	{Lgopid, "gopid"},
    82  }
    83  
    84  func (f Flags) Bits() uint32 {
    85  	if !f.defined {
    86  		return Ldefault
    87  	}
    88  	return f.flags
    89  }
    90  
    91  func (f Flags) String() string {
    92  	flags := f.Bits()
    93  	var flagNames []string
    94  	for _, it := range flagComboToString {
    95  		if flags&it.flag == it.flag {
    96  			flags &^= it.flag
    97  			flagNames = append(flagNames, it.name)
    98  		}
    99  	}
   100  	if len(flagNames) == 0 {
   101  		return "none"
   102  	}
   103  	sort.Strings(flagNames)
   104  	return strings.Join(flagNames, ",")
   105  }
   106  
   107  func (f *Flags) UnmarshalJSON(bytes []byte) error {
   108  	var s string
   109  	if err := json.Unmarshal(bytes, &s); err != nil {
   110  		return err
   111  	}
   112  	*f = FlagsFromString(s)
   113  	return nil
   114  }
   115  
   116  func (f Flags) MarshalJSON() ([]byte, error) {
   117  	return []byte(`"` + f.String() + `"`), nil
   118  }
   119  
   120  func FlagsFromString(from string, def ...uint32) Flags {
   121  	from = strings.TrimSpace(from)
   122  	if from == "" && len(def) > 0 {
   123  		return Flags{defined: true, flags: def[0]}
   124  	}
   125  	flags := uint32(0)
   126  	for _, flag := range strings.Split(strings.ToLower(from), ",") {
   127  		flags |= flagFromString[strings.TrimSpace(flag)]
   128  	}
   129  	return Flags{defined: true, flags: flags}
   130  }
   131  
   132  func FlagsFromBits(flags uint32) Flags {
   133  	return Flags{defined: true, flags: flags}
   134  }