Bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc

Bumps [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) from 1.15.1 to 1.16.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.15.1...v1.16.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-06-14 08:48:26 +00:00
committed by Ralf Haferkamp
parent 666a166932
commit fdaa7f71eb
29 changed files with 1902 additions and 1053 deletions

12
go.mod
View File

@@ -84,7 +84,7 @@ require (
go.opentelemetry.io/contrib/zpages v0.42.0
go.opentelemetry.io/otel v1.16.0
go.opentelemetry.io/otel/exporters/jaeger v1.15.1
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0
go.opentelemetry.io/otel/sdk v1.16.0
go.opentelemetry.io/otel/trace v1.16.0
golang.org/x/crypto v0.9.0
@@ -95,8 +95,8 @@ require (
golang.org/x/sync v0.2.0
golang.org/x/term v0.8.0
golang.org/x/text v0.9.0
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f
google.golang.org/grpc v1.54.0
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4
google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.30.0
gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v2 v2.4.0
@@ -204,7 +204,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v1.8.9 // indirect
@@ -311,8 +311,8 @@ require (
go.etcd.io/etcd/client/v3 v3.5.7 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/atomic v1.10.0 // indirect

27
go.sum
View File

@@ -32,8 +32,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o=
@@ -115,7 +115,7 @@ cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x
cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE=
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
@@ -901,8 +901,9 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -1670,12 +1671,12 @@ go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
go.opentelemetry.io/otel/exporters/jaeger v1.15.1 h1:x3SLvwli0OyAJapNcOIzf1xXBRBA+HD3elrMQmFfmXo=
go.opentelemetry.io/otel/exporters/jaeger v1.15.1/go.mod h1:0Ck9b5oLL/bFZvfAEEqtrb1U0jZXjm5fWXMCOCG3vvM=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1 h1:XYDQtNzdb2T4uM1pku2m76eSMDJgqhJ+6KzkqgQBALc=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1/go.mod h1:uOTV75+LOzV+ODmL8ahRLWkFA3eQcSC2aAsbxIu4duk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1 h1:tyoeaUh8REKay72DVYsSEBYV18+fGONe+YYPaOxgLoE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1/go.mod h1:HUSnrjQQ19KX9ECjpQxufsF+3ioD3zISPMlauTPZu2g=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1 h1:pIfoG5IAZFzp9EUlJzdSkpUwpaUAAnD+Ru1nBLTACIQ=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1/go.mod h1:poNKBqF5+nR/6ke2oGTDjHfksrsHDOHXAl2g4+9ONsY=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo=
go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE=
@@ -2307,8 +2308,8 @@ google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZV
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -2349,8 +2350,8 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e h1:m7aQHHqd0q89mRwhwS9Bx2rjyl/hsFAeta+uGrHsQaU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=

1229
vendor/github.com/golang/glog/glog.go generated vendored
View File

File diff suppressed because it is too large Load Diff

View File

@@ -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
View 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")
}

View 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...)
}

View 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
}

View 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
}

View File

@@ -2,7 +2,7 @@
[![Go Reference](https://pkg.go.dev/badge/go.opentelemetry.io/otel/exporters/otlp/otlptrace.svg)](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)
[OpenTelemetry Protocol Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.5.0/specification/protocol/exporter.md) implementation.
[OpenTelemetry Protocol Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/protocol/exporter.md) implementation.
## Installation
@@ -36,7 +36,7 @@ The `otlptracehttp` package implements a client for the span exporter that sends
The following environment variables can be used (instead of options objects) to
override the default configuration. For more information about how each of
these environment variables is interpreted, see [the OpenTelemetry
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/protocol/exporter.md).
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/protocol/exporter.md).
| Environment variable | Option | Default value |
| ------------------------------------------------------------------------ |------------------------------ | -------------------------------------------------------- |

View File

@@ -19,7 +19,7 @@ import (
)
// GetUserAgentHeader returns an OTLP header value form "OTel OTLP Exporter Go/{{ .Version }}"
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#user-agent
// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/protocol/exporter.md#user-agent
func GetUserAgentHeader() string {
return "OTel OTLP Exporter Go/" + otlptrace.Version()
}

View File

@@ -16,5 +16,5 @@ package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
// Version is the current release version of the OpenTelemetry OTLP trace exporter in use.
func Version() string {
return "1.15.1"
return "1.16.0"
}

View File

@@ -20,10 +20,6 @@ How to get your contributions merged smoothly and quickly.
both author's & review's time is wasted. Create more PRs to address different
concerns and everyone will be happy.
- For speculative changes, consider opening an issue and discussing it first. If
you are suggesting a behavioral or API change, consider starting with a [gRFC
proposal](https://github.com/grpc/proposal).
- If you are searching for features to work on, issues labeled [Status: Help
Wanted](https://github.com/grpc/grpc-go/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Status%3A+Help+Wanted%22)
is a great place to start. These issues are well-documented and usually can be

View File

@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.30.0
// protoc v4.22.0
// source: grpc/binlog/v1/binarylog.proto

View File

@@ -244,19 +244,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
}
}()
scSet := false
if cc.dopts.scChan != nil {
// Try to get an initial service config.
select {
case sc, ok := <-cc.dopts.scChan:
if ok {
cc.sc = &sc
cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc})
scSet = true
}
default:
}
}
if cc.dopts.bs == nil {
cc.dopts.bs = backoff.DefaultExponential
}
@@ -272,7 +259,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
}
channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority)
if cc.dopts.scChan != nil && !scSet {
if cc.dopts.scChan != nil {
// Blocking wait for the initial service config.
select {
case sc, ok := <-cc.dopts.scChan:

View File

@@ -295,6 +295,9 @@ func withBackoff(bs internalbackoff.Strategy) DialOption {
// WithBlock returns a DialOption which makes callers of Dial block until the
// underlying connection is up. Without this, Dial returns immediately and
// connecting the server happens in background.
//
// Use of this feature is not recommended. For more information, please see:
// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
func WithBlock() DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.block = true
@@ -306,6 +309,9 @@ func WithBlock() DialOption {
// the context.DeadlineExceeded error.
// Implies WithBlock()
//
// Use of this feature is not recommended. For more information, please see:
// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
@@ -448,6 +454,9 @@ func withBinaryLogger(bl binarylog.Logger) DialOption {
// FailOnNonTempDialError only affects the initial dial, and does not do
// anything useful unless you are also using WithBlock().
//
// Use of this feature is not recommended. For more information, please see:
// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a

View File

@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.30.0
// protoc v4.22.0
// source: grpc/health/v1/health.proto

View File

@@ -79,7 +79,7 @@ var (
// XDSFederation indicates whether federation support is enabled, which can
// be enabled by setting the environment variable
// "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true".
XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", false)
XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", true)
// XDSRLS indicates whether processing of Cluster Specifier plugins and
// support for the RLS CLuster Specifier is enabled, which can be enabled by

View File

@@ -0,0 +1,65 @@
/*
*
* Copyright 2022 gRPC authors.
*
* 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 grpcsync
import (
"context"
"google.golang.org/grpc/internal/buffer"
)
// CallbackSerializer provides a mechanism to schedule callbacks in a
// synchronized manner. It provides a FIFO guarantee on the order of execution
// of scheduled callbacks. New callbacks can be scheduled by invoking the
// Schedule() method.
//
// This type is safe for concurrent access.
type CallbackSerializer struct {
callbacks *buffer.Unbounded
}
// NewCallbackSerializer returns a new CallbackSerializer instance. The provided
// context will be passed to the scheduled callbacks. Users should cancel the
// provided context to shutdown the CallbackSerializer. It is guaranteed that no
// callbacks will be executed once this context is canceled.
func NewCallbackSerializer(ctx context.Context) *CallbackSerializer {
t := &CallbackSerializer{callbacks: buffer.NewUnbounded()}
go t.run(ctx)
return t
}
// Schedule adds a callback to be scheduled after existing callbacks are run.
//
// Callbacks are expected to honor the context when performing any blocking
// operations, and should return early when the context is canceled.
func (t *CallbackSerializer) Schedule(f func(ctx context.Context)) {
t.callbacks.Put(f)
}
func (t *CallbackSerializer) run(ctx context.Context) {
for ctx.Err() == nil {
select {
case <-ctx.Done():
return
case callback := <-t.callbacks.Get():
t.callbacks.Load()
callback.(func(ctx context.Context))(ctx)
}
}
}

View File

@@ -30,6 +30,7 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/status"
)
@@ -488,12 +489,13 @@ type loopyWriter struct {
bdpEst *bdpEstimator
draining bool
conn net.Conn
logger *grpclog.PrefixLogger
// Side-specific handlers
ssGoAwayHandler func(*goAway) (bool, error)
}
func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn) *loopyWriter {
func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger) *loopyWriter {
var buf bytes.Buffer
l := &loopyWriter{
side: s,
@@ -507,6 +509,7 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato
hEnc: hpack.NewEncoder(&buf),
bdpEst: bdpEst,
conn: conn,
logger: logger,
}
return l
}
@@ -536,8 +539,8 @@ const minBatchSize = 1000
// left open to allow the I/O error to be encountered by the reader instead.
func (l *loopyWriter) run() (err error) {
defer func() {
if logger.V(logLevel) {
logger.Infof("transport: loopyWriter exiting with error: %v", err)
if l.logger.V(logLevel) {
l.logger.Infof("loopyWriter exiting with error: %v", err)
}
if !isIOError(err) {
l.framer.writer.Flush()
@@ -636,8 +639,8 @@ func (l *loopyWriter) headerHandler(h *headerFrame) error {
if l.side == serverSide {
str, ok := l.estdStreams[h.streamID]
if !ok {
if logger.V(logLevel) {
logger.Warningf("transport: loopy doesn't recognize the stream: %d", h.streamID)
if l.logger.V(logLevel) {
l.logger.Infof("Unrecognized streamID %d in loopyWriter", h.streamID)
}
return nil
}
@@ -692,8 +695,8 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He
l.hBuf.Reset()
for _, f := range hf {
if err := l.hEnc.WriteField(f); err != nil {
if logger.V(logLevel) {
logger.Warningf("transport: loopyWriter.writeHeader encountered error while encoding headers: %v", err)
if l.logger.V(logLevel) {
l.logger.Warningf("Encountered error while encoding headers: %v", err)
}
}
}

View File

@@ -39,6 +39,7 @@ import (
"golang.org/x/net/http2"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer"
@@ -83,6 +84,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s
contentSubtype: contentSubtype,
stats: stats,
}
st.logger = prefixLoggerForServerHandlerTransport(st)
if v := r.Header.Get("grpc-timeout"); v != "" {
to, err := decodeTimeout(v)
@@ -150,13 +152,14 @@ type serverHandlerTransport struct {
// TODO make sure this is consistent across handler_server and http2_server
contentSubtype string
stats []stats.Handler
stats []stats.Handler
logger *grpclog.PrefixLogger
}
func (ht *serverHandlerTransport) Close(err error) {
ht.closeOnce.Do(func() {
if logger.V(logLevel) {
logger.Infof("Closing serverHandlerTransport: %v", err)
if ht.logger.V(logLevel) {
ht.logger.Infof("Closing: %v", err)
}
close(ht.closedCh)
})

View File

@@ -38,6 +38,7 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/channelz"
icredentials "google.golang.org/grpc/internal/credentials"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
imetadata "google.golang.org/grpc/internal/metadata"
@@ -145,6 +146,7 @@ type http2Client struct {
bufferPool *bufferPool
connectionID uint64
logger *grpclog.PrefixLogger
}
func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, useProxy bool, grpcUA string) (net.Conn, error) {
@@ -244,7 +246,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
if err := connectCtx.Err(); err != nil {
// connectCtx expired before exiting the function. Hard close the connection.
if logger.V(logLevel) {
logger.Infof("newClientTransport: aborting due to connectCtx: %v", err)
logger.Infof("Aborting due to connect deadline expiring: %v", err)
}
conn.Close()
}
@@ -346,6 +348,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
bufferPool: newBufferPool(),
onClose: onClose,
}
t.logger = prefixLoggerForClientTransport(t)
// Add peer information to the http2client context.
t.ctx = peer.NewContext(t.ctx, t.getPeer())
@@ -444,7 +447,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
return nil, err
}
go func() {
t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn)
t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
t.loopy.run()
close(t.writerDone)
}()
@@ -782,7 +785,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
s.id = h.streamID
s.fc = &inFlow{limit: uint32(t.initialWindowSize)}
t.mu.Lock()
if t.activeStreams == nil { // Can be niled from Close().
if t.state == draining || t.activeStreams == nil { // Can be niled from Close().
t.mu.Unlock()
return false // Don't create a stream if the transport is already closed.
}
@@ -859,8 +862,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
}
}
if transportDrainRequired {
if logger.V(logLevel) {
logger.Infof("transport: t.nextID > MaxStreamID. Draining")
if t.logger.V(logLevel) {
t.logger.Infof("Draining transport: t.nextID > MaxStreamID")
}
t.GracefulClose()
}
@@ -952,8 +955,8 @@ func (t *http2Client) Close(err error) {
t.mu.Unlock()
return
}
if logger.V(logLevel) {
logger.Infof("transport: closing: %v", err)
if t.logger.V(logLevel) {
t.logger.Infof("Closing: %v", err)
}
// Call t.onClose ASAP to prevent the client from attempting to create new
// streams.
@@ -1009,8 +1012,8 @@ func (t *http2Client) GracefulClose() {
t.mu.Unlock()
return
}
if logger.V(logLevel) {
logger.Infof("transport: GracefulClose called")
if t.logger.V(logLevel) {
t.logger.Infof("GracefulClose called")
}
t.onClose(GoAwayInvalid)
t.state = draining
@@ -1174,8 +1177,8 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
}
statusCode, ok := http2ErrConvTab[f.ErrCode]
if !ok {
if logger.V(logLevel) {
logger.Warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error: %v", f.ErrCode)
if t.logger.V(logLevel) {
t.logger.Infof("Received a RST_STREAM frame with code %q, but found no mapped gRPC status", f.ErrCode)
}
statusCode = codes.Unknown
}

View File

@@ -35,7 +35,9 @@ import (
"github.com/golang/protobuf/proto"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/internal/pretty"
"google.golang.org/grpc/internal/syscall"
"google.golang.org/grpc/codes"
@@ -129,6 +131,8 @@ type http2Server struct {
// This lock may not be taken if mu is already held.
maxStreamMu sync.Mutex
maxStreamID uint32 // max stream ID ever seen
logger *grpclog.PrefixLogger
}
// NewServerTransport creates a http2 transport with conn and configuration
@@ -267,6 +271,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
czData: new(channelzData),
bufferPool: newBufferPool(),
}
t.logger = prefixLoggerForServerTransport(t)
// Add peer information to the http2server context.
t.ctx = peer.NewContext(t.ctx, t.getPeer())
@@ -331,7 +336,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
t.handleSettings(sf)
go func() {
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn)
t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
t.loopy.run()
close(t.writerDone)
@@ -425,8 +430,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
// "Transports must consider requests containing the Connection header
// as malformed." - A41
case "connection":
if logger.V(logLevel) {
logger.Errorf("transport: http2Server.operateHeaders parsed a :connection header which makes a request malformed as per the HTTP/2 spec")
if t.logger.V(logLevel) {
t.logger.Infof("Received a HEADERS frame with a :connection header which makes the request malformed, as per the HTTP/2 spec")
}
protocolError = true
default:
@@ -436,7 +441,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
v, err := decodeMetadataHeader(hf.Name, hf.Value)
if err != nil {
headerError = status.Newf(codes.Internal, "malformed binary metadata %q in header %q: %v", hf.Value, hf.Name, err)
logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
t.logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
break
}
mdata[hf.Name] = append(mdata[hf.Name], v)
@@ -450,8 +455,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
// error, this takes precedence over a client not speaking gRPC.
if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 {
errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"]))
if logger.V(logLevel) {
logger.Errorf("transport: %v", errMsg)
if t.logger.V(logLevel) {
t.logger.Infof("Aborting the stream early: %v", errMsg)
}
t.controlBuf.put(&earlyAbortStream{
httpStatus: http.StatusBadRequest,
@@ -545,9 +550,9 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
}
if httpMethod != http.MethodPost {
t.mu.Unlock()
errMsg := fmt.Sprintf("http2Server.operateHeaders parsed a :method field: %v which should be POST", httpMethod)
if logger.V(logLevel) {
logger.Infof("transport: %v", errMsg)
errMsg := fmt.Sprintf("Received a HEADERS frame with :method %q which should be POST", httpMethod)
if t.logger.V(logLevel) {
t.logger.Infof("Aborting the stream early: %v", errMsg)
}
t.controlBuf.put(&earlyAbortStream{
httpStatus: 405,
@@ -563,8 +568,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
var err error
if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil {
t.mu.Unlock()
if logger.V(logLevel) {
logger.Infof("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err)
if t.logger.V(logLevel) {
t.logger.Infof("Aborting the stream early due to InTapHandle failure: %v", err)
}
stat, ok := status.FromError(err)
if !ok {
@@ -638,8 +643,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
if err != nil {
if se, ok := err.(http2.StreamError); ok {
if logger.V(logLevel) {
logger.Warningf("transport: http2Server.HandleStreams encountered http2.StreamError: %v", se)
if t.logger.V(logLevel) {
t.logger.Warningf("Encountered http2.StreamError: %v", se)
}
t.mu.Lock()
s := t.activeStreams[se.StreamID]
@@ -682,8 +687,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
case *http2.GoAwayFrame:
// TODO: Handle GoAway from the client appropriately.
default:
if logger.V(logLevel) {
logger.Errorf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
if t.logger.V(logLevel) {
t.logger.Infof("Received unsupported frame type %T", frame)
}
}
}
@@ -942,8 +947,8 @@ func (t *http2Server) checkForHeaderListSize(it interface{}) bool {
var sz int64
for _, f := range hdrFrame.hf {
if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
if logger.V(logLevel) {
logger.Errorf("header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
if t.logger.V(logLevel) {
t.logger.Infof("Header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
}
return false
}
@@ -1056,7 +1061,7 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
stBytes, err := proto.Marshal(p)
if err != nil {
// TODO: return error instead, when callers are able to handle it.
logger.Errorf("transport: failed to marshal rpc status: %v, error: %v", p, err)
t.logger.Errorf("Failed to marshal rpc status: %s, error: %v", pretty.ToJSON(p), err)
} else {
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
}
@@ -1171,8 +1176,8 @@ func (t *http2Server) keepalive() {
select {
case <-ageTimer.C:
// Close the connection after grace period.
if logger.V(logLevel) {
logger.Infof("transport: closing server transport due to maximum connection age.")
if t.logger.V(logLevel) {
t.logger.Infof("Closing server transport due to maximum connection age")
}
t.controlBuf.put(closeConnection{})
case <-t.done:
@@ -1223,8 +1228,8 @@ func (t *http2Server) Close(err error) {
t.mu.Unlock()
return
}
if logger.V(logLevel) {
logger.Infof("transport: closing: %v", err)
if t.logger.V(logLevel) {
t.logger.Infof("Closing: %v", err)
}
t.state = closing
streams := t.activeStreams
@@ -1232,8 +1237,8 @@ func (t *http2Server) Close(err error) {
t.mu.Unlock()
t.controlBuf.finish()
close(t.done)
if err := t.conn.Close(); err != nil && logger.V(logLevel) {
logger.Infof("transport: error closing conn during Close: %v", err)
if err := t.conn.Close(); err != nil && t.logger.V(logLevel) {
t.logger.Infof("Error closing underlying net.Conn during Close: %v", err)
}
channelz.RemoveEntry(t.channelzID)
// Cancel all active streams.

View File

@@ -38,7 +38,6 @@ import (
"golang.org/x/net/http2/hpack"
spb "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
@@ -86,7 +85,6 @@ var (
// 504 Gateway timeout - UNAVAILABLE.
http.StatusGatewayTimeout: codes.Unavailable,
}
logger = grpclog.Component("transport")
)
// isReservedHeader checks whether hdr belongs to HTTP2 headers

View File

@@ -0,0 +1,40 @@
/*
*
* Copyright 2023 gRPC authors.
*
* 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 transport
import (
"fmt"
"google.golang.org/grpc/grpclog"
internalgrpclog "google.golang.org/grpc/internal/grpclog"
)
var logger = grpclog.Component("transport")
func prefixLoggerForServerTransport(p *http2Server) *internalgrpclog.PrefixLogger {
return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-transport %p] ", p))
}
func prefixLoggerForServerHandlerTransport(p *serverHandlerTransport) *internalgrpclog.PrefixLogger {
return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-handler-transport %p] ", p))
}
func prefixLoggerForClientTransport(p *http2Client) *internalgrpclog.PrefixLogger {
return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[client-transport %p] ", p))
}

View File

@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.30.0
// protoc v4.22.0
// grpc/reflection/v1alpha/reflection.proto is a deprecated file.
@@ -39,11 +39,14 @@ const (
)
// The message sent by the client when calling ServerReflectionInfo method.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ServerReflectionRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"`
// To use reflection service, the client should set one of the following
// fields in message_request. The server distinguishes requests by their
@@ -91,6 +94,7 @@ func (*ServerReflectionRequest) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{0}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionRequest) GetHost() string {
if x != nil {
return x.Host
@@ -105,6 +109,7 @@ func (m *ServerReflectionRequest) GetMessageRequest() isServerReflectionRequest_
return nil
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionRequest) GetFileByFilename() string {
if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_FileByFilename); ok {
return x.FileByFilename
@@ -112,6 +117,7 @@ func (x *ServerReflectionRequest) GetFileByFilename() string {
return ""
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionRequest) GetFileContainingSymbol() string {
if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_FileContainingSymbol); ok {
return x.FileContainingSymbol
@@ -119,6 +125,7 @@ func (x *ServerReflectionRequest) GetFileContainingSymbol() string {
return ""
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionRequest) GetFileContainingExtension() *ExtensionRequest {
if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_FileContainingExtension); ok {
return x.FileContainingExtension
@@ -126,6 +133,7 @@ func (x *ServerReflectionRequest) GetFileContainingExtension() *ExtensionRequest
return nil
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionRequest) GetAllExtensionNumbersOfType() string {
if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_AllExtensionNumbersOfType); ok {
return x.AllExtensionNumbersOfType
@@ -133,6 +141,7 @@ func (x *ServerReflectionRequest) GetAllExtensionNumbersOfType() string {
return ""
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionRequest) GetListServices() string {
if x, ok := x.GetMessageRequest().(*ServerReflectionRequest_ListServices); ok {
return x.ListServices
@@ -146,6 +155,8 @@ type isServerReflectionRequest_MessageRequest interface {
type ServerReflectionRequest_FileByFilename struct {
// Find a proto file by the file name.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
FileByFilename string `protobuf:"bytes,3,opt,name=file_by_filename,json=fileByFilename,proto3,oneof"`
}
@@ -153,12 +164,16 @@ type ServerReflectionRequest_FileContainingSymbol struct {
// Find the proto file that declares the given fully-qualified symbol name.
// This field should be a fully-qualified symbol name
// (e.g. <package>.<service>[.<method>] or <package>.<type>).
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
FileContainingSymbol string `protobuf:"bytes,4,opt,name=file_containing_symbol,json=fileContainingSymbol,proto3,oneof"`
}
type ServerReflectionRequest_FileContainingExtension struct {
// Find the proto file which defines an extension extending the given
// message type with the given field number.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
FileContainingExtension *ExtensionRequest `protobuf:"bytes,5,opt,name=file_containing_extension,json=fileContainingExtension,proto3,oneof"`
}
@@ -171,12 +186,16 @@ type ServerReflectionRequest_AllExtensionNumbersOfType struct {
// StatusCode::UNIMPLEMENTED if it's not implemented.
// This field should be a fully-qualified type name. The format is
// <package>.<type>
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
AllExtensionNumbersOfType string `protobuf:"bytes,6,opt,name=all_extension_numbers_of_type,json=allExtensionNumbersOfType,proto3,oneof"`
}
type ServerReflectionRequest_ListServices struct {
// List the full names of registered services. The content will not be
// checked.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ListServices string `protobuf:"bytes,7,opt,name=list_services,json=listServices,proto3,oneof"`
}
@@ -193,14 +212,19 @@ func (*ServerReflectionRequest_ListServices) isServerReflectionRequest_MessageRe
// The type name and extension number sent by the client when requesting
// file_containing_extension.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ExtensionRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Fully-qualified type name. The format should be <package>.<type>
ContainingType string `protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3" json:"containing_type,omitempty"`
ExtensionNumber int32 `protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"`
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ContainingType string `protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3" json:"containing_type,omitempty"`
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ExtensionNumber int32 `protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"`
}
func (x *ExtensionRequest) Reset() {
@@ -235,6 +259,7 @@ func (*ExtensionRequest) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{1}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ExtensionRequest) GetContainingType() string {
if x != nil {
return x.ContainingType
@@ -242,6 +267,7 @@ func (x *ExtensionRequest) GetContainingType() string {
return ""
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ExtensionRequest) GetExtensionNumber() int32 {
if x != nil {
return x.ExtensionNumber
@@ -250,12 +276,16 @@ func (x *ExtensionRequest) GetExtensionNumber() int32 {
}
// The message sent by the server to answer ServerReflectionInfo method.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ServerReflectionResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ValidHost string `protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3" json:"valid_host,omitempty"`
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ValidHost string `protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3" json:"valid_host,omitempty"`
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
OriginalRequest *ServerReflectionRequest `protobuf:"bytes,2,opt,name=original_request,json=originalRequest,proto3" json:"original_request,omitempty"`
// The server set one of the following fields according to the message_request
// in the request.
@@ -301,6 +331,7 @@ func (*ServerReflectionResponse) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{2}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionResponse) GetValidHost() string {
if x != nil {
return x.ValidHost
@@ -308,6 +339,7 @@ func (x *ServerReflectionResponse) GetValidHost() string {
return ""
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionResponse) GetOriginalRequest() *ServerReflectionRequest {
if x != nil {
return x.OriginalRequest
@@ -322,6 +354,7 @@ func (m *ServerReflectionResponse) GetMessageResponse() isServerReflectionRespon
return nil
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionResponse) GetFileDescriptorResponse() *FileDescriptorResponse {
if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_FileDescriptorResponse); ok {
return x.FileDescriptorResponse
@@ -329,6 +362,7 @@ func (x *ServerReflectionResponse) GetFileDescriptorResponse() *FileDescriptorRe
return nil
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionResponse) GetAllExtensionNumbersResponse() *ExtensionNumberResponse {
if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_AllExtensionNumbersResponse); ok {
return x.AllExtensionNumbersResponse
@@ -336,6 +370,7 @@ func (x *ServerReflectionResponse) GetAllExtensionNumbersResponse() *ExtensionNu
return nil
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionResponse) GetListServicesResponse() *ListServiceResponse {
if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_ListServicesResponse); ok {
return x.ListServicesResponse
@@ -343,6 +378,7 @@ func (x *ServerReflectionResponse) GetListServicesResponse() *ListServiceRespons
return nil
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServerReflectionResponse) GetErrorResponse() *ErrorResponse {
if x, ok := x.GetMessageResponse().(*ServerReflectionResponse_ErrorResponse); ok {
return x.ErrorResponse
@@ -361,21 +397,29 @@ type ServerReflectionResponse_FileDescriptorResponse struct {
// FileDescriptorResponse message to encapsulate the repeated fields.
// The reflection service is allowed to avoid sending FileDescriptorProtos
// that were previously sent in response to earlier requests in the stream.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
FileDescriptorResponse *FileDescriptorResponse `protobuf:"bytes,4,opt,name=file_descriptor_response,json=fileDescriptorResponse,proto3,oneof"`
}
type ServerReflectionResponse_AllExtensionNumbersResponse struct {
// This message is used to answer all_extension_numbers_of_type requst.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
AllExtensionNumbersResponse *ExtensionNumberResponse `protobuf:"bytes,5,opt,name=all_extension_numbers_response,json=allExtensionNumbersResponse,proto3,oneof"`
}
type ServerReflectionResponse_ListServicesResponse struct {
// This message is used to answer list_services request.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ListServicesResponse *ListServiceResponse `protobuf:"bytes,6,opt,name=list_services_response,json=listServicesResponse,proto3,oneof"`
}
type ServerReflectionResponse_ErrorResponse struct {
// This message is used when an error occurs.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ErrorResponse *ErrorResponse `protobuf:"bytes,7,opt,name=error_response,json=errorResponse,proto3,oneof"`
}
@@ -392,6 +436,8 @@ func (*ServerReflectionResponse_ErrorResponse) isServerReflectionResponse_Messag
// Serialized FileDescriptorProto messages sent by the server answering
// a file_by_filename, file_containing_symbol, or file_containing_extension
// request.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type FileDescriptorResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -400,6 +446,8 @@ type FileDescriptorResponse struct {
// Serialized FileDescriptorProto messages. We avoid taking a dependency on
// descriptor.proto, which uses proto2 only features, by making them opaque
// bytes instead.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
FileDescriptorProto [][]byte `protobuf:"bytes,1,rep,name=file_descriptor_proto,json=fileDescriptorProto,proto3" json:"file_descriptor_proto,omitempty"`
}
@@ -435,6 +483,7 @@ func (*FileDescriptorResponse) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{3}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *FileDescriptorResponse) GetFileDescriptorProto() [][]byte {
if x != nil {
return x.FileDescriptorProto
@@ -444,6 +493,8 @@ func (x *FileDescriptorResponse) GetFileDescriptorProto() [][]byte {
// A list of extension numbers sent by the server answering
// all_extension_numbers_of_type request.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ExtensionNumberResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -451,7 +502,10 @@ type ExtensionNumberResponse struct {
// Full name of the base type, including the package name. The format
// is <package>.<type>
BaseTypeName string `protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3" json:"base_type_name,omitempty"`
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
BaseTypeName string `protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3" json:"base_type_name,omitempty"`
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ExtensionNumber []int32 `protobuf:"varint,2,rep,packed,name=extension_number,json=extensionNumber,proto3" json:"extension_number,omitempty"`
}
@@ -487,6 +541,7 @@ func (*ExtensionNumberResponse) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{4}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ExtensionNumberResponse) GetBaseTypeName() string {
if x != nil {
return x.BaseTypeName
@@ -494,6 +549,7 @@ func (x *ExtensionNumberResponse) GetBaseTypeName() string {
return ""
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ExtensionNumberResponse) GetExtensionNumber() []int32 {
if x != nil {
return x.ExtensionNumber
@@ -502,6 +558,8 @@ func (x *ExtensionNumberResponse) GetExtensionNumber() []int32 {
}
// A list of ServiceResponse sent by the server answering list_services request.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ListServiceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -509,6 +567,8 @@ type ListServiceResponse struct {
// The information of each service may be expanded in the future, so we use
// ServiceResponse message to encapsulate it.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
Service []*ServiceResponse `protobuf:"bytes,1,rep,name=service,proto3" json:"service,omitempty"`
}
@@ -544,6 +604,7 @@ func (*ListServiceResponse) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{5}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ListServiceResponse) GetService() []*ServiceResponse {
if x != nil {
return x.Service
@@ -553,6 +614,8 @@ func (x *ListServiceResponse) GetService() []*ServiceResponse {
// The information of a single service used by ListServiceResponse to answer
// list_services request.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ServiceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -560,6 +623,8 @@ type ServiceResponse struct {
// Full name of a registered service, including its package name. The format
// is <package>.<service>
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
@@ -595,6 +660,7 @@ func (*ServiceResponse) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{6}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ServiceResponse) GetName() string {
if x != nil {
return x.Name
@@ -603,13 +669,18 @@ func (x *ServiceResponse) GetName() string {
}
// The error code and error message sent by the server when an error occurs.
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
type ErrorResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// This field uses the error codes defined in grpc::StatusCode.
ErrorCode int32 `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"`
//
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ErrorCode int32 `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"`
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
}
@@ -645,6 +716,7 @@ func (*ErrorResponse) Descriptor() ([]byte, []int) {
return file_grpc_reflection_v1alpha_reflection_proto_rawDescGZIP(), []int{7}
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ErrorResponse) GetErrorCode() int32 {
if x != nil {
return x.ErrorCode
@@ -652,6 +724,7 @@ func (x *ErrorResponse) GetErrorCode() int32 {
return 0
}
// Deprecated: The entire proto file grpc/reflection/v1alpha/reflection.proto is marked as deprecated.
func (x *ErrorResponse) GetErrorMessage() string {
if x != nil {
return x.ErrorMessage

View File

@@ -43,7 +43,6 @@ import (
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/internal/transport"
@@ -146,7 +145,7 @@ type Server struct {
channelzID *channelz.Identifier
czData *channelzData
serverWorkerChannels []chan *serverWorkerData
serverWorkerChannel chan *serverWorkerData
}
type serverOptions struct {
@@ -561,40 +560,38 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
const serverWorkerResetThreshold = 1 << 16
// serverWorkers blocks on a *transport.Stream channel forever and waits for
// data to be fed by serveStreams. This allows different requests to be
// data to be fed by serveStreams. This allows multiple requests to be
// processed by the same goroutine, removing the need for expensive stack
// re-allocations (see the runtime.morestack problem [1]).
//
// [1] https://github.com/golang/go/issues/18138
func (s *Server) serverWorker(ch chan *serverWorkerData) {
// To make sure all server workers don't reset at the same time, choose a
// random number of iterations before resetting.
threshold := serverWorkerResetThreshold + grpcrand.Intn(serverWorkerResetThreshold)
for completed := 0; completed < threshold; completed++ {
data, ok := <-ch
func (s *Server) serverWorker() {
for completed := 0; completed < serverWorkerResetThreshold; completed++ {
data, ok := <-s.serverWorkerChannel
if !ok {
return
}
s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream))
data.wg.Done()
s.handleSingleStream(data)
}
go s.serverWorker(ch)
go s.serverWorker()
}
// initServerWorkers creates worker goroutines and channels to process incoming
func (s *Server) handleSingleStream(data *serverWorkerData) {
defer data.wg.Done()
s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream))
}
// initServerWorkers creates worker goroutines and a channel to process incoming
// connections to reduce the time spent overall on runtime.morestack.
func (s *Server) initServerWorkers() {
s.serverWorkerChannels = make([]chan *serverWorkerData, s.opts.numServerWorkers)
s.serverWorkerChannel = make(chan *serverWorkerData)
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
s.serverWorkerChannels[i] = make(chan *serverWorkerData)
go s.serverWorker(s.serverWorkerChannels[i])
go s.serverWorker()
}
}
func (s *Server) stopServerWorkers() {
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
close(s.serverWorkerChannels[i])
}
close(s.serverWorkerChannel)
}
// NewServer creates a gRPC server which has no service registered and has not
@@ -946,26 +943,21 @@ func (s *Server) serveStreams(st transport.ServerTransport) {
defer st.Close(errors.New("finished serving streams for the server transport"))
var wg sync.WaitGroup
var roundRobinCounter uint32
st.HandleStreams(func(stream *transport.Stream) {
wg.Add(1)
if s.opts.numServerWorkers > 0 {
data := &serverWorkerData{st: st, wg: &wg, stream: stream}
select {
case s.serverWorkerChannels[atomic.AddUint32(&roundRobinCounter, 1)%s.opts.numServerWorkers] <- data:
case s.serverWorkerChannel <- data:
return
default:
// If all stream workers are busy, fallback to the default code path.
go func() {
s.handleStream(st, stream, s.traceInfo(st, stream))
wg.Done()
}()
}
} else {
go func() {
defer wg.Done()
s.handleStream(st, stream, s.traceInfo(st, stream))
}()
}
go func() {
defer wg.Done()
s.handleStream(st, stream, s.traceInfo(st, stream))
}()
}, func(ctx context.Context, method string) context.Context {
if !EnableTracing {
return ctx

View File

@@ -77,7 +77,9 @@ func FromProto(s *spb.Status) *Status {
// FromError returns a Status representation of err.
//
// - If err was produced by this package or implements the method `GRPCStatus()
// *Status`, the appropriate Status is returned.
// *Status`, or if err wraps a type satisfying this, the appropriate Status is
// returned. For wrapped errors, the message returned contains the entire
// err.Error() text and not just the wrapped status.
//
// - If err is nil, a Status is returned with codes.OK and no message.
//
@@ -88,10 +90,15 @@ func FromError(err error) (s *Status, ok bool) {
if err == nil {
return nil, true
}
if se, ok := err.(interface {
GRPCStatus() *Status
}); ok {
return se.GRPCStatus(), true
type grpcstatus interface{ GRPCStatus() *Status }
if gs, ok := err.(grpcstatus); ok {
return gs.GRPCStatus(), true
}
var gs grpcstatus
if errors.As(err, &gs) {
p := gs.GRPCStatus().Proto()
p.Message = err.Error()
return status.FromProto(p), true
}
return New(codes.Unknown, err.Error()), false
}
@@ -103,19 +110,16 @@ func Convert(err error) *Status {
return s
}
// Code returns the Code of the error if it is a Status error, codes.OK if err
// is nil, or codes.Unknown otherwise.
// Code returns the Code of the error if it is a Status error or if it wraps a
// Status error. If that is not the case, it returns codes.OK if err is nil, or
// codes.Unknown otherwise.
func Code(err error) codes.Code {
// Don't use FromError to avoid allocation of OK status.
if err == nil {
return codes.OK
}
if se, ok := err.(interface {
GRPCStatus() *Status
}); ok {
return se.GRPCStatus().Code()
}
return codes.Unknown
return Convert(err).Code()
}
// FromContextError converts a context error or wrapped context error into a

View File

@@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
const Version = "1.54.0"
const Version = "1.55.0"

16
vendor/modules.txt vendored
View File

@@ -1012,9 +1012,11 @@ github.com/golang/geo/r1
github.com/golang/geo/r2
github.com/golang/geo/r3
github.com/golang/geo/s1
# github.com/golang/glog v1.0.0
## explicit; go 1.11
# github.com/golang/glog v1.1.0
## explicit; go 1.18
github.com/golang/glog
github.com/golang/glog/internal/logsink
github.com/golang/glog/internal/stackdump
# github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
## explicit
github.com/golang/groupcache/lru
@@ -1841,16 +1843,16 @@ go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent
go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger
go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore
go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift
# go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1
# go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0
## explicit; go 1.19
go.opentelemetry.io/otel/exporters/otlp/internal/retry
# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1
# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0
## explicit; go 1.19
go.opentelemetry.io/otel/exporters/otlp/otlptrace
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform
# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1
# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0
## explicit; go 1.19
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
# go.opentelemetry.io/otel/metric v1.16.0
@@ -2043,7 +2045,7 @@ google.golang.org/appengine/internal/log
google.golang.org/appengine/internal/remote_api
google.golang.org/appengine/internal/urlfetch
google.golang.org/appengine/urlfetch
# google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f
# google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4
## explicit; go 1.19
google.golang.org/genproto/googleapis/api
google.golang.org/genproto/googleapis/api/annotations
@@ -2051,7 +2053,7 @@ google.golang.org/genproto/googleapis/api/httpbody
google.golang.org/genproto/googleapis/rpc/errdetails
google.golang.org/genproto/googleapis/rpc/status
google.golang.org/genproto/protobuf/field_mask
# google.golang.org/grpc v1.54.0
# google.golang.org/grpc v1.55.0
## explicit; go 1.17
google.golang.org/grpc
google.golang.org/grpc/attributes