Source File
	text_handler.go
Belonging Package
	log/slog
// Copyright 2022 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package slogimport ()// TextHandler is a [Handler] that writes Records to an [io.Writer] as a// sequence of key=value pairs separated by spaces and followed by a newline.type TextHandler struct {*commonHandler}// NewTextHandler creates a [TextHandler] that writes to w,// using the given options.// If opts is nil, the default options are used.func ( io.Writer, *HandlerOptions) *TextHandler {if == nil {= &HandlerOptions{}}return &TextHandler{&commonHandler{json: false,w: ,opts: *,mu: &sync.Mutex{},},}}// Enabled reports whether the handler handles records at the given level.// The handler ignores records whose level is lower.func ( *TextHandler) ( context.Context, Level) bool {return .commonHandler.enabled()}// WithAttrs returns a new [TextHandler] whose attributes consists// of h's attributes followed by attrs.func ( *TextHandler) ( []Attr) Handler {return &TextHandler{commonHandler: .commonHandler.withAttrs()}}func ( *TextHandler) ( string) Handler {return &TextHandler{commonHandler: .commonHandler.withGroup()}}// Handle formats its argument [Record] as a single line of space-separated// key=value items.//// If the Record's time is zero, the time is omitted.// Otherwise, the key is "time"// and the value is output in RFC3339 format with millisecond precision.//// The level's key is "level" and its value is the result of calling [Level.String].//// If the AddSource option is set and source information is available,// the key is "source" and the value is output as FILE:LINE.//// The message's key is "msg".//// To modify these or other attributes, or remove them from the output, use// [HandlerOptions.ReplaceAttr].//// If a value implements [encoding.TextMarshaler], the result of MarshalText is// written. Otherwise, the result of [fmt.Sprint] is written.//// Keys and values are quoted with [strconv.Quote] if they contain Unicode space// characters, non-printing characters, '"' or '='.//// Keys inside groups consist of components (keys or group names) separated by// dots. No further escaping is performed.// Thus there is no way to determine from the key "a.b.c" whether there// are two groups "a" and "b" and a key "c", or a single group "a.b" and a key "c",// or single group "a" and a key "b.c".// If it is necessary to reconstruct the group structure of a key// even in the presence of dots inside components, use// [HandlerOptions.ReplaceAttr] to encode that information in the key.//// Each call to Handle results in a single serialized call to// io.Writer.Write.func ( *TextHandler) ( context.Context, Record) error {return .commonHandler.handle()}func appendTextValue( *handleState, Value) error {switch .Kind() {case KindString:.appendString(.str())case KindTime:.appendTime(.time())case KindAny:if , := .any.(encoding.TextMarshaler); {, := .MarshalText()if != nil {return}// TODO: avoid the conversion to string..appendString(string())return nil}if , := byteSlice(.any); {// As of Go 1.19, this only allocates for strings longer than 32 bytes..buf.WriteString(strconv.Quote(string()))return nil}.appendString(fmt.Sprintf("%+v", .Any()))default:*.buf = .append(*.buf)}return nil}// byteSlice returns its argument as a []byte if the argument's// underlying type is []byte, along with a second return value of true.// Otherwise it returns nil, false.func byteSlice( any) ([]byte, bool) {if , := .([]byte); {return , true}// Like Printf's %s, we allow both the slice type and the byte element type to be named.:= reflect.TypeOf()if != nil && .Kind() == reflect.Slice && .Elem().Kind() == reflect.Uint8 {return reflect.ValueOf().Bytes(), true}return nil, false}func needsQuoting( string) bool {if len() == 0 {return true}for := 0; < len(); {:= []if < utf8.RuneSelf {// Quote anything except a backslash that would need quoting in a// JSON string, as well as space and '='if != '\\' && ( == ' ' || == '=' || !safeSet[]) {return true}++continue}, := utf8.DecodeRuneInString([:])if == utf8.RuneError || unicode.IsSpace() || !unicode.IsPrint() {return true}+=}return false}
![]()  | 
The pages are generated with Golds v0.7.9-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |