mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
GB28181: Support GB28181-2016 protocol. v5.0.74 (#3201)
01. Support GB config as StreamCaster. 02. Support disable GB by --gb28181=off. 03. Add utests for SIP examples. 04. Wireshark plugin to decode TCP/9000 as rtp.rfc4571 05. Support MPEGPS program stream codec. 06. Add utest for PS stream codec. 07. Decode MPEGPS packet stream. 08. Carry RTP and PS packet as helper in PS message. 09. Support recover from error mode. 10. Support process by a pack of PS/TS messages. 11. Add statistic for recovered and msgs dropped. 12. Recover from err position fastly. 13. Define state machine for GB session. 14. Bind context to GB session. 15. Re-invite when media disconnected. 16. Update GitHub actions with GB28181. 17. Support parse CANDIDATE by env or pip. 18. Support mux GB28181 to RTMP. 19. Support regression test by srs-bench.
This commit is contained in:
parent
9c81a0e1bd
commit
5a420ece3b
298 changed files with 43343 additions and 763 deletions
34
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/.gitignore
generated
vendored
Normal file
34
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
# IDEA files
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Unit testing
|
||||
*.coverprofile
|
14
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/.travis.yml
generated
vendored
Normal file
14
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
|
||||
install:
|
||||
- make deps
|
||||
|
||||
script:
|
||||
- make test
|
||||
|
||||
sudo: false
|
21
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/LICENSE
generated
vendored
Normal file
21
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Denis Parchenko
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
19
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/Makefile
generated
vendored
Normal file
19
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
NAME=logrus-prefixed-formatter
|
||||
PACKAGES=$(shell go list ./...)
|
||||
|
||||
deps:
|
||||
@echo "--> Installing dependencies"
|
||||
@go get -d -v -t ./...
|
||||
|
||||
test-deps:
|
||||
@which ginkgo 2>/dev/null ; if [ $$? -eq 1 ]; then \
|
||||
go get -u -v github.com/onsi/ginkgo/ginkgo; \
|
||||
fi
|
||||
|
||||
test: test-deps
|
||||
@echo "--> Running tests"
|
||||
@ginkgo -r --randomizeAllSpecs --randomizeSuites --failOnPending --cover --trace --race
|
||||
|
||||
format:
|
||||
@echo "--> Running go fmt"
|
||||
@go fmt $(PACKAGES)
|
116
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/README.md
generated
vendored
Normal file
116
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/README.md
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
# Logrus Prefixed Log Formatter
|
||||
[](https://travis-ci.org/x-cray/logrus-prefixed-formatter)
|
||||
|
||||
[Logrus](https://github.com/sirupsen/logrus) formatter mainly based on original `logrus.TextFormatter` but with slightly
|
||||
modified colored output and support for log entry prefixes, e.g. message source followed by a colon. In addition, custom
|
||||
color themes are supported.
|
||||
|
||||

|
||||
|
||||
Just like with the original `logrus.TextFormatter` when a TTY is not attached, the output is compatible with the
|
||||
[logfmt](http://godoc.org/github.com/kr/logfmt) format:
|
||||
|
||||
```text
|
||||
time="Oct 27 00:44:26" level=debug msg="Started observing beach" animal=walrus number=8
|
||||
time="Oct 27 00:44:26" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||
time="Oct 27 00:44:26" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||
time="Oct 27 00:44:26" level=debug msg="Temperature changes" temperature=-4
|
||||
time="Oct 27 00:44:26" level=panic msg="It's over 9000!" animal=orca size=9009
|
||||
time="Oct 27 00:44:26" level=fatal msg="The ice breaks!" number=100 omg=true
|
||||
exit status 1
|
||||
```
|
||||
|
||||
## Installation
|
||||
To install formatter, use `go get`:
|
||||
|
||||
```sh
|
||||
$ go get github.com/x-cray/logrus-prefixed-formatter
|
||||
```
|
||||
|
||||
## Usage
|
||||
Here is how it should be used:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
prefixed "github.com/x-cray/logrus-prefixed-formatter"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(prefixed.TextFormatter)
|
||||
log.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(logrus.Fields{
|
||||
"prefix": "main",
|
||||
"animal": "walrus",
|
||||
"number": 8,
|
||||
}).Debug("Started observing beach")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"prefix": "sensor",
|
||||
"temperature": -4,
|
||||
}).Info("Temperature changes")
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
`prefixed.TextFormatter` exposes the following fields and methods.
|
||||
|
||||
### Fields
|
||||
|
||||
* `ForceColors bool` — set to true to bypass checking for a TTY before outputting colors.
|
||||
* `DisableColors bool` — force disabling colors. For a TTY colors are enabled by default.
|
||||
* `DisableUppercase bool` — set to true to turn off the conversion of the log level names to uppercase.
|
||||
* `ForceFormatting bool` — force formatted layout, even for non-TTY output.
|
||||
* `DisableTimestamp bool` — disable timestamp logging. Useful when output is redirected to logging system that already adds timestamps.
|
||||
* `FullTimestamp bool` — enable logging the full timestamp when a TTY is attached instead of just the time passed since beginning of execution.
|
||||
* `TimestampFormat string` — timestamp format to use for display when a full timestamp is printed.
|
||||
* `DisableSorting bool` — the fields are sorted by default for a consistent output. For applications that log extremely frequently and don't use the JSON formatter this may not be desired.
|
||||
* `QuoteEmptyFields bool` — wrap empty fields in quotes if true.
|
||||
* `QuoteCharacter string` — can be set to the override the default quoting character `"` with something else. For example: `'`, or `` ` ``.
|
||||
* `SpacePadding int` — pad msg field with spaces on the right for display. The value for this parameter will be the size of padding. Its default value is zero, which means no padding will be applied.
|
||||
|
||||
### Methods
|
||||
|
||||
#### `SetColorScheme(colorScheme *prefixed.ColorScheme)`
|
||||
|
||||
Sets an alternative color scheme for colored output. `prefixed.ColorScheme` struct supports the following fields:
|
||||
* `InfoLevelStyle string` — info level style.
|
||||
* `WarnLevelStyle string` — warn level style.
|
||||
* `ErrorLevelStyle string` — error style.
|
||||
* `FatalLevelStyle string` — fatal level style.
|
||||
* `PanicLevelStyle string` — panic level style.
|
||||
* `DebugLevelStyle string` — debug level style.
|
||||
* `PrefixStyle string` — prefix style.
|
||||
* `TimestampStyle string` — timestamp style.
|
||||
|
||||
Color styles should be specified using [mgutz/ansi](https://github.com/mgutz/ansi#style-format) style syntax. For example, here is the default theme:
|
||||
|
||||
```go
|
||||
InfoLevelStyle: "green",
|
||||
WarnLevelStyle: "yellow",
|
||||
ErrorLevelStyle: "red",
|
||||
FatalLevelStyle: "red",
|
||||
PanicLevelStyle: "red",
|
||||
DebugLevelStyle: "blue",
|
||||
PrefixStyle: "cyan",
|
||||
TimestampStyle: "black+h"
|
||||
```
|
||||
|
||||
It's not necessary to specify all colors when changing color scheme if you want to change just specific ones:
|
||||
|
||||
```go
|
||||
formatter.SetColorScheme(&prefixed.ColorScheme{
|
||||
PrefixStyle: "blue+b",
|
||||
TimestampStyle: "white+h",
|
||||
})
|
||||
```
|
||||
|
||||
# License
|
||||
MIT
|
366
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/formatter.go
generated
vendored
Normal file
366
trunk/3rdparty/srs-bench/vendor/github.com/x-cray/logrus-prefixed-formatter/formatter.go
generated
vendored
Normal file
|
@ -0,0 +1,366 @@
|
|||
package prefixed
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/mgutz/ansi"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
const defaultTimestampFormat = time.RFC3339
|
||||
|
||||
var (
|
||||
baseTimestamp time.Time = time.Now()
|
||||
defaultColorScheme *ColorScheme = &ColorScheme{
|
||||
InfoLevelStyle: "green",
|
||||
WarnLevelStyle: "yellow",
|
||||
ErrorLevelStyle: "red",
|
||||
FatalLevelStyle: "red",
|
||||
PanicLevelStyle: "red",
|
||||
DebugLevelStyle: "blue",
|
||||
PrefixStyle: "cyan",
|
||||
TimestampStyle: "black+h",
|
||||
}
|
||||
noColorsColorScheme *compiledColorScheme = &compiledColorScheme{
|
||||
InfoLevelColor: ansi.ColorFunc(""),
|
||||
WarnLevelColor: ansi.ColorFunc(""),
|
||||
ErrorLevelColor: ansi.ColorFunc(""),
|
||||
FatalLevelColor: ansi.ColorFunc(""),
|
||||
PanicLevelColor: ansi.ColorFunc(""),
|
||||
DebugLevelColor: ansi.ColorFunc(""),
|
||||
PrefixColor: ansi.ColorFunc(""),
|
||||
TimestampColor: ansi.ColorFunc(""),
|
||||
}
|
||||
defaultCompiledColorScheme *compiledColorScheme = compileColorScheme(defaultColorScheme)
|
||||
)
|
||||
|
||||
func miniTS() int {
|
||||
return int(time.Since(baseTimestamp) / time.Second)
|
||||
}
|
||||
|
||||
type ColorScheme struct {
|
||||
InfoLevelStyle string
|
||||
WarnLevelStyle string
|
||||
ErrorLevelStyle string
|
||||
FatalLevelStyle string
|
||||
PanicLevelStyle string
|
||||
DebugLevelStyle string
|
||||
PrefixStyle string
|
||||
TimestampStyle string
|
||||
}
|
||||
|
||||
type compiledColorScheme struct {
|
||||
InfoLevelColor func(string) string
|
||||
WarnLevelColor func(string) string
|
||||
ErrorLevelColor func(string) string
|
||||
FatalLevelColor func(string) string
|
||||
PanicLevelColor func(string) string
|
||||
DebugLevelColor func(string) string
|
||||
PrefixColor func(string) string
|
||||
TimestampColor func(string) string
|
||||
}
|
||||
|
||||
type TextFormatter struct {
|
||||
// Set to true to bypass checking for a TTY before outputting colors.
|
||||
ForceColors bool
|
||||
|
||||
// Force disabling colors. For a TTY colors are enabled by default.
|
||||
DisableColors bool
|
||||
|
||||
// Force formatted layout, even for non-TTY output.
|
||||
ForceFormatting bool
|
||||
|
||||
// Disable timestamp logging. useful when output is redirected to logging
|
||||
// system that already adds timestamps.
|
||||
DisableTimestamp bool
|
||||
|
||||
// Disable the conversion of the log levels to uppercase
|
||||
DisableUppercase bool
|
||||
|
||||
// Enable logging the full timestamp when a TTY is attached instead of just
|
||||
// the time passed since beginning of execution.
|
||||
FullTimestamp bool
|
||||
|
||||
// Timestamp format to use for display when a full timestamp is printed.
|
||||
TimestampFormat string
|
||||
|
||||
// The fields are sorted by default for a consistent output. For applications
|
||||
// that log extremely frequently and don't use the JSON formatter this may not
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
|
||||
// Wrap empty fields in quotes if true.
|
||||
QuoteEmptyFields bool
|
||||
|
||||
// Can be set to the override the default quoting character "
|
||||
// with something else. For example: ', or `.
|
||||
QuoteCharacter string
|
||||
|
||||
// Pad msg field with spaces on the right for display.
|
||||
// The value for this parameter will be the size of padding.
|
||||
// Its default value is zero, which means no padding will be applied for msg.
|
||||
SpacePadding int
|
||||
|
||||
// Color scheme to use.
|
||||
colorScheme *compiledColorScheme
|
||||
|
||||
// Whether the logger's out is to a terminal.
|
||||
isTerminal bool
|
||||
|
||||
sync.Once
|
||||
}
|
||||
|
||||
func getCompiledColor(main string, fallback string) func(string) string {
|
||||
var style string
|
||||
if main != "" {
|
||||
style = main
|
||||
} else {
|
||||
style = fallback
|
||||
}
|
||||
return ansi.ColorFunc(style)
|
||||
}
|
||||
|
||||
func compileColorScheme(s *ColorScheme) *compiledColorScheme {
|
||||
return &compiledColorScheme{
|
||||
InfoLevelColor: getCompiledColor(s.InfoLevelStyle, defaultColorScheme.InfoLevelStyle),
|
||||
WarnLevelColor: getCompiledColor(s.WarnLevelStyle, defaultColorScheme.WarnLevelStyle),
|
||||
ErrorLevelColor: getCompiledColor(s.ErrorLevelStyle, defaultColorScheme.ErrorLevelStyle),
|
||||
FatalLevelColor: getCompiledColor(s.FatalLevelStyle, defaultColorScheme.FatalLevelStyle),
|
||||
PanicLevelColor: getCompiledColor(s.PanicLevelStyle, defaultColorScheme.PanicLevelStyle),
|
||||
DebugLevelColor: getCompiledColor(s.DebugLevelStyle, defaultColorScheme.DebugLevelStyle),
|
||||
PrefixColor: getCompiledColor(s.PrefixStyle, defaultColorScheme.PrefixStyle),
|
||||
TimestampColor: getCompiledColor(s.TimestampStyle, defaultColorScheme.TimestampStyle),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) init(entry *logrus.Entry) {
|
||||
if len(f.QuoteCharacter) == 0 {
|
||||
f.QuoteCharacter = "\""
|
||||
}
|
||||
if entry.Logger != nil {
|
||||
f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
return terminal.IsTerminal(int(v.Fd()))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) SetColorScheme(colorScheme *ColorScheme) {
|
||||
f.colorScheme = compileColorScheme(colorScheme)
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
var b *bytes.Buffer
|
||||
var keys []string = make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
lastKeyIdx := len(keys) - 1
|
||||
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
}
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
prefixFieldClashes(entry.Data)
|
||||
|
||||
f.Do(func() { f.init(entry) })
|
||||
|
||||
isFormatted := f.ForceFormatting || f.isTerminal
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = defaultTimestampFormat
|
||||
}
|
||||
if isFormatted {
|
||||
isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
|
||||
var colorScheme *compiledColorScheme
|
||||
if isColored {
|
||||
if f.colorScheme == nil {
|
||||
colorScheme = defaultCompiledColorScheme
|
||||
} else {
|
||||
colorScheme = f.colorScheme
|
||||
}
|
||||
} else {
|
||||
colorScheme = noColorsColorScheme
|
||||
}
|
||||
f.printColored(b, entry, keys, timestampFormat, colorScheme)
|
||||
} else {
|
||||
if !f.DisableTimestamp {
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat), true)
|
||||
}
|
||||
f.appendKeyValue(b, "level", entry.Level.String(), true)
|
||||
if entry.Message != "" {
|
||||
f.appendKeyValue(b, "msg", entry.Message, lastKeyIdx >= 0)
|
||||
}
|
||||
for i, key := range keys {
|
||||
f.appendKeyValue(b, key, entry.Data[key], lastKeyIdx != i)
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteByte('\n')
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry, keys []string, timestampFormat string, colorScheme *compiledColorScheme) {
|
||||
var levelColor func(string) string
|
||||
var levelText string
|
||||
switch entry.Level {
|
||||
case logrus.InfoLevel:
|
||||
levelColor = colorScheme.InfoLevelColor
|
||||
case logrus.WarnLevel:
|
||||
levelColor = colorScheme.WarnLevelColor
|
||||
case logrus.ErrorLevel:
|
||||
levelColor = colorScheme.ErrorLevelColor
|
||||
case logrus.FatalLevel:
|
||||
levelColor = colorScheme.FatalLevelColor
|
||||
case logrus.PanicLevel:
|
||||
levelColor = colorScheme.PanicLevelColor
|
||||
default:
|
||||
levelColor = colorScheme.DebugLevelColor
|
||||
}
|
||||
|
||||
if entry.Level != logrus.WarnLevel {
|
||||
levelText = entry.Level.String()
|
||||
} else {
|
||||
levelText = "warn"
|
||||
}
|
||||
|
||||
if !f.DisableUppercase {
|
||||
levelText = strings.ToUpper(levelText)
|
||||
}
|
||||
|
||||
level := levelColor(fmt.Sprintf("%5s", levelText))
|
||||
prefix := ""
|
||||
message := entry.Message
|
||||
|
||||
if prefixValue, ok := entry.Data["prefix"]; ok {
|
||||
prefix = colorScheme.PrefixColor(" " + prefixValue.(string) + ":")
|
||||
} else {
|
||||
prefixValue, trimmedMsg := extractPrefix(entry.Message)
|
||||
if len(prefixValue) > 0 {
|
||||
prefix = colorScheme.PrefixColor(" " + prefixValue + ":")
|
||||
message = trimmedMsg
|
||||
}
|
||||
}
|
||||
|
||||
messageFormat := "%s"
|
||||
if f.SpacePadding != 0 {
|
||||
messageFormat = fmt.Sprintf("%%-%ds", f.SpacePadding)
|
||||
}
|
||||
|
||||
if f.DisableTimestamp {
|
||||
fmt.Fprintf(b, "%s%s "+messageFormat, level, prefix, message)
|
||||
} else {
|
||||
var timestamp string
|
||||
if !f.FullTimestamp {
|
||||
timestamp = fmt.Sprintf("[%04d]", miniTS())
|
||||
} else {
|
||||
timestamp = fmt.Sprintf("[%s]", entry.Time.Format(timestampFormat))
|
||||
}
|
||||
fmt.Fprintf(b, "%s %s%s "+messageFormat, colorScheme.TimestampColor(timestamp), level, prefix, message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
if k != "prefix" {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " %s=%+v", levelColor(k), v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) needsQuoting(text string) bool {
|
||||
if f.QuoteEmptyFields && len(text) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, ch := range text {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.') {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func extractPrefix(msg string) (string, string) {
|
||||
prefix := ""
|
||||
regex := regexp.MustCompile("^\\[(.*?)\\]")
|
||||
if regex.MatchString(msg) {
|
||||
match := regex.FindString(msg)
|
||||
prefix, msg = match[1:len(match)-1], strings.TrimSpace(msg[len(match):])
|
||||
}
|
||||
return prefix, msg
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}, appendSpace bool) {
|
||||
b.WriteString(key)
|
||||
b.WriteByte('=')
|
||||
f.appendValue(b, value)
|
||||
|
||||
if appendSpace {
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
if !f.needsQuoting(value) {
|
||||
b.WriteString(value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
||||
}
|
||||
case error:
|
||||
errmsg := value.Error()
|
||||
if !f.needsQuoting(errmsg) {
|
||||
b.WriteString(errmsg)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
||||
}
|
||||
default:
|
||||
fmt.Fprint(b, value)
|
||||
}
|
||||
}
|
||||
|
||||
// This is to not silently overwrite `time`, `msg` and `level` fields when
|
||||
// dumping it. If this code wasn't there doing:
|
||||
//
|
||||
// logrus.WithField("level", 1).Info("hello")
|
||||
//
|
||||
// would just silently drop the user provided level. Instead with this code
|
||||
// it'll be logged as:
|
||||
//
|
||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
||||
func prefixFieldClashes(data logrus.Fields) {
|
||||
if t, ok := data["time"]; ok {
|
||||
data["fields.time"] = t
|
||||
}
|
||||
|
||||
if m, ok := data["msg"]; ok {
|
||||
data["fields.msg"] = m
|
||||
}
|
||||
|
||||
if l, ok := data["level"]; ok {
|
||||
data["fields.level"] = l
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue