build(deps): bump cloud.google.com/go/compute from 1.10.0 to 1.19.3
Bumps [cloud.google.com/go/compute](https://github.com/googleapis/google-cloud-go) from 1.10.0 to 1.19.3. - [Release notes](https://github.com/googleapis/google-cloud-go/releases) - [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md) - [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.10.0...compute/v1.19.3) --- updated-dependencies: - dependency-name: cloud.google.com/go/compute dependency-type: direct:production update-type: version-update:semver-minor ... Migrated to the new version by following https://github.com/googleapis/google-cloud-go/blob/main/migration.md Co-authored-by: Tomáš Hozza <thozza@redhat.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
parent
468c63d433
commit
60e55b5ed3
448 changed files with 119170 additions and 54581 deletions
1229
vendor/github.com/golang/glog/glog.go
generated
vendored
1229
vendor/github.com/golang/glog/glog.go
generated
vendored
File diff suppressed because it is too large
Load diff
305
vendor/github.com/golang/glog/glog_file.go
generated
vendored
305
vendor/github.com/golang/glog/glog_file.go
generated
vendored
|
|
@ -1,6 +1,6 @@
|
|||
// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
|
||||
// Go support for leveled logs, analogous to https://github.com/google/glog.
|
||||
//
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -19,26 +19,34 @@
|
|||
package glog
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MaxSize is the maximum size of a log file in bytes.
|
||||
var MaxSize uint64 = 1024 * 1024 * 1800
|
||||
"github.com/golang/glog/internal/logsink"
|
||||
)
|
||||
|
||||
// logDirs lists the candidate directories for new log files.
|
||||
var logDirs []string
|
||||
|
||||
// If non-empty, overrides the choice of directory in which to write logs.
|
||||
// See createLogDirs for the full list of possible destinations.
|
||||
var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
|
||||
var (
|
||||
// If non-empty, overrides the choice of directory in which to write logs.
|
||||
// See createLogDirs for the full list of possible destinations.
|
||||
logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
|
||||
logLink = flag.String("log_link", "", "If non-empty, add symbolic links in this directory to the log files")
|
||||
logBufLevel = flag.Int("logbuflevel", int(logsink.Info), "Buffer log messages logged at this level or lower"+
|
||||
" (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms.")
|
||||
)
|
||||
|
||||
func createLogDirs() {
|
||||
if *logDir != "" {
|
||||
|
|
@ -64,9 +72,17 @@ func init() {
|
|||
if err == nil {
|
||||
userName = current.Username
|
||||
}
|
||||
|
||||
// Sanitize userName since it may contain filepath separators on Windows.
|
||||
userName = strings.Replace(userName, `\`, "_", -1)
|
||||
// Sanitize userName since it is used to construct file paths.
|
||||
userName = strings.Map(func(r rune) rune {
|
||||
switch {
|
||||
case r >= 'a' && r <= 'z':
|
||||
case r >= 'A' && r <= 'Z':
|
||||
case r >= '0' && r <= '9':
|
||||
default:
|
||||
return '_'
|
||||
}
|
||||
return r
|
||||
}, userName)
|
||||
}
|
||||
|
||||
// shortHostname returns its argument, truncating at the first period.
|
||||
|
|
@ -122,3 +138,270 @@ func create(tag string, t time.Time) (f *os.File, filename string, err error) {
|
|||
}
|
||||
return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
|
||||
}
|
||||
|
||||
// flushSyncWriter is the interface satisfied by logging destinations.
|
||||
type flushSyncWriter interface {
|
||||
Flush() error
|
||||
Sync() error
|
||||
io.Writer
|
||||
filenames() []string
|
||||
}
|
||||
|
||||
var sinks struct {
|
||||
stderr stderrSink
|
||||
file fileSink
|
||||
}
|
||||
|
||||
func init() {
|
||||
sinks.stderr.w = os.Stderr
|
||||
|
||||
// Register stderr first: that way if we crash during file-writing at least
|
||||
// the log will have gone somewhere.
|
||||
logsink.TextSinks = append(logsink.TextSinks, &sinks.stderr, &sinks.file)
|
||||
|
||||
sinks.file.flushChan = make(chan logsink.Severity, 1)
|
||||
go sinks.file.flushDaemon()
|
||||
}
|
||||
|
||||
// stderrSink is a logsink.Text that writes log entries to stderr
|
||||
// if they meet certain conditions.
|
||||
type stderrSink struct {
|
||||
mu sync.Mutex
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
// Enabled implements logsink.Text.Enabled. It returns true if any of the
|
||||
// various stderr flags are enabled for logs of the given severity, if the log
|
||||
// message is from the standard "log" package, or if google.Init has not yet run
|
||||
// (and hence file logging is not yet initialized).
|
||||
func (s *stderrSink) Enabled(m *logsink.Meta) bool {
|
||||
return toStderr || alsoToStderr || m.Severity >= stderrThreshold.get()
|
||||
}
|
||||
|
||||
// Emit implements logsink.Text.Emit.
|
||||
func (s *stderrSink) Emit(m *logsink.Meta, data []byte) (n int, err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
dn, err := s.w.Write(data)
|
||||
n += dn
|
||||
return n, err
|
||||
}
|
||||
|
||||
// severityWriters is an array of flushSyncWriter with a value for each
|
||||
// logsink.Severity.
|
||||
type severityWriters [4]flushSyncWriter
|
||||
|
||||
// fileSink is a logsink.Text that prints to a set of Google log files.
|
||||
type fileSink struct {
|
||||
mu sync.Mutex
|
||||
// file holds writer for each of the log types.
|
||||
file severityWriters
|
||||
flushChan chan logsink.Severity
|
||||
}
|
||||
|
||||
// Enabled implements logsink.Text.Enabled. It returns true if google.Init
|
||||
// has run and both --disable_log_to_disk and --logtostderr are false.
|
||||
func (s *fileSink) Enabled(m *logsink.Meta) bool {
|
||||
return !toStderr
|
||||
}
|
||||
|
||||
// Emit implements logsink.Text.Emit
|
||||
func (s *fileSink) Emit(m *logsink.Meta, data []byte) (n int, err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if err = s.createMissingFiles(m.Severity); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for sev := m.Severity; sev >= logsink.Info; sev-- {
|
||||
if _, fErr := s.file[sev].Write(data); fErr != nil && err == nil {
|
||||
err = fErr // Take the first error.
|
||||
}
|
||||
}
|
||||
n = len(data)
|
||||
if int(m.Severity) > *logBufLevel {
|
||||
select {
|
||||
case s.flushChan <- m.Severity:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
|
||||
// file's Sync method and providing a wrapper for the Write method that provides log
|
||||
// file rotation. There are conflicting methods, so the file cannot be embedded.
|
||||
// s.mu is held for all its methods.
|
||||
type syncBuffer struct {
|
||||
sink *fileSink
|
||||
*bufio.Writer
|
||||
file *os.File
|
||||
names []string
|
||||
sev logsink.Severity
|
||||
nbytes uint64 // The number of bytes written to this file
|
||||
}
|
||||
|
||||
func (sb *syncBuffer) Sync() error {
|
||||
return sb.file.Sync()
|
||||
}
|
||||
|
||||
func (sb *syncBuffer) Write(p []byte) (n int, err error) {
|
||||
if sb.nbytes+uint64(len(p)) >= MaxSize {
|
||||
if err := sb.rotateFile(time.Now()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
n, err = sb.Writer.Write(p)
|
||||
sb.nbytes += uint64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (sb *syncBuffer) filenames() []string {
|
||||
return sb.names
|
||||
}
|
||||
|
||||
const footer = "\nCONTINUED IN NEXT FILE\n"
|
||||
|
||||
// rotateFile closes the syncBuffer's file and starts a new one.
|
||||
func (sb *syncBuffer) rotateFile(now time.Time) error {
|
||||
var err error
|
||||
pn := "<none>"
|
||||
file, name, err := create(sb.sev.String(), now)
|
||||
|
||||
if sb.file != nil {
|
||||
// The current log file becomes the previous log at the end of
|
||||
// this block, so save its name for use in the header of the next
|
||||
// file.
|
||||
pn = sb.file.Name()
|
||||
sb.Flush()
|
||||
// If there's an existing file, write a footer with the name of
|
||||
// the next file in the chain, followed by the constant string
|
||||
// \nCONTINUED IN NEXT FILE\n to make continuation detection simple.
|
||||
sb.file.Write([]byte("Next log: "))
|
||||
sb.file.Write([]byte(name))
|
||||
sb.file.Write([]byte(footer))
|
||||
sb.file.Close()
|
||||
}
|
||||
|
||||
sb.file = file
|
||||
sb.names = append(sb.names, name)
|
||||
sb.nbytes = 0
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
|
||||
|
||||
// Write header.
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
|
||||
fmt.Fprintf(&buf, "Running on machine: %s\n", host)
|
||||
fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Fprintf(&buf, "Previous log: %s\n", pn)
|
||||
fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
|
||||
n, err := sb.file.Write(buf.Bytes())
|
||||
sb.nbytes += uint64(n)
|
||||
return err
|
||||
}
|
||||
|
||||
// bufferSize sizes the buffer associated with each log file. It's large
|
||||
// so that log records can accumulate without the logging thread blocking
|
||||
// on disk I/O. The flushDaemon will block instead.
|
||||
const bufferSize = 256 * 1024
|
||||
|
||||
// createMissingFiles creates all the log files for severity from infoLog up to
|
||||
// upTo that have not already been created.
|
||||
// s.mu is held.
|
||||
func (s *fileSink) createMissingFiles(upTo logsink.Severity) error {
|
||||
if s.file[upTo] != nil {
|
||||
return nil
|
||||
}
|
||||
now := time.Now()
|
||||
// Files are created in increasing severity order, so we can be assured that
|
||||
// if a high severity logfile exists, then so do all of lower severity.
|
||||
for sev := logsink.Info; sev <= upTo; sev++ {
|
||||
if s.file[sev] != nil {
|
||||
continue
|
||||
}
|
||||
sb := &syncBuffer{
|
||||
sink: s,
|
||||
sev: sev,
|
||||
}
|
||||
if err := sb.rotateFile(now); err != nil {
|
||||
return err
|
||||
}
|
||||
s.file[sev] = sb
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// flushDaemon periodically flushes the log file buffers.
|
||||
func (s *fileSink) flushDaemon() {
|
||||
tick := time.NewTicker(30 * time.Second)
|
||||
defer tick.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
s.Flush()
|
||||
case sev := <-s.flushChan:
|
||||
s.flush(sev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flush flushes all pending log I/O.
|
||||
func Flush() {
|
||||
sinks.file.Flush()
|
||||
}
|
||||
|
||||
// Flush flushes all the logs and attempts to "sync" their data to disk.
|
||||
func (s *fileSink) Flush() error {
|
||||
return s.flush(logsink.Info)
|
||||
}
|
||||
|
||||
// flush flushes all logs of severity threshold or greater.
|
||||
func (s *fileSink) flush(threshold logsink.Severity) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
var firstErr error
|
||||
updateErr := func(err error) {
|
||||
if err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
}
|
||||
|
||||
// Flush from fatal down, in case there's trouble flushing.
|
||||
for sev := logsink.Fatal; sev >= threshold; sev-- {
|
||||
file := s.file[sev]
|
||||
if file != nil {
|
||||
updateErr(file.Flush())
|
||||
updateErr(file.Sync())
|
||||
}
|
||||
}
|
||||
|
||||
return firstErr
|
||||
}
|
||||
|
||||
// Names returns the names of the log files holding the FATAL, ERROR,
|
||||
// WARNING, or INFO logs. Returns ErrNoLog if the log for the given
|
||||
// level doesn't exist (e.g. because no messages of that level have been
|
||||
// written). This may return multiple names if the log type requested
|
||||
// has rolled over.
|
||||
func Names(s string) ([]string, error) {
|
||||
severity, err := logsink.ParseSeverity(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sinks.file.mu.Lock()
|
||||
defer sinks.file.mu.Unlock()
|
||||
f := sinks.file.file[severity]
|
||||
if f == nil {
|
||||
return nil, ErrNoLog
|
||||
}
|
||||
|
||||
return f.filenames(), nil
|
||||
}
|
||||
|
|
|
|||
395
vendor/github.com/golang/glog/glog_flags.go
generated
vendored
Normal file
395
vendor/github.com/golang/glog/glog_flags.go
generated
vendored
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
// Go support for leveled logs, analogous to https://github.com/google/glog.
|
||||
//
|
||||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package glog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/golang/glog/internal/logsink"
|
||||
)
|
||||
|
||||
// modulePat contains a filter for the -vmodule flag.
|
||||
// It holds a verbosity level and a file pattern to match.
|
||||
type modulePat struct {
|
||||
pattern string
|
||||
literal bool // The pattern is a literal string
|
||||
full bool // The pattern wants to match the full path
|
||||
level Level
|
||||
}
|
||||
|
||||
// match reports whether the file matches the pattern. It uses a string
|
||||
// comparison if the pattern contains no metacharacters.
|
||||
func (m *modulePat) match(full, file string) bool {
|
||||
if m.literal {
|
||||
if m.full {
|
||||
return full == m.pattern
|
||||
}
|
||||
return file == m.pattern
|
||||
}
|
||||
if m.full {
|
||||
match, _ := filepath.Match(m.pattern, full)
|
||||
return match
|
||||
}
|
||||
match, _ := filepath.Match(m.pattern, file)
|
||||
return match
|
||||
}
|
||||
|
||||
// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
|
||||
// that require filepath.Match to be called to match the pattern.
|
||||
func isLiteral(pattern string) bool {
|
||||
return !strings.ContainsAny(pattern, `\*?[]`)
|
||||
}
|
||||
|
||||
// isFull reports whether the pattern matches the full file path, that is,
|
||||
// whether it contains /.
|
||||
func isFull(pattern string) bool {
|
||||
return strings.ContainsRune(pattern, '/')
|
||||
}
|
||||
|
||||
// verboseFlags represents the setting of the -v and -vmodule flags.
|
||||
type verboseFlags struct {
|
||||
// moduleLevelCache is a sync.Map storing the -vmodule Level for each V()
|
||||
// call site, identified by PC. If there is no matching -vmodule filter,
|
||||
// the cached value is exactly v. moduleLevelCache is replaced with a new
|
||||
// Map whenever the -vmodule or -v flag changes state.
|
||||
moduleLevelCache atomic.Value
|
||||
|
||||
// mu guards all fields below.
|
||||
mu sync.Mutex
|
||||
|
||||
// v stores the value of the -v flag. It may be read safely using
|
||||
// sync.LoadInt32, but is only modified under mu.
|
||||
v Level
|
||||
|
||||
// module stores the parsed -vmodule flag.
|
||||
module []modulePat
|
||||
|
||||
// moduleLength caches len(module). If greater than zero, it
|
||||
// means vmodule is enabled. It may be read safely using sync.LoadInt32, but
|
||||
// is only modified under mu.
|
||||
moduleLength int32
|
||||
}
|
||||
|
||||
// NOTE: For compatibility with the open-sourced v1 version of this
|
||||
// package (github.com/golang/glog) we need to retain that flag.Level
|
||||
// implements the flag.Value interface. See also go/log-vs-glog.
|
||||
|
||||
// String is part of the flag.Value interface.
|
||||
func (l *Level) String() string {
|
||||
return strconv.FormatInt(int64(l.Get().(Level)), 10)
|
||||
}
|
||||
|
||||
// Get is part of the flag.Value interface.
|
||||
func (l *Level) Get() any {
|
||||
if l == &vflags.v {
|
||||
// l is the value registered for the -v flag.
|
||||
return Level(atomic.LoadInt32((*int32)(l)))
|
||||
}
|
||||
return *l
|
||||
}
|
||||
|
||||
// Set is part of the flag.Value interface.
|
||||
func (l *Level) Set(value string) error {
|
||||
v, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if l == &vflags.v {
|
||||
// l is the value registered for the -v flag.
|
||||
vflags.mu.Lock()
|
||||
defer vflags.mu.Unlock()
|
||||
vflags.moduleLevelCache.Store(&sync.Map{})
|
||||
atomic.StoreInt32((*int32)(l), int32(v))
|
||||
return nil
|
||||
}
|
||||
*l = Level(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// vModuleFlag is the flag.Value for the --vmodule flag.
|
||||
type vModuleFlag struct{ *verboseFlags }
|
||||
|
||||
func (f vModuleFlag) String() string {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
var b bytes.Buffer
|
||||
for i, f := range f.module {
|
||||
if i > 0 {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Get returns nil for this flag type since the struct is not exported.
|
||||
func (f vModuleFlag) Get() any { return nil }
|
||||
|
||||
var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
|
||||
// Syntax: -vmodule=recordio=2,foo/bar/baz=1,gfs*=3
|
||||
func (f vModuleFlag) Set(value string) error {
|
||||
var filter []modulePat
|
||||
for _, pat := range strings.Split(value, ",") {
|
||||
if len(pat) == 0 {
|
||||
// Empty strings such as from a trailing comma can be ignored.
|
||||
continue
|
||||
}
|
||||
patLev := strings.Split(pat, "=")
|
||||
if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
|
||||
return errVmoduleSyntax
|
||||
}
|
||||
pattern := patLev[0]
|
||||
v, err := strconv.Atoi(patLev[1])
|
||||
if err != nil {
|
||||
return errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
}
|
||||
// TODO: check syntax of filter?
|
||||
filter = append(filter, modulePat{pattern, isLiteral(pattern), isFull(pattern), Level(v)})
|
||||
}
|
||||
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
f.module = filter
|
||||
atomic.StoreInt32((*int32)(&f.moduleLength), int32(len(f.module)))
|
||||
f.moduleLevelCache.Store(&sync.Map{})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *verboseFlags) levelForPC(pc uintptr) Level {
|
||||
if level, ok := f.moduleLevelCache.Load().(*sync.Map).Load(pc); ok {
|
||||
return level.(Level)
|
||||
}
|
||||
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
level := Level(f.v)
|
||||
fn := runtime.FuncForPC(pc)
|
||||
file, _ := fn.FileLine(pc)
|
||||
// The file is something like /a/b/c/d.go. We want just the d for
|
||||
// regular matches, /a/b/c/d for full matches.
|
||||
if strings.HasSuffix(file, ".go") {
|
||||
file = file[:len(file)-3]
|
||||
}
|
||||
full := file
|
||||
if slash := strings.LastIndex(file, "/"); slash >= 0 {
|
||||
file = file[slash+1:]
|
||||
}
|
||||
for _, filter := range f.module {
|
||||
if filter.match(full, file) {
|
||||
level = filter.level
|
||||
break // Use the first matching level.
|
||||
}
|
||||
}
|
||||
f.moduleLevelCache.Load().(*sync.Map).Store(pc, level)
|
||||
return level
|
||||
}
|
||||
|
||||
func (f *verboseFlags) enabled(callerDepth int, level Level) bool {
|
||||
if atomic.LoadInt32(&f.moduleLength) == 0 {
|
||||
// No vmodule values specified, so compare against v level.
|
||||
return Level(atomic.LoadInt32((*int32)(&f.v))) >= level
|
||||
}
|
||||
|
||||
pcs := [1]uintptr{}
|
||||
if runtime.Callers(callerDepth+2, pcs[:]) < 1 {
|
||||
return false
|
||||
}
|
||||
frame, _ := runtime.CallersFrames(pcs[:]).Next()
|
||||
return f.levelForPC(frame.Entry) >= level
|
||||
}
|
||||
|
||||
// traceLocation represents an entry in the -log_backtrace_at flag.
|
||||
type traceLocation struct {
|
||||
file string
|
||||
line int
|
||||
}
|
||||
|
||||
var errTraceSyntax = errors.New("syntax error: expect file.go:234")
|
||||
|
||||
func parseTraceLocation(value string) (traceLocation, error) {
|
||||
fields := strings.Split(value, ":")
|
||||
if len(fields) != 2 {
|
||||
return traceLocation{}, errTraceSyntax
|
||||
}
|
||||
file, lineStr := fields[0], fields[1]
|
||||
if !strings.Contains(file, ".") {
|
||||
return traceLocation{}, errTraceSyntax
|
||||
}
|
||||
line, err := strconv.Atoi(lineStr)
|
||||
if err != nil {
|
||||
return traceLocation{}, errTraceSyntax
|
||||
}
|
||||
if line < 0 {
|
||||
return traceLocation{}, errors.New("negative value for line")
|
||||
}
|
||||
return traceLocation{file, line}, nil
|
||||
}
|
||||
|
||||
// match reports whether the specified file and line matches the trace location.
|
||||
// The argument file name is the full path, not the basename specified in the flag.
|
||||
func (t traceLocation) match(file string, line int) bool {
|
||||
if t.line != line {
|
||||
return false
|
||||
}
|
||||
if i := strings.LastIndex(file, "/"); i >= 0 {
|
||||
file = file[i+1:]
|
||||
}
|
||||
return t.file == file
|
||||
}
|
||||
|
||||
func (t traceLocation) String() string {
|
||||
return fmt.Sprintf("%s:%d", t.file, t.line)
|
||||
}
|
||||
|
||||
// traceLocations represents the -log_backtrace_at flag.
|
||||
// Syntax: -log_backtrace_at=recordio.go:234,sstable.go:456
|
||||
// Note that unlike vmodule the file extension is included here.
|
||||
type traceLocations struct {
|
||||
mu sync.Mutex
|
||||
locsLen int32 // Safe for atomic read without mu.
|
||||
locs []traceLocation
|
||||
}
|
||||
|
||||
func (t *traceLocations) String() string {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
var buf bytes.Buffer
|
||||
for i, tl := range t.locs {
|
||||
if i > 0 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
buf.WriteString(tl.String())
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Get always returns nil for this flag type since the struct is not exported
|
||||
func (t *traceLocations) Get() any { return nil }
|
||||
|
||||
func (t *traceLocations) Set(value string) error {
|
||||
var locs []traceLocation
|
||||
for _, s := range strings.Split(value, ",") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
loc, err := parseTraceLocation(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
locs = append(locs, loc)
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
atomic.StoreInt32(&t.locsLen, int32(len(locs)))
|
||||
t.locs = locs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *traceLocations) match(file string, line int) bool {
|
||||
if atomic.LoadInt32(&t.locsLen) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
for _, tl := range t.locs {
|
||||
if tl.match(file, line) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// severityFlag is an atomic flag.Value implementation for logsink.Severity.
|
||||
type severityFlag int32
|
||||
|
||||
func (s *severityFlag) get() logsink.Severity {
|
||||
return logsink.Severity(atomic.LoadInt32((*int32)(s)))
|
||||
}
|
||||
func (s *severityFlag) String() string { return strconv.FormatInt(int64(*s), 10) }
|
||||
func (s *severityFlag) Get() any { return s.get() }
|
||||
func (s *severityFlag) Set(value string) error {
|
||||
threshold, err := logsink.ParseSeverity(value)
|
||||
if err != nil {
|
||||
// Not a severity name. Try a raw number.
|
||||
v, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
threshold = logsink.Severity(v)
|
||||
if threshold < logsink.Info || threshold > logsink.Fatal {
|
||||
return fmt.Errorf("Severity %d out of range (min %d, max %d).", v, logsink.Info, logsink.Fatal)
|
||||
}
|
||||
}
|
||||
atomic.StoreInt32((*int32)(s), int32(threshold))
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
vflags verboseFlags // The -v and -vmodule flags.
|
||||
|
||||
logBacktraceAt traceLocations // The -log_backtrace_at flag.
|
||||
|
||||
// Boolean flags. Not handled atomically because the flag.Value interface
|
||||
// does not let us avoid the =true, and that shorthand is necessary for
|
||||
// compatibility. TODO: does this matter enough to fix? Seems unlikely.
|
||||
toStderr bool // The -logtostderr flag.
|
||||
alsoToStderr bool // The -alsologtostderr flag.
|
||||
|
||||
stderrThreshold severityFlag // The -stderrthreshold flag.
|
||||
)
|
||||
|
||||
// verboseEnabled returns whether the caller at the given depth should emit
|
||||
// verbose logs at the given level, with depth 0 identifying the caller of
|
||||
// verboseEnabled.
|
||||
func verboseEnabled(callerDepth int, level Level) bool {
|
||||
return vflags.enabled(callerDepth+1, level)
|
||||
}
|
||||
|
||||
// backtraceAt returns whether the logging call at the given function and line
|
||||
// should also emit a backtrace of the current call stack.
|
||||
func backtraceAt(file string, line int) bool {
|
||||
return logBacktraceAt.match(file, line)
|
||||
}
|
||||
|
||||
func init() {
|
||||
vflags.moduleLevelCache.Store(&sync.Map{})
|
||||
|
||||
flag.Var(&vflags.v, "v", "log level for V logs")
|
||||
flag.Var(vModuleFlag{&vflags}, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
|
||||
|
||||
flag.Var(&logBacktraceAt, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
|
||||
|
||||
stderrThreshold = severityFlag(logsink.Error)
|
||||
|
||||
flag.BoolVar(&toStderr, "logtostderr", false, "log to standard error instead of files")
|
||||
flag.BoolVar(&alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
|
||||
flag.Var(&stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
|
||||
}
|
||||
387
vendor/github.com/golang/glog/internal/logsink/logsink.go
generated
vendored
Normal file
387
vendor/github.com/golang/glog/internal/logsink/logsink.go
generated
vendored
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package logsink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog/internal/stackdump"
|
||||
)
|
||||
|
||||
// MaxLogMessageLen is the limit on length of a formatted log message, including
|
||||
// the standard line prefix and trailing newline.
|
||||
//
|
||||
// Chosen to match C++ glog.
|
||||
const MaxLogMessageLen = 15000
|
||||
|
||||
// A Severity is a severity at which a message can be logged.
|
||||
type Severity int8
|
||||
|
||||
// These constants identify the log levels in order of increasing severity.
|
||||
// A message written to a high-severity log file is also written to each
|
||||
// lower-severity log file.
|
||||
const (
|
||||
Info Severity = iota
|
||||
Warning
|
||||
Error
|
||||
|
||||
// Fatal contains logs written immediately before the process terminates.
|
||||
//
|
||||
// Sink implementations should not terminate the process themselves: the log
|
||||
// package will perform any necessary cleanup and terminate the process as
|
||||
// appropriate.
|
||||
Fatal
|
||||
)
|
||||
|
||||
func (s Severity) String() string {
|
||||
switch s {
|
||||
case Info:
|
||||
return "INFO"
|
||||
case Warning:
|
||||
return "WARNING"
|
||||
case Error:
|
||||
return "ERROR"
|
||||
case Fatal:
|
||||
return "FATAL"
|
||||
}
|
||||
return fmt.Sprintf("%T(%d)", s, s)
|
||||
}
|
||||
|
||||
// ParseSeverity returns the case-insensitive Severity value for the given string.
|
||||
func ParseSeverity(name string) (Severity, error) {
|
||||
name = strings.ToUpper(name)
|
||||
for s := Info; s <= Fatal; s++ {
|
||||
if s.String() == name {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
return -1, fmt.Errorf("logsink: invalid severity %q", name)
|
||||
}
|
||||
|
||||
// Meta is metadata about a logging call.
|
||||
type Meta struct {
|
||||
// Time is the time at which the log call was made.
|
||||
Time time.Time
|
||||
|
||||
// File is the source file from which the log entry originates.
|
||||
File string
|
||||
// Line is the line offset within the source file.
|
||||
Line int
|
||||
// Depth is the number of stack frames between the logsink and the log call.
|
||||
Depth int
|
||||
|
||||
Severity Severity
|
||||
|
||||
// Verbose indicates whether the call was made via "log.V". Log entries below
|
||||
// the current verbosity threshold are not sent to the sink.
|
||||
Verbose bool
|
||||
|
||||
// Thread ID. This can be populated with a thread ID from another source,
|
||||
// such as a system we are importing logs from. In the normal case, this
|
||||
// will be set to the process ID (PID), since Go doesn't have threads.
|
||||
Thread int64
|
||||
|
||||
// Stack trace starting in the logging function. May be nil.
|
||||
// A logsink should implement the StackWanter interface to request this.
|
||||
//
|
||||
// Even if WantStack returns false, this field may be set (e.g. if another
|
||||
// sink wants a stack trace).
|
||||
Stack *stackdump.Stack
|
||||
}
|
||||
|
||||
// Structured is a logging destination that accepts structured data as input.
|
||||
type Structured interface {
|
||||
// Printf formats according to a fmt.Printf format specifier and writes a log
|
||||
// entry. The precise result of formatting depends on the sink, but should
|
||||
// aim for consistency with fmt.Printf.
|
||||
//
|
||||
// Printf returns the number of bytes occupied by the log entry, which
|
||||
// may not be equal to the total number of bytes written.
|
||||
//
|
||||
// Printf returns any error encountered *if* it is severe enough that the log
|
||||
// package should terminate the process.
|
||||
//
|
||||
// The sink must not modify the *Meta parameter, nor reference it after
|
||||
// Printf has returned: it may be reused in subsequent calls.
|
||||
Printf(meta *Meta, format string, a ...any) (n int, err error)
|
||||
}
|
||||
|
||||
// StackWanter can be implemented by a logsink.Structured to indicate that it
|
||||
// wants a stack trace to accompany at least some of the log messages it receives.
|
||||
type StackWanter interface {
|
||||
// WantStack returns true if the sink requires a stack trace for a log message
|
||||
// with this metadata.
|
||||
//
|
||||
// NOTE: Returning true implies that meta.Stack will be non-nil. Returning
|
||||
// false does NOT imply that meta.Stack will be nil.
|
||||
WantStack(meta *Meta) bool
|
||||
}
|
||||
|
||||
// Text is a logging destination that accepts pre-formatted log lines (instead of
|
||||
// structured data).
|
||||
type Text interface {
|
||||
// Enabled returns whether this sink should output messages for the given
|
||||
// Meta. If the sink returns false for a given Meta, the Printf function will
|
||||
// not call Emit on it for the corresponding log message.
|
||||
Enabled(*Meta) bool
|
||||
|
||||
// Emit writes a pre-formatted text log entry (including any applicable
|
||||
// header) to the log. It returns the number of bytes occupied by the entry
|
||||
// (which may differ from the length of the passed-in slice).
|
||||
//
|
||||
// Emit returns any error encountered *if* it is severe enough that the log
|
||||
// package should terminate the process.
|
||||
//
|
||||
// The sink must not modify the *Meta parameter, nor reference it after
|
||||
// Printf has returned: it may be reused in subsequent calls.
|
||||
//
|
||||
// NOTE: When developing a text sink, keep in mind the surface in which the
|
||||
// logs will be displayed, and whether it's important that the sink be
|
||||
// resistent to tampering in the style of b/211428300. Standard text sinks
|
||||
// (like `stderrSink`) do not protect against this (e.g. by escaping
|
||||
// characters) because the cases where they would show user-influenced bytes
|
||||
// are vanishingly small.
|
||||
Emit(*Meta, []byte) (n int, err error)
|
||||
}
|
||||
|
||||
// bufs is a pool of *bytes.Buffer used in formatting log entries.
|
||||
var bufs sync.Pool // Pool of *bytes.Buffer.
|
||||
|
||||
// textPrintf formats a text log entry and emits it to all specified Text sinks.
|
||||
//
|
||||
// The returned n is the maximum across all Emit calls.
|
||||
// The returned err is the first non-nil error encountered.
|
||||
// Sinks that are disabled by configuration should return (0, nil).
|
||||
func textPrintf(m *Meta, textSinks []Text, format string, args ...any) (n int, err error) {
|
||||
// We expect at most file, stderr, and perhaps syslog. If there are more,
|
||||
// we'll end up allocating - no big deal.
|
||||
const maxExpectedTextSinks = 3
|
||||
var noAllocSinks [maxExpectedTextSinks]Text
|
||||
|
||||
sinks := noAllocSinks[:0]
|
||||
for _, s := range textSinks {
|
||||
if s.Enabled(m) {
|
||||
sinks = append(sinks, s)
|
||||
}
|
||||
}
|
||||
if len(sinks) == 0 && m.Severity != Fatal {
|
||||
return 0, nil // No TextSinks specified; don't bother formatting.
|
||||
}
|
||||
|
||||
bufi := bufs.Get()
|
||||
var buf *bytes.Buffer
|
||||
if bufi == nil {
|
||||
buf = bytes.NewBuffer(nil)
|
||||
bufi = buf
|
||||
} else {
|
||||
buf = bufi.(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
}
|
||||
|
||||
// Lmmdd hh:mm:ss.uuuuuu PID/GID file:line]
|
||||
//
|
||||
// The "PID" entry arguably ought to be TID for consistency with other
|
||||
// environments, but TID is not meaningful in a Go program due to the
|
||||
// multiplexing of goroutines across threads.
|
||||
//
|
||||
// Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
|
||||
// It's worth about 3X. Fprintf is hard.
|
||||
const severityChar = "IWEF"
|
||||
buf.WriteByte(severityChar[m.Severity])
|
||||
|
||||
_, month, day := m.Time.Date()
|
||||
hour, minute, second := m.Time.Clock()
|
||||
twoDigits(buf, int(month))
|
||||
twoDigits(buf, day)
|
||||
buf.WriteByte(' ')
|
||||
twoDigits(buf, hour)
|
||||
buf.WriteByte(':')
|
||||
twoDigits(buf, minute)
|
||||
buf.WriteByte(':')
|
||||
twoDigits(buf, second)
|
||||
buf.WriteByte('.')
|
||||
nDigits(buf, 6, uint64(m.Time.Nanosecond()/1000), '0')
|
||||
buf.WriteByte(' ')
|
||||
|
||||
nDigits(buf, 7, uint64(m.Thread), ' ')
|
||||
buf.WriteByte(' ')
|
||||
|
||||
{
|
||||
file := m.File
|
||||
if i := strings.LastIndex(file, "/"); i >= 0 {
|
||||
file = file[i+1:]
|
||||
}
|
||||
buf.WriteString(file)
|
||||
}
|
||||
|
||||
buf.WriteByte(':')
|
||||
{
|
||||
var tmp [19]byte
|
||||
buf.Write(strconv.AppendInt(tmp[:0], int64(m.Line), 10))
|
||||
}
|
||||
buf.WriteString("] ")
|
||||
|
||||
msgStart := buf.Len()
|
||||
fmt.Fprintf(buf, format, args...)
|
||||
if buf.Len() > MaxLogMessageLen-1 {
|
||||
buf.Truncate(MaxLogMessageLen - 1)
|
||||
}
|
||||
msgEnd := buf.Len()
|
||||
if b := buf.Bytes(); b[len(b)-1] != '\n' {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
|
||||
for _, s := range sinks {
|
||||
sn, sErr := s.Emit(m, buf.Bytes())
|
||||
if sn > n {
|
||||
n = sn
|
||||
}
|
||||
if sErr != nil && err == nil {
|
||||
err = sErr
|
||||
}
|
||||
}
|
||||
|
||||
if m.Severity == Fatal {
|
||||
savedM := *m
|
||||
fatalMessageStore(savedEntry{
|
||||
meta: &savedM,
|
||||
msg: buf.Bytes()[msgStart:msgEnd],
|
||||
})
|
||||
} else {
|
||||
bufs.Put(bufi)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
const digits = "0123456789"
|
||||
|
||||
// twoDigits formats a zero-prefixed two-digit integer to buf.
|
||||
func twoDigits(buf *bytes.Buffer, d int) {
|
||||
buf.WriteByte(digits[(d/10)%10])
|
||||
buf.WriteByte(digits[d%10])
|
||||
}
|
||||
|
||||
// nDigits formats an n-digit integer to buf, padding with pad on the left. It
|
||||
// assumes d != 0.
|
||||
func nDigits(buf *bytes.Buffer, n int, d uint64, pad byte) {
|
||||
var tmp [20]byte
|
||||
|
||||
cutoff := len(tmp) - n
|
||||
j := len(tmp) - 1
|
||||
for ; d > 0; j-- {
|
||||
tmp[j] = digits[d%10]
|
||||
d /= 10
|
||||
}
|
||||
for ; j >= cutoff; j-- {
|
||||
tmp[j] = pad
|
||||
}
|
||||
j++
|
||||
buf.Write(tmp[j:])
|
||||
}
|
||||
|
||||
// Printf writes a log entry to all registered TextSinks in this package, then
|
||||
// to all registered StructuredSinks.
|
||||
//
|
||||
// The returned n is the maximum across all Emit and Printf calls.
|
||||
// The returned err is the first non-nil error encountered.
|
||||
// Sinks that are disabled by configuration should return (0, nil).
|
||||
func Printf(m *Meta, format string, args ...any) (n int, err error) {
|
||||
m.Depth++
|
||||
n, err = textPrintf(m, TextSinks, format, args...)
|
||||
|
||||
for _, sink := range StructuredSinks {
|
||||
// TODO: Support TextSinks that implement StackWanter?
|
||||
if sw, ok := sink.(StackWanter); ok && sw.WantStack(m) {
|
||||
if m.Stack == nil {
|
||||
// First, try to find a stacktrace in args, otherwise generate one.
|
||||
for _, arg := range args {
|
||||
if stack, ok := arg.(stackdump.Stack); ok {
|
||||
m.Stack = &stack
|
||||
break
|
||||
}
|
||||
}
|
||||
if m.Stack == nil {
|
||||
stack := stackdump.Caller( /* skipDepth = */ m.Depth)
|
||||
m.Stack = &stack
|
||||
}
|
||||
}
|
||||
}
|
||||
sn, sErr := sink.Printf(m, format, args...)
|
||||
if sn > n {
|
||||
n = sn
|
||||
}
|
||||
if sErr != nil && err == nil {
|
||||
err = sErr
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// The sets of sinks to which logs should be written.
|
||||
//
|
||||
// These must only be modified during package init, and are read-only thereafter.
|
||||
var (
|
||||
// StructuredSinks is the set of Structured sink instances to which logs
|
||||
// should be written.
|
||||
StructuredSinks []Structured
|
||||
|
||||
// TextSinks is the set of Text sink instances to which logs should be
|
||||
// written.
|
||||
//
|
||||
// These are registered separately from Structured sink implementations to
|
||||
// avoid the need to repeat the work of formatting a message for each Text
|
||||
// sink that writes it. The package-level Printf function writes to both sets
|
||||
// independenty, so a given log destination should only register a Structured
|
||||
// *or* a Text sink (not both).
|
||||
TextSinks []Text
|
||||
)
|
||||
|
||||
type savedEntry struct {
|
||||
meta *Meta
|
||||
msg []byte
|
||||
}
|
||||
|
||||
// StructuredTextWrapper is a Structured sink which forwards logs to a set of Text sinks.
|
||||
//
|
||||
// The purpose of this sink is to allow applications to intercept logging calls before they are
|
||||
// serialized and sent to Text sinks. For example, if one needs to redact PII from logging
|
||||
// arguments before they reach STDERR, one solution would be to do the redacting in a Structured
|
||||
// sink that forwards logs to a StructuredTextWrapper instance, and make STDERR a child of that
|
||||
// StructuredTextWrapper instance. This is how one could set this up in their application:
|
||||
//
|
||||
// func init() {
|
||||
//
|
||||
// wrapper := logsink.StructuredTextWrapper{TextSinks: logsink.TextSinks}
|
||||
// // sanitizersink will intercept logs and remove PII
|
||||
// sanitizer := sanitizersink{Sink: &wrapper}
|
||||
// logsink.StructuredSinks = append(logsink.StructuredSinks, &sanitizer)
|
||||
// logsink.TextSinks = nil
|
||||
//
|
||||
// }
|
||||
type StructuredTextWrapper struct {
|
||||
// TextSinks is the set of Text sinks that should receive logs from this
|
||||
// StructuredTextWrapper instance.
|
||||
TextSinks []Text
|
||||
}
|
||||
|
||||
// Printf forwards logs to all Text sinks registered in the StructuredTextWrapper.
|
||||
func (w *StructuredTextWrapper) Printf(meta *Meta, format string, args ...any) (n int, err error) {
|
||||
return textPrintf(meta, w.TextSinks, format, args...)
|
||||
}
|
||||
35
vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go
generated
vendored
Normal file
35
vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package logsink
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func fatalMessageStore(e savedEntry) {
|
||||
// Only put a new one in if we haven't assigned before.
|
||||
atomic.CompareAndSwapPointer(&fatalMessage, nil, unsafe.Pointer(&e))
|
||||
}
|
||||
|
||||
var fatalMessage unsafe.Pointer // savedEntry stored with CompareAndSwapPointer
|
||||
|
||||
// FatalMessage returns the Meta and message contents of the first message
|
||||
// logged with Fatal severity, or false if none has occurred.
|
||||
func FatalMessage() (*Meta, []byte, bool) {
|
||||
e := (*savedEntry)(atomic.LoadPointer(&fatalMessage))
|
||||
if e == nil {
|
||||
return nil, nil, false
|
||||
}
|
||||
return e.meta, e.msg, true
|
||||
}
|
||||
|
||||
// DoNotUseRacyFatalMessage is FatalMessage, but worse.
|
||||
//
|
||||
//go:norace
|
||||
//go:nosplit
|
||||
func DoNotUseRacyFatalMessage() (*Meta, []byte, bool) {
|
||||
e := (*savedEntry)(fatalMessage)
|
||||
if e == nil {
|
||||
return nil, nil, false
|
||||
}
|
||||
return e.meta, e.msg, true
|
||||
}
|
||||
127
vendor/github.com/golang/glog/internal/stackdump/stackdump.go
generated
vendored
Normal file
127
vendor/github.com/golang/glog/internal/stackdump/stackdump.go
generated
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package stackdump provides wrappers for runtime.Stack and runtime.Callers
|
||||
// with uniform support for skipping caller frames.
|
||||
//
|
||||
// ⚠ Unlike the functions in the runtime package, these may allocate a
|
||||
// non-trivial quantity of memory: use them with care. ⚠
|
||||
package stackdump
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// runtimeStackSelfFrames is 1 if runtime.Stack includes the call to
|
||||
// runtime.Stack itself or 0 if it does not.
|
||||
//
|
||||
// As of 2016-04-27, the gccgo compiler includes runtime.Stack but the gc
|
||||
// compiler does not.
|
||||
var runtimeStackSelfFrames = func() int {
|
||||
for n := 1 << 10; n < 1<<20; n *= 2 {
|
||||
buf := make([]byte, n)
|
||||
n := runtime.Stack(buf, false)
|
||||
if bytes.Contains(buf[:n], []byte("runtime.Stack")) {
|
||||
return 1
|
||||
} else if n < len(buf) || bytes.Count(buf, []byte("\n")) >= 3 {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}()
|
||||
|
||||
// Stack is a stack dump for a single goroutine.
|
||||
type Stack struct {
|
||||
// Text is a representation of the stack dump in a human-readable format.
|
||||
Text []byte
|
||||
|
||||
// PC is a representation of the stack dump using raw program counter values.
|
||||
PC []uintptr
|
||||
}
|
||||
|
||||
func (s Stack) String() string { return string(s.Text) }
|
||||
|
||||
// Caller returns the Stack dump for the calling goroutine, starting skipDepth
|
||||
// frames before the caller of Caller. (Caller(0) provides a dump starting at
|
||||
// the caller of this function.)
|
||||
func Caller(skipDepth int) Stack {
|
||||
return Stack{
|
||||
Text: CallerText(skipDepth + 1),
|
||||
PC: CallerPC(skipDepth + 1),
|
||||
}
|
||||
}
|
||||
|
||||
// CallerText returns a textual dump of the stack starting skipDepth frames before
|
||||
// the caller. (CallerText(0) provides a dump starting at the caller of this
|
||||
// function.)
|
||||
func CallerText(skipDepth int) []byte {
|
||||
for n := 1 << 10; ; n *= 2 {
|
||||
buf := make([]byte, n)
|
||||
n := runtime.Stack(buf, false)
|
||||
if n < len(buf) {
|
||||
return pruneFrames(skipDepth+1+runtimeStackSelfFrames, buf[:n])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CallerPC returns a dump of the program counters of the stack starting
|
||||
// skipDepth frames before the caller. (CallerPC(0) provides a dump starting at
|
||||
// the caller of this function.)
|
||||
func CallerPC(skipDepth int) []uintptr {
|
||||
for n := 1 << 8; ; n *= 2 {
|
||||
buf := make([]uintptr, n)
|
||||
n := runtime.Callers(skipDepth+2, buf)
|
||||
if n < len(buf) {
|
||||
return buf[:n]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pruneFrames removes the topmost skipDepth frames of the first goroutine in a
|
||||
// textual stack dump. It overwrites the passed-in slice.
|
||||
//
|
||||
// If there are fewer than skipDepth frames in the first goroutine's stack,
|
||||
// pruneFrames prunes it to an empty stack and leaves the remaining contents
|
||||
// intact.
|
||||
func pruneFrames(skipDepth int, stack []byte) []byte {
|
||||
headerLen := 0
|
||||
for i, c := range stack {
|
||||
if c == '\n' {
|
||||
headerLen = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
if headerLen == 0 {
|
||||
return stack // No header line - not a well-formed stack trace.
|
||||
}
|
||||
|
||||
skipLen := headerLen
|
||||
skipNewlines := skipDepth * 2
|
||||
for ; skipLen < len(stack) && skipNewlines > 0; skipLen++ {
|
||||
c := stack[skipLen]
|
||||
if c != '\n' {
|
||||
continue
|
||||
}
|
||||
skipNewlines--
|
||||
skipLen++
|
||||
if skipNewlines == 0 || skipLen == len(stack) || stack[skipLen] == '\n' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
pruned := stack[skipLen-headerLen:]
|
||||
copy(pruned, stack[:headerLen])
|
||||
return pruned
|
||||
}
|
||||
8
vendor/github.com/golang/protobuf/jsonpb/decode.go
generated
vendored
8
vendor/github.com/golang/protobuf/jsonpb/decode.go
generated
vendored
|
|
@ -386,8 +386,14 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error
|
|||
}
|
||||
|
||||
func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
|
||||
if fd.Cardinality() == protoreflect.Repeated {
|
||||
return false
|
||||
}
|
||||
if md := fd.Message(); md != nil {
|
||||
return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
|
||||
return md.FullName() == "google.protobuf.Value"
|
||||
}
|
||||
if ed := fd.Enum(); ed != nil {
|
||||
return ed.FullName() == "google.protobuf.NullValue"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
62
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
62
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/empty/empty.proto
|
||||
|
||||
package empty
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// Symbols defined in public import of google/protobuf/empty.proto.
|
||||
|
||||
type Empty = emptypb.Empty
|
||||
|
||||
var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{
|
||||
0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
|
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{}
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() }
|
||||
func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() {
|
||||
if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes,
|
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs,
|
||||
}.Build()
|
||||
File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue