mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-05-19 09:46:57 +03:00
Compare commits
23 Commits
weakpointe
...
poc/jaeger
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fc1172910 | ||
|
|
87c1cfdf0d | ||
|
|
921850f7c9 | ||
|
|
7c04b07b16 | ||
|
|
57ac1302de | ||
|
|
f6854855b0 | ||
|
|
c65a4f1ec9 | ||
|
|
cdcf5a8061 | ||
|
|
1cfd9e05f2 | ||
|
|
fd491b3cc2 | ||
|
|
aab4de6066 | ||
|
|
58ba8569e2 | ||
|
|
b302a44302 | ||
|
|
9a8f5037a0 | ||
|
|
2aa883a1bd | ||
|
|
67f5d0aec9 | ||
|
|
247ffff910 | ||
|
|
df2c973e50 | ||
|
|
615d719fac | ||
|
|
6028ca11de | ||
|
|
7202ce8a5b | ||
|
|
2267070297 | ||
|
|
1b5b234804 |
@@ -40,6 +40,40 @@ type CommonParams struct {
|
||||
DebugRemoteAddr string
|
||||
}
|
||||
|
||||
// GetJaegerCommonParams returns CommonParams for Jaeger.
|
||||
func GetJaegerCommonParams() (*CommonParams, error) {
|
||||
// Extract tenantID
|
||||
var tenantID = logstorage.TenantID{
|
||||
AccountID: 0,
|
||||
ProjectID: 0,
|
||||
}
|
||||
timeField := "_time"
|
||||
|
||||
msgFields := []string{"_msg"}
|
||||
streamFields := []string{"_stream"}
|
||||
ignoreFields := []string{"_ignore"}
|
||||
|
||||
extraFields := []logstorage.Field{}
|
||||
|
||||
debug := false
|
||||
debugRequestURI := ""
|
||||
debugRemoteAddr := ""
|
||||
|
||||
cp := &CommonParams{
|
||||
TenantID: tenantID,
|
||||
TimeField: timeField,
|
||||
MsgFields: msgFields,
|
||||
StreamFields: streamFields,
|
||||
IgnoreFields: ignoreFields,
|
||||
ExtraFields: extraFields,
|
||||
Debug: debug,
|
||||
DebugRequestURI: debugRequestURI,
|
||||
DebugRemoteAddr: debugRemoteAddr,
|
||||
}
|
||||
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
// GetCommonParams returns CommonParams from r.
|
||||
func GetCommonParams(r *http.Request) (*CommonParams, error) {
|
||||
// Extract tenantID
|
||||
|
||||
45
app/vlinsert/jaeger/jaeger.go
Normal file
45
app/vlinsert/jaeger/jaeger.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package jaeger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jaegertracing/jaeger/storage/dependencystore"
|
||||
"github.com/jaegertracing/jaeger/storage/spanstore"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
jaeger2 "github.com/VictoriaMetrics/VictoriaMetrics/app/vlselect/jaeger"
|
||||
"github.com/jaegertracing/jaeger/plugin/storage/grpc/shared"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// MustInit - init for Jaeger gRPC storage backend
|
||||
func MustInit() {
|
||||
lis, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", 17271))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
var opts []grpc.ServerOption
|
||||
grpcServer := grpc.NewServer(opts...)
|
||||
|
||||
handler := shared.NewGRPCHandler(&shared.GRPCHandlerStorageImpl{
|
||||
SpanReader: func() spanstore.Reader { return &jaeger2.SpanReaderPluginServer{} },
|
||||
SpanWriter: func() spanstore.Writer { return &SpanWriterPluginServer{} },
|
||||
DependencyReader: func() dependencystore.Reader { return &jaeger2.SpanReaderPluginServer{} },
|
||||
ArchiveSpanReader: func() spanstore.Reader { return nil },
|
||||
ArchiveSpanWriter: func() spanstore.Writer { return nil },
|
||||
StreamingSpanWriter: func() spanstore.Writer { return nil },
|
||||
})
|
||||
|
||||
//proto.RegisterSpanWriterPluginServer(grpcServer, &SpanWriterPluginServer{})
|
||||
//proto.RegisterSpanReaderPluginServer(grpcServer, &jaeger2.SpanReaderPluginServer{})
|
||||
err = handler.Register(grpcServer)
|
||||
if err != nil {
|
||||
panic("unable to register Jaeger gRPC handler: " + err.Error())
|
||||
}
|
||||
|
||||
go grpcServer.Serve(lis)
|
||||
}
|
||||
|
||||
// MustStop - stop for Jaeger gRPC storage backend
|
||||
func MustStop() {}
|
||||
44
app/vlinsert/jaeger/span_writer_plugin_server.go
Normal file
44
app/vlinsert/jaeger/span_writer_plugin_server.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package jaeger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jaegertracing/jaeger/model"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vlinsert/insertutils"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/jaeger"
|
||||
)
|
||||
|
||||
// A SpanWriterPluginServer represents plugin Jaeger interface to write gRPC storage backend
|
||||
type SpanWriterPluginServer struct {
|
||||
}
|
||||
|
||||
var bbufPool bytesutil.ByteBufferPool
|
||||
|
||||
// WriteSpan writes spans
|
||||
func (s *SpanWriterPluginServer) WriteSpan(ctx context.Context, span *model.Span) error {
|
||||
if span == nil {
|
||||
return fmt.Errorf("span not found")
|
||||
}
|
||||
|
||||
cp, err := insertutils.GetJaegerCommonParams()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lmp := cp.NewLogMessageProcessor("jaeger")
|
||||
defer lmp.MustClose()
|
||||
// bytes buf here
|
||||
bbuf := bbufPool.Get()
|
||||
defer bbufPool.Put(bbuf)
|
||||
bbuf.Reset()
|
||||
fields, streamFields, err := jaeger.SpanToFields(span)
|
||||
lmp.AddRow(span.StartTime.UnixNano(), fields, streamFields)
|
||||
// bytes bf clear
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SpanWriterPluginServer) Close() error {
|
||||
return nil
|
||||
}
|
||||
42
app/vlinsert/jaeger/test_client/grpc_client_test.go
Normal file
42
app/vlinsert/jaeger/test_client/grpc_client_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/jaeger/proto"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func newSpanReaderPluginClient(t *testing.T) proto.SpanReaderPluginClient {
|
||||
conn, err := grpc.NewClient(fmt.Sprintf("0.0.0.0:%d", 17271), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
t.Fatalf("cannot connect to server: %v", err)
|
||||
}
|
||||
return proto.NewSpanReaderPluginClient(conn)
|
||||
}
|
||||
|
||||
func newSpanWriterPluginClient(t *testing.T) proto.SpanWriterPluginClient {
|
||||
conn, err := grpc.NewClient(fmt.Sprintf("0.0.0.0:%d", 17271), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
t.Fatalf("cannot connect to server: %v", err)
|
||||
}
|
||||
return proto.NewSpanWriterPluginClient(conn)
|
||||
}
|
||||
|
||||
func TestSpanWriter(t *testing.T) {
|
||||
// This is NOT a unit test. Please run the VictoriaLogs before executing this test.
|
||||
client := newSpanWriterPluginClient(t)
|
||||
req := &proto.WriteSpanRequest{}
|
||||
resp, err := client.WriteSpan(context.Background(), req)
|
||||
fmt.Println(resp, err)
|
||||
}
|
||||
|
||||
func TestSpanReaderGetOperations(t *testing.T) {
|
||||
// This is NOT a unit test. Please run the VictoriaLogs before executing this test.
|
||||
client := newSpanReaderPluginClient(t)
|
||||
req := &proto.GetOperationsRequest{}
|
||||
resp, err := client.GetOperations(context.Background(), req)
|
||||
fmt.Println(resp, err)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package vlinsert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vlinsert/jaeger"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -17,11 +18,13 @@ import (
|
||||
// Init initializes vlinsert
|
||||
func Init() {
|
||||
syslog.MustInit()
|
||||
jaeger.MustInit()
|
||||
}
|
||||
|
||||
// Stop stops vlinsert
|
||||
func Stop() {
|
||||
syslog.MustStop()
|
||||
jaeger.MustStop()
|
||||
}
|
||||
|
||||
// RequestHandler handles insert requests for VictoriaLogs
|
||||
|
||||
293
app/vlselect/jaeger/span_reader_plugin_server.go
Normal file
293
app/vlselect/jaeger/span_reader_plugin_server.go
Normal file
@@ -0,0 +1,293 @@
|
||||
package jaeger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/jaeger"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/jaegertracing/jaeger/model"
|
||||
"github.com/jaegertracing/jaeger/storage/spanstore"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vlstorage"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logstorage"
|
||||
)
|
||||
|
||||
// A SpanReaderPluginServer represents a Jaeger interface to read from gRPC storage backend
|
||||
type SpanReaderPluginServer struct{}
|
||||
|
||||
type row struct {
|
||||
timestamp int64
|
||||
fields []logstorage.Field
|
||||
}
|
||||
|
||||
func (s *SpanReaderPluginServer) GetTrace(ctx context.Context, traceID model.TraceID) (*model.Trace, error) {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
logger.Infof("GetTrace finished in %dms", time.Since(start).Milliseconds())
|
||||
}()
|
||||
qStr := fmt.Sprintf("%s:%s", jaeger.TraceID, traceID.String())
|
||||
q, err := logstorage.ParseQueryAtTimestamp(qStr, time.Now().UnixNano())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse query [%s]: %s", qStr, err)
|
||||
}
|
||||
|
||||
var rows []row
|
||||
var rowsLock sync.Mutex
|
||||
writeBlock := func(_ uint, timestamps []int64, columns []logstorage.BlockColumn) {
|
||||
clonedColumnNames := make([]string, len(columns))
|
||||
for i, c := range columns {
|
||||
clonedColumnNames[i] = strings.Clone(c.Name)
|
||||
}
|
||||
|
||||
for i, timestamp := range timestamps {
|
||||
fields := make([]logstorage.Field, len(columns))
|
||||
for j := range columns {
|
||||
if columns[j].Values[i] != "" {
|
||||
fields = append(fields, logstorage.Field{Name: clonedColumnNames[j], Value: strings.Clone(columns[j].Values[i])})
|
||||
}
|
||||
}
|
||||
|
||||
rowsLock.Lock()
|
||||
rows = append(rows, row{
|
||||
timestamp: timestamp,
|
||||
fields: fields,
|
||||
})
|
||||
rowsLock.Unlock()
|
||||
}
|
||||
}
|
||||
logger.Infof("GetTrace query: %s", q.String())
|
||||
if err = vlstorage.RunQuery(context.TODO(), []logstorage.TenantID{{AccountID: 0, ProjectID: 0}}, q, writeBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spans := make([]*model.Span, 0, len(rows))
|
||||
for i := range rows {
|
||||
sp, err := jaeger.FieldsToSpan(rows[i].fields)
|
||||
if err != nil {
|
||||
logger.Errorf("cannot unmarshal log fields [%v] to span: %s", rows[i].fields, err)
|
||||
continue
|
||||
}
|
||||
spans = append(spans, sp)
|
||||
}
|
||||
trace := &model.Trace{
|
||||
Spans: spans,
|
||||
}
|
||||
return trace, nil
|
||||
}
|
||||
|
||||
func (s *SpanReaderPluginServer) GetServices(ctx context.Context) ([]string, error) {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
logger.Infof("GetServices finished in %dms", time.Since(start).Milliseconds())
|
||||
}()
|
||||
qStr := "*"
|
||||
q, err := logstorage.ParseQueryAtTimestamp(qStr, time.Now().UnixNano())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse query [%s]: %s", qStr, err)
|
||||
}
|
||||
q.AddTimeFilter(0, time.Now().UnixNano())
|
||||
logger.Infof("GetServices StreamFieldValues query: %s", q.String())
|
||||
serviceHits, err := vlstorage.GetStreamFieldValues(ctx, []logstorage.TenantID{{AccountID: 0, ProjectID: 0}}, q, jaeger.ProcessServiceName, uint64(1000))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serviceList := make([]string, 0)
|
||||
for i := range serviceHits {
|
||||
serviceList = append(serviceList, serviceHits[i].Value)
|
||||
}
|
||||
|
||||
return serviceList, nil
|
||||
}
|
||||
|
||||
func (s *SpanReaderPluginServer) GetOperations(ctx context.Context, req spanstore.OperationQueryParameters) ([]spanstore.Operation, error) {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
logger.Infof("GetOperations finished in %dms", time.Since(start).Milliseconds())
|
||||
}()
|
||||
qStr := fmt.Sprintf("_stream:{%s=\"%s\"}", jaeger.ProcessServiceName, req.ServiceName) // todo spankind filter
|
||||
q, err := logstorage.ParseQueryAtTimestamp(qStr, time.Now().UnixNano())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse query [%s]: %s", qStr, err)
|
||||
}
|
||||
logger.Infof("GetOperations StreamFieldValues query: %s", q.String())
|
||||
operationHits, err := vlstorage.GetStreamFieldValues(ctx, []logstorage.TenantID{{AccountID: 0, ProjectID: 0}}, q, jaeger.OperationName, uint64(1000))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
operationList := make([]spanstore.Operation, 0)
|
||||
for i := range operationHits {
|
||||
operationList = append(operationList, spanstore.Operation{Name: operationHits[i].Value})
|
||||
}
|
||||
return operationList, nil
|
||||
}
|
||||
|
||||
func (s *SpanReaderPluginServer) FindTraces(ctx context.Context, query *spanstore.TraceQueryParameters) ([]*model.Trace, error) {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
logger.Infof("FindTraces finished in %dms", time.Since(start).Milliseconds())
|
||||
}()
|
||||
traceIDs, err := s.FindTraceIDs(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(traceIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
traceIDStrList := make([]string, 0, len(traceIDs))
|
||||
for _, traceID := range traceIDs {
|
||||
traceIDStrList = append(traceIDStrList, traceID.String())
|
||||
}
|
||||
qStr := fmt.Sprintf(jaeger.TraceID+":in(%s)", strings.Join(traceIDStrList, ","))
|
||||
|
||||
q, err := logstorage.ParseQueryAtTimestamp(qStr, time.Now().UnixNano())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse query [%s]: %s", qStr, err)
|
||||
}
|
||||
q.AddTimeFilter(query.StartTimeMin.UnixNano(), query.StartTimeMax.UnixNano())
|
||||
|
||||
var rows []row
|
||||
var rowsLock sync.Mutex
|
||||
writeBlock := func(_ uint, timestamps []int64, columns []logstorage.BlockColumn) {
|
||||
clonedColumnNames := make([]string, len(columns))
|
||||
for i, c := range columns {
|
||||
clonedColumnNames[i] = strings.Clone(c.Name)
|
||||
}
|
||||
|
||||
for i, timestamp := range timestamps {
|
||||
fields := make([]logstorage.Field, 0, len(columns))
|
||||
for j := range columns {
|
||||
if columns[j].Values[i] != "" {
|
||||
fields = append(fields, logstorage.Field{Name: clonedColumnNames[j], Value: strings.Clone(columns[j].Values[i])})
|
||||
}
|
||||
}
|
||||
|
||||
rowsLock.Lock()
|
||||
rows = append(rows, row{
|
||||
timestamp: timestamp,
|
||||
fields: fields,
|
||||
})
|
||||
rowsLock.Unlock()
|
||||
}
|
||||
}
|
||||
logger.Infof("FindTraces query: %s", q.String())
|
||||
if err = vlstorage.RunQuery(context.TODO(), []logstorage.TenantID{{AccountID: 0, ProjectID: 0}}, q, writeBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tracesMap := make(map[string]*model.Trace)
|
||||
traces := make([]*model.Trace, len(traceIDs), len(traceIDs))
|
||||
for i := range traceIDs {
|
||||
traces[i] = &model.Trace{}
|
||||
tracesMap[traceIDs[i].String()] = traces[i]
|
||||
}
|
||||
|
||||
for i := range rows {
|
||||
sp, err := jaeger.FieldsToSpan(rows[i].fields)
|
||||
if err != nil {
|
||||
logger.Errorf("cannot unmarshal log fields [%v] to span: %s", rows[i].fields, err)
|
||||
continue
|
||||
}
|
||||
|
||||
tracesMap[sp.TraceID.String()].Spans = append(tracesMap[sp.TraceID.String()].Spans, sp)
|
||||
}
|
||||
return traces, nil
|
||||
}
|
||||
|
||||
func (s *SpanReaderPluginServer) FindTraceIDs(ctx context.Context, query *spanstore.TraceQueryParameters) ([]model.TraceID, error) {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
logger.Infof("FindTraceIDs finished in %dms", time.Since(start).Milliseconds())
|
||||
}()
|
||||
qStr := ""
|
||||
if svcName := query.ServiceName; svcName != "" {
|
||||
qStr += fmt.Sprintf("AND _stream:{"+jaeger.ProcessServiceName+"=\"%s\"} ", svcName)
|
||||
}
|
||||
if operationName := query.OperationName; operationName != "" {
|
||||
qStr += fmt.Sprintf("AND _stream:{"+jaeger.OperationName+"=\"%s\"} ", operationName)
|
||||
}
|
||||
|
||||
if tags := query.Tags; len(tags) > 0 {
|
||||
for k, v := range tags {
|
||||
qStr += fmt.Sprintf(`AND "`+jaeger.TagKey+`":=%s `, k, v)
|
||||
}
|
||||
}
|
||||
if durationMin := query.DurationMin; durationMin > 0 {
|
||||
qStr += fmt.Sprintf("AND "+jaeger.Duration+":>%d ", durationMin.Nanoseconds())
|
||||
}
|
||||
if durationMax := query.DurationMax; durationMax > 0 {
|
||||
qStr += fmt.Sprintf("AND duration:<%d ", durationMax.Nanoseconds())
|
||||
}
|
||||
qStr = strings.TrimLeft(qStr+" | last 1 by (_time) partition by ("+jaeger.TraceID+") | fields _time, "+jaeger.TraceID+" | sort by (_time) desc", "AND ")
|
||||
|
||||
logger.Infof("FindTraceIDs query debug: %s", qStr)
|
||||
q, err := logstorage.ParseQueryAtTimestamp(qStr, query.StartTimeMax.UnixNano())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse query [%s]: %s", qStr, err)
|
||||
}
|
||||
q.AddPipeLimit(uint64(query.NumTraces))
|
||||
|
||||
traceIDSs, err := findTraceIDsSplitTimeRange(q, query.StartTimeMin, query.StartTimeMax, query.NumTraces)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
traceIDList := make([]model.TraceID, 0, query.NumTraces)
|
||||
for _, v := range traceIDSs {
|
||||
tid, err := model.TraceIDFromString(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot unmarshal [%s]: %s", v, err)
|
||||
}
|
||||
traceIDList = append(traceIDList, tid)
|
||||
}
|
||||
return traceIDList, nil
|
||||
}
|
||||
|
||||
// findTraceIDsSplitTimeRange try to search from the nearest time range of the end time.
|
||||
// if the result already met requirement of `limit`, return.
|
||||
// otherwise, amplify the time range to 5x and search again, until the start time exceed the input.
|
||||
func findTraceIDsSplitTimeRange(q *logstorage.Query, startTime, endTime time.Time, limit int) ([]string, error) {
|
||||
step := time.Minute
|
||||
startTimeCurrent := endTime.Add(-step)
|
||||
traceIDList := make([]string, 0, 10)
|
||||
writeBlock := func(_ uint, _ []int64, columns []logstorage.BlockColumn) {
|
||||
for i := range columns {
|
||||
if columns[i].Name == "trace_id" {
|
||||
for _, v := range columns[i].Values {
|
||||
traceIDList = append(traceIDList, v)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for startTimeCurrent.After(startTime) {
|
||||
qClone := q.CloneWithTimeFilter(endTime.UnixNano(), startTimeCurrent.UnixNano(), endTime.UnixNano())
|
||||
logger.Infof("FindTraces query: %s", qClone.String())
|
||||
if err := vlstorage.RunQuery(context.TODO(), []logstorage.TenantID{{AccountID: 0, ProjectID: 0}}, qClone, writeBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(traceIDList) == limit {
|
||||
return traceIDList, nil
|
||||
}
|
||||
traceIDList = traceIDList[:0]
|
||||
step *= 5
|
||||
startTimeCurrent = startTimeCurrent.Add(-step)
|
||||
}
|
||||
|
||||
// one last try with input time range
|
||||
qClone := q.CloneWithTimeFilter(endTime.UnixNano(), startTimeCurrent.UnixNano(), endTime.UnixNano())
|
||||
logger.Infof("FindTraces query: %s", qClone.String())
|
||||
if err := vlstorage.RunQuery(context.TODO(), []logstorage.TenantID{{AccountID: 0, ProjectID: 0}}, qClone, writeBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return traceIDList, nil
|
||||
}
|
||||
|
||||
func (s *SpanReaderPluginServer) GetDependencies(ctx context.Context, endTs time.Time, lookback time.Duration) ([]model.DependencyLink, error) {
|
||||
return []model.DependencyLink{}, nil
|
||||
}
|
||||
41
go.mod
41
go.mod
@@ -30,11 +30,12 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/snappy v0.0.4
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/googleapis/gax-go/v2 v2.14.1
|
||||
github.com/googleapis/gax-go/v2 v2.13.0
|
||||
github.com/influxdata/influxdb v1.11.8
|
||||
github.com/jaegertracing/jaeger v1.55.0
|
||||
github.com/klauspost/compress v1.17.11
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
github.com/prometheus/prometheus v0.301.0
|
||||
github.com/prometheus/prometheus v0.54.1
|
||||
github.com/urfave/cli/v2 v2.27.5
|
||||
github.com/valyala/fastjson v1.6.4
|
||||
github.com/valyala/fastrand v1.1.0
|
||||
@@ -45,16 +46,17 @@ require (
|
||||
golang.org/x/net v0.34.0
|
||||
golang.org/x/oauth2 v0.25.0
|
||||
golang.org/x/sys v0.29.0
|
||||
google.golang.org/api v0.216.0
|
||||
google.golang.org/api v0.195.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.118.0 // indirect
|
||||
cloud.google.com/go/auth v0.14.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
|
||||
cloud.google.com/go v0.115.1 // indirect
|
||||
cloud.google.com/go/auth v0.9.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/iam v1.3.1 // indirect
|
||||
cloud.google.com/go/iam v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
@@ -81,62 +83,69 @@ require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dennwc/varint v1.0.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.3 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.61.0 // indirect
|
||||
github.com/prometheus/common/sigv4 v0.1.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/prometheus/sigv4 v0.1.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.23.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.14.1 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.117.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.58.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
|
||||
go.opentelemetry.io/otel v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250106144421-5f5ef82da422 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.32.0 // indirect
|
||||
|
||||
515
lib/jaeger/fields.go
Normal file
515
lib/jaeger/fields.go
Normal file
@@ -0,0 +1,515 @@
|
||||
package jaeger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jaegertracing/jaeger/model"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logstorage"
|
||||
)
|
||||
|
||||
// define the label name for span attributes
|
||||
const (
|
||||
// attributes that can be stored in a single field.
|
||||
TraceID string = "trace_id"
|
||||
SpanID string = "span_id"
|
||||
OperationName string = "operation_name"
|
||||
Flags string = "flags"
|
||||
StartTime string = "start_time"
|
||||
EndTime string = "end_time"
|
||||
Duration string = "duration"
|
||||
ProcessID string = "process_id"
|
||||
|
||||
ProcessServiceName string = "process_service_name"
|
||||
ProcessTagKey string = "process_tag:%s"
|
||||
ProcessTagVType string = "process_tag:%s:v_type"
|
||||
|
||||
// attributes that can be stored in a single field but does not need to be queried.
|
||||
Logs string = "log"
|
||||
Warnings string = "warnings"
|
||||
References string = "references"
|
||||
|
||||
// attributes that cannot be stored in a single field.
|
||||
TagKey string = "tag:%s" // e.g.: span_tag:otel.scope.name
|
||||
TagVType string = "tag:%s:v_type" // e.g.: span_tag:otel.scope.name:v_type
|
||||
)
|
||||
|
||||
func SpanToFieldsByteBuffer(bbuf *bytesutil.ByteBuffer, span *model.Span) ([]logstorage.Field, []logstorage.Field, error) {
|
||||
|
||||
fields := make([]logstorage.Field, 0)
|
||||
|
||||
fields = append(fields, logstorage.Field{Name: "_msg", Value: "span"},
|
||||
logstorage.Field{Name: TraceID, Value: span.TraceID.String()},
|
||||
logstorage.Field{Name: SpanID, Value: span.SpanID.String()},
|
||||
logstorage.Field{Name: Flags, Value: strconv.FormatUint(uint64(span.Flags), 10)},
|
||||
logstorage.Field{Name: StartTime, Value: strconv.FormatInt(span.StartTime.UnixNano(), 10)},
|
||||
logstorage.Field{Name: EndTime, Value: strconv.FormatInt(span.StartTime.Add(span.Duration).UnixNano(), 10)},
|
||||
logstorage.Field{Name: Duration, Value: strconv.FormatInt(span.Duration.Nanoseconds(), 10)}, logstorage.Field{Name: ProcessID, Value: span.ProcessID},
|
||||
logstorage.Field{Name: ProcessServiceName, Value: span.GetProcess().GetServiceName()},
|
||||
logstorage.Field{Name: OperationName, Value: span.GetOperationName()},
|
||||
)
|
||||
|
||||
if tags := span.GetProcess().GetTags(); len(tags) > 0 {
|
||||
for i := range tags {
|
||||
var value string
|
||||
switch tags[i].GetVType() {
|
||||
case model.ValueType_STRING:
|
||||
value = tags[i].GetVStr()
|
||||
case model.ValueType_BOOL:
|
||||
value = strconv.FormatBool(tags[i].GetVBool())
|
||||
case model.ValueType_INT64:
|
||||
value = strconv.FormatInt(tags[i].GetVInt64(), 10)
|
||||
case model.ValueType_FLOAT64:
|
||||
value = strconv.FormatFloat(tags[i].GetVFloat64(), 'f', -1, 64)
|
||||
case model.ValueType_BINARY:
|
||||
value = string(tags[i].GetVBinary())
|
||||
}
|
||||
startIdx := int64(len(bbuf.B))
|
||||
bbuf.Write([]byte("process_tag:"))
|
||||
bbuf.Write([]byte(tags[i].GetKey()))
|
||||
fields = append(fields, logstorage.Field{Name: string(bbuf.B[startIdx:]), Value: value})
|
||||
vType := int64(tags[i].GetVType())
|
||||
if vType > 0 {
|
||||
bbuf.Write([]byte(":v_type"))
|
||||
//fields = append(fields, logstorage.Field{Name: string(bbuf.B[startIdx:]), Value: strconv.FormatInt(int64(tags[i].GetVType()), 10)})
|
||||
fields = append(fields, logstorage.Field{Name: string(bbuf.B[startIdx:]), Value: "1"})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(span.Logs) > 0 {
|
||||
logs, err := json.Marshal(span.Logs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: Logs,
|
||||
Value: string(logs),
|
||||
})
|
||||
}
|
||||
|
||||
if len(span.Warnings) > 0 {
|
||||
warnings, err := json.Marshal(span.Warnings)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: Warnings,
|
||||
Value: string(warnings),
|
||||
})
|
||||
}
|
||||
|
||||
if len(span.References) > 0 {
|
||||
refs, err := json.Marshal(span.References)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: References,
|
||||
Value: string(refs),
|
||||
})
|
||||
}
|
||||
|
||||
tags := span.GetTags()
|
||||
for i := range tags {
|
||||
var value string
|
||||
switch tags[i].GetVType() {
|
||||
case model.ValueType_STRING:
|
||||
value = tags[i].GetVStr()
|
||||
case model.ValueType_BOOL:
|
||||
value = strconv.FormatBool(tags[i].GetVBool())
|
||||
case model.ValueType_INT64:
|
||||
value = strconv.FormatInt(tags[i].GetVInt64(), 10)
|
||||
case model.ValueType_FLOAT64:
|
||||
value = strconv.FormatFloat(tags[i].GetVFloat64(), 'f', -1, 64)
|
||||
case model.ValueType_BINARY:
|
||||
value = string(tags[i].GetVBinary())
|
||||
}
|
||||
startIdx := int64(len(bbuf.B))
|
||||
bbuf.Write([]byte("tag:"))
|
||||
bbuf.Write([]byte(tags[i].GetKey()))
|
||||
fields = append(fields, logstorage.Field{Name: string(bbuf.B[startIdx:]), Value: value})
|
||||
vtype := int64(tags[i].GetVType())
|
||||
if vtype > 0 {
|
||||
bbuf.Write([]byte(":v_type"))
|
||||
startVtype := int64(len(bbuf.B))
|
||||
bbuf.Write([]byte(strconv.FormatInt(int64(tags[i].GetVType()), 10)))
|
||||
fields = append(fields, logstorage.Field{Name: string(bbuf.B[startIdx:startVtype]), Value: string(bbuf.B[startVtype:])})
|
||||
}
|
||||
|
||||
}
|
||||
streamFields := make([]logstorage.Field, 0, 2)
|
||||
streamFields = append(streamFields,
|
||||
logstorage.Field{Name: ProcessServiceName, Value: span.GetProcess().GetServiceName()},
|
||||
logstorage.Field{Name: OperationName, Value: span.GetOperationName()},
|
||||
)
|
||||
|
||||
return fields, streamFields, nil
|
||||
}
|
||||
func SpanToFieldsStringBuilder(sb *strings.Builder, span *model.Span) ([]logstorage.Field, []logstorage.Field, error) {
|
||||
fields := make([]logstorage.Field, 0)
|
||||
|
||||
fields = append(fields, logstorage.Field{Name: "_msg", Value: "span"},
|
||||
logstorage.Field{Name: TraceID, Value: span.TraceID.String()},
|
||||
logstorage.Field{Name: SpanID, Value: span.SpanID.String()},
|
||||
logstorage.Field{Name: Flags, Value: strconv.FormatUint(uint64(span.Flags), 10)},
|
||||
logstorage.Field{Name: StartTime, Value: strconv.FormatInt(span.StartTime.UnixNano(), 10)},
|
||||
logstorage.Field{Name: EndTime, Value: strconv.FormatInt(span.StartTime.Add(span.Duration).UnixNano(), 10)},
|
||||
logstorage.Field{Name: Duration, Value: strconv.FormatInt(span.Duration.Nanoseconds(), 10)}, logstorage.Field{Name: ProcessID, Value: span.ProcessID},
|
||||
logstorage.Field{Name: ProcessServiceName, Value: span.GetProcess().GetServiceName()},
|
||||
logstorage.Field{Name: OperationName, Value: span.GetOperationName()},
|
||||
)
|
||||
|
||||
if tags := span.GetProcess().GetTags(); len(tags) > 0 {
|
||||
for i := range tags {
|
||||
var value string
|
||||
switch tags[i].GetVType() {
|
||||
case model.ValueType_STRING:
|
||||
value = tags[i].GetVStr()
|
||||
case model.ValueType_BOOL:
|
||||
value = strconv.FormatBool(tags[i].GetVBool())
|
||||
case model.ValueType_INT64:
|
||||
value = strconv.FormatInt(tags[i].GetVInt64(), 10)
|
||||
case model.ValueType_FLOAT64:
|
||||
value = strconv.FormatFloat(tags[i].GetVFloat64(), 'f', -1, 64)
|
||||
case model.ValueType_BINARY:
|
||||
value = string(tags[i].GetVBinary())
|
||||
}
|
||||
sb.WriteString("process_tag:")
|
||||
sb.WriteString(tags[i].GetKey())
|
||||
var f1 = logstorage.Field{Name: sb.String(), Value: value}
|
||||
sb.WriteString(":v_type")
|
||||
var f2 = logstorage.Field{Name: sb.String(), Value: strconv.FormatInt(int64(tags[i].GetVType()), 10)}
|
||||
sb.Reset()
|
||||
fields = append(fields, f1, f2)
|
||||
}
|
||||
}
|
||||
if len(span.Logs) > 0 {
|
||||
logs, err := json.Marshal(span.Logs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: Logs,
|
||||
Value: string(logs),
|
||||
})
|
||||
}
|
||||
|
||||
if len(span.Warnings) > 0 {
|
||||
warnings, err := json.Marshal(span.Warnings)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: Warnings,
|
||||
Value: string(warnings),
|
||||
})
|
||||
}
|
||||
|
||||
if len(span.References) > 0 {
|
||||
refs, err := json.Marshal(span.References)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: References,
|
||||
Value: string(refs),
|
||||
})
|
||||
}
|
||||
|
||||
tags := span.GetTags()
|
||||
for i := range tags {
|
||||
var value string
|
||||
switch tags[i].GetVType() {
|
||||
case model.ValueType_STRING:
|
||||
value = tags[i].GetVStr()
|
||||
case model.ValueType_BOOL:
|
||||
value = strconv.FormatBool(tags[i].GetVBool())
|
||||
case model.ValueType_INT64:
|
||||
value = strconv.FormatInt(tags[i].GetVInt64(), 10)
|
||||
case model.ValueType_FLOAT64:
|
||||
value = strconv.FormatFloat(tags[i].GetVFloat64(), 'f', -1, 64)
|
||||
case model.ValueType_BINARY:
|
||||
value = string(tags[i].GetVBinary())
|
||||
}
|
||||
sb.WriteString("tag:")
|
||||
sb.WriteString(tags[i].GetKey())
|
||||
var f1 = logstorage.Field{Name: sb.String(), Value: value}
|
||||
sb.WriteString(":v_type")
|
||||
var f2 = logstorage.Field{Name: sb.String(), Value: strconv.FormatInt(int64(tags[i].GetVType()), 10)}
|
||||
sb.Reset()
|
||||
fields = append(fields, f1, f2)
|
||||
}
|
||||
streamFields := make([]logstorage.Field, 0, 2)
|
||||
streamFields = append(streamFields,
|
||||
logstorage.Field{Name: ProcessServiceName, Value: span.GetProcess().GetServiceName()},
|
||||
logstorage.Field{Name: OperationName, Value: span.GetOperationName()},
|
||||
)
|
||||
|
||||
return fields, streamFields, nil
|
||||
}
|
||||
func SpanToFields(span *model.Span) ([]logstorage.Field, []logstorage.Field, error) {
|
||||
fields := make([]logstorage.Field, 0)
|
||||
|
||||
fields = append(fields, logstorage.Field{Name: "_msg", Value: "span"},
|
||||
logstorage.Field{Name: TraceID, Value: span.TraceID.String()},
|
||||
logstorage.Field{Name: SpanID, Value: span.SpanID.String()},
|
||||
logstorage.Field{Name: Flags, Value: strconv.FormatUint(uint64(span.Flags), 10)},
|
||||
logstorage.Field{Name: StartTime, Value: strconv.FormatInt(span.StartTime.UnixNano(), 10)},
|
||||
logstorage.Field{Name: EndTime, Value: strconv.FormatInt(span.StartTime.Add(span.Duration).UnixNano(), 10)},
|
||||
logstorage.Field{Name: Duration, Value: strconv.FormatInt(span.Duration.Nanoseconds(), 10)}, logstorage.Field{Name: ProcessID, Value: span.ProcessID},
|
||||
logstorage.Field{Name: ProcessServiceName, Value: span.GetProcess().GetServiceName()},
|
||||
logstorage.Field{Name: OperationName, Value: span.GetOperationName()},
|
||||
)
|
||||
|
||||
if tags := span.GetProcess().GetTags(); len(tags) > 0 {
|
||||
for i := range tags {
|
||||
var value string
|
||||
switch tags[i].GetVType() {
|
||||
case model.ValueType_STRING:
|
||||
value = tags[i].GetVStr()
|
||||
case model.ValueType_BOOL:
|
||||
value = strconv.FormatBool(tags[i].GetVBool())
|
||||
case model.ValueType_INT64:
|
||||
value = strconv.FormatInt(tags[i].GetVInt64(), 10)
|
||||
case model.ValueType_FLOAT64:
|
||||
value = strconv.FormatFloat(tags[i].GetVFloat64(), 'f', -1, 64)
|
||||
case model.ValueType_BINARY:
|
||||
value = string(tags[i].GetVBinary())
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: fmt.Sprintf(ProcessTagVType, tags[i].GetKey()),
|
||||
Value: strconv.FormatInt(int64(tags[i].GetVType()), 10),
|
||||
}, logstorage.Field{
|
||||
Name: fmt.Sprintf(ProcessTagKey, tags[i].GetKey()),
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(span.Logs) > 0 {
|
||||
logs, err := json.Marshal(span.Logs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: Logs,
|
||||
Value: string(logs),
|
||||
})
|
||||
}
|
||||
|
||||
if len(span.Warnings) > 0 {
|
||||
warnings, err := json.Marshal(span.Warnings)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: Warnings,
|
||||
Value: string(warnings),
|
||||
})
|
||||
}
|
||||
|
||||
if len(span.References) > 0 {
|
||||
refs, err := json.Marshal(span.References)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: References,
|
||||
Value: string(refs),
|
||||
})
|
||||
}
|
||||
|
||||
tags := span.GetTags()
|
||||
for i := range tags {
|
||||
var value string
|
||||
switch tags[i].GetVType() {
|
||||
case model.ValueType_STRING:
|
||||
value = tags[i].GetVStr()
|
||||
case model.ValueType_BOOL:
|
||||
value = strconv.FormatBool(tags[i].GetVBool())
|
||||
case model.ValueType_INT64:
|
||||
value = strconv.FormatInt(tags[i].GetVInt64(), 10)
|
||||
case model.ValueType_FLOAT64:
|
||||
value = strconv.FormatFloat(tags[i].GetVFloat64(), 'f', -1, 64)
|
||||
case model.ValueType_BINARY:
|
||||
value = string(tags[i].GetVBinary())
|
||||
}
|
||||
fields = append(fields, logstorage.Field{
|
||||
Name: fmt.Sprintf(TagVType, tags[i].GetKey()),
|
||||
Value: strconv.FormatInt(int64(tags[i].GetVType()), 10),
|
||||
}, logstorage.Field{
|
||||
Name: fmt.Sprintf(TagKey, tags[i].GetKey()),
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
streamFields := make([]logstorage.Field, 0, 2)
|
||||
streamFields = append(streamFields,
|
||||
logstorage.Field{Name: ProcessServiceName, Value: span.GetProcess().GetServiceName()},
|
||||
logstorage.Field{Name: OperationName, Value: span.GetOperationName()},
|
||||
)
|
||||
|
||||
return fields, streamFields, nil
|
||||
}
|
||||
|
||||
func FieldsToSpan(fields []logstorage.Field) (*model.Span, error) {
|
||||
sp := &model.Span{
|
||||
Process: &model.Process{},
|
||||
}
|
||||
|
||||
tagMap, tagVTypeMap, processTagMap, processVTypeMap := make(map[string]string), make(map[string]model.ValueType), make(map[string]string), make(map[string]model.ValueType)
|
||||
|
||||
for _, field := range fields {
|
||||
switch field.Name {
|
||||
case "_stream":
|
||||
logstorage.GetStreamTags()
|
||||
case TraceID:
|
||||
traceID, err := model.TraceIDFromString(field.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.TraceID = traceID
|
||||
case SpanID:
|
||||
spanID, err := model.SpanIDFromString(field.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.SpanID = spanID
|
||||
case OperationName:
|
||||
sp.OperationName = field.Value
|
||||
case Flags:
|
||||
flags, err := strconv.ParseUint(field.Value, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.Flags = model.Flags(uint32(flags))
|
||||
case StartTime:
|
||||
unixNano, err := strconv.ParseInt(field.Value, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.StartTime = time.Unix(0, unixNano)
|
||||
case Duration:
|
||||
nano, err := strconv.ParseInt(field.Value, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.Duration = time.Duration(nano)
|
||||
case ProcessID:
|
||||
sp.ProcessID = field.Value
|
||||
case ProcessServiceName:
|
||||
sp.Process.ServiceName = field.Value
|
||||
case Logs:
|
||||
var logs []model.Log
|
||||
err := json.Unmarshal([]byte(field.Value), &logs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.Logs = logs
|
||||
case Warnings:
|
||||
var warnings []string
|
||||
err := json.Unmarshal([]byte(field.Value), &warnings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.Warnings = warnings
|
||||
case References:
|
||||
var refs []model.SpanRef
|
||||
err := json.Unmarshal([]byte(field.Value), &refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.References = refs
|
||||
default:
|
||||
if strings.HasPrefix(field.Name, "process_tag:") {
|
||||
if strings.HasSuffix(field.Name, ":v_type") {
|
||||
vType, err := strconv.ParseInt(field.Value, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
processVTypeMap[strings.TrimSuffix(strings.TrimPrefix(field.Name, "process_tag:"), ":v_type")] = model.ValueType(vType)
|
||||
} else {
|
||||
processTagMap[strings.TrimPrefix(field.Name, "process_tag:")] = field.Value
|
||||
}
|
||||
} else if strings.HasPrefix(field.Name, "tag:") {
|
||||
if strings.HasSuffix(field.Name, ":v_type") {
|
||||
vType, err := strconv.ParseInt(field.Value, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tagVTypeMap[strings.TrimSuffix(strings.TrimPrefix(field.Name, "tag:"), ":v_type")] = model.ValueType(vType)
|
||||
} else {
|
||||
tagMap[strings.TrimPrefix(field.Name, "tag:")] = field.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(tagMap) > 0 {
|
||||
tags, err := mapToTags(tagMap, tagVTypeMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.Tags = tags
|
||||
}
|
||||
|
||||
if len(processTagMap) > 0 {
|
||||
tags, err := mapToTags(processTagMap, processVTypeMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.Process.Tags = tags
|
||||
}
|
||||
|
||||
if sp.SpanID != 0 {
|
||||
return sp, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid fields: %v", fields)
|
||||
}
|
||||
|
||||
func mapToTags(tagMap map[string]string, tagVTypeMap map[string]model.ValueType) ([]model.KeyValue, error) {
|
||||
tags := make([]model.KeyValue, 0, len(tagMap))
|
||||
for name, vStr := range tagMap {
|
||||
vType, ok := tagVTypeMap[name]
|
||||
/*if !ok {
|
||||
return nil, fmt.Errorf("cannot find tag value type for tag [%s]", name)
|
||||
} */
|
||||
if !ok {
|
||||
// assume tag is of type string
|
||||
vType = model.ValueType(0)
|
||||
}
|
||||
tag := model.KeyValue{
|
||||
Key: name,
|
||||
VType: vType,
|
||||
}
|
||||
switch vType {
|
||||
case model.ValueType_STRING:
|
||||
tag.VStr = vStr
|
||||
case model.ValueType_BOOL:
|
||||
v, err := strconv.ParseBool(vStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tag.VBool = v
|
||||
case model.ValueType_INT64:
|
||||
v, err := strconv.ParseInt(vStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tag.VInt64 = v
|
||||
case model.ValueType_FLOAT64:
|
||||
v, err := strconv.ParseFloat(vStr, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tag.VFloat64 = v
|
||||
case model.ValueType_BINARY:
|
||||
tag.VBinary = []byte(vStr)
|
||||
}
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
152
lib/jaeger/fields_test.go
Normal file
152
lib/jaeger/fields_test.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package jaeger
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/jaegertracing/jaeger/model"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||
)
|
||||
|
||||
var span = &model.Span{
|
||||
TraceID: model.TraceID{Low: 4300929031727684986, High: 12612784095082448122},
|
||||
SpanID: 0x04210a5512d46c4b,
|
||||
OperationName: "/",
|
||||
References: []model.SpanRef{},
|
||||
Flags: 0,
|
||||
Duration: 198458,
|
||||
Tags: []model.KeyValue{
|
||||
{
|
||||
Key: "otel.scope.name",
|
||||
VType: model.StringType,
|
||||
VStr: "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",
|
||||
},
|
||||
{
|
||||
Key: "otel.scope.version",
|
||||
VType: model.StringType,
|
||||
VStr: "0.60.0",
|
||||
},
|
||||
{
|
||||
Key: "httpd.method",
|
||||
VType: model.StringType,
|
||||
VStr: "GET",
|
||||
},
|
||||
{
|
||||
Key: "httpd.scheme",
|
||||
VType: model.StringType,
|
||||
VStr: "http",
|
||||
},
|
||||
{
|
||||
Key: "net.host.name",
|
||||
VType: model.StringType,
|
||||
VStr: "localhost",
|
||||
},
|
||||
{
|
||||
Key: "net.host.port",
|
||||
VType: model.Int64Type,
|
||||
VStr: "",
|
||||
VInt64: 8080,
|
||||
},
|
||||
{
|
||||
Key: "net.sock.peer",
|
||||
VType: model.StringType,
|
||||
VStr: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
Key: "net.sock.peer.port",
|
||||
VType: model.Int64Type,
|
||||
VStr: "",
|
||||
VInt64: 59398,
|
||||
},
|
||||
{
|
||||
Key: "user_agent.original",
|
||||
VType: model.StringType,
|
||||
VStr: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15",
|
||||
},
|
||||
{
|
||||
Key: "http.target",
|
||||
VType: model.StringType,
|
||||
VStr: "/",
|
||||
},
|
||||
{
|
||||
Key: "net.protocol.version",
|
||||
VType: model.StringType,
|
||||
VStr: "1.1",
|
||||
},
|
||||
{
|
||||
Key: "http.route",
|
||||
VType: model.StringType,
|
||||
VStr: "/",
|
||||
},
|
||||
{
|
||||
Key: "http.status_code",
|
||||
VType: model.Int64Type,
|
||||
VStr: "",
|
||||
VInt64: 200,
|
||||
},
|
||||
{
|
||||
Key: "span.kind",
|
||||
VType: model.StringType,
|
||||
VStr: "server",
|
||||
},
|
||||
},
|
||||
|
||||
Logs: nil,
|
||||
Process: &model.Process{
|
||||
ServiceName: "frontend",
|
||||
Tags: []model.KeyValue{
|
||||
{
|
||||
Key: "host.name",
|
||||
VType: model.StringType,
|
||||
VStr: "orbstack",
|
||||
},
|
||||
{
|
||||
Key: "os.type",
|
||||
VType: model.StringType,
|
||||
VStr: "linux",
|
||||
},
|
||||
{
|
||||
Key: "telemetry.sdk.language",
|
||||
VType: model.StringType,
|
||||
VStr: "go",
|
||||
},
|
||||
{
|
||||
Key: "telemetry.sdk.name",
|
||||
VType: model.StringType,
|
||||
VStr: "opentelemetry",
|
||||
},
|
||||
{
|
||||
Key: "telemetry.sdk.version",
|
||||
VType: model.StringType,
|
||||
VStr: "1.35.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
ProcessID: "",
|
||||
Warnings: nil,
|
||||
}
|
||||
|
||||
func BenchmarkSpanToFields(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
SpanToFields(span)
|
||||
}
|
||||
}
|
||||
func BenchmarkSpanToFieldsStringBuilder(b *testing.B) {
|
||||
sb := &strings.Builder{}
|
||||
sb.Grow(80)
|
||||
for i := 0; i < b.N; i++ {
|
||||
SpanToFieldsStringBuilder(sb, span)
|
||||
}
|
||||
}
|
||||
|
||||
var bbufPool bytesutil.ByteBufferPool
|
||||
|
||||
func BenchmarkSpanToFieldsByteBuffer(b *testing.B) {
|
||||
bbuf := bbufPool.Get()
|
||||
defer bbufPool.Put(bbuf)
|
||||
for i := 0; i < b.N; i++ {
|
||||
SpanToFieldsByteBuffer(bbuf, span)
|
||||
bbuf.Reset()
|
||||
}
|
||||
}
|
||||
1
lib/jaeger/proto/README.md
Normal file
1
lib/jaeger/proto/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Files under `github.com/VictoriaMetrics/VictoriaMetrics/app/vlinsert/jaeger/proto` are copied from `github.com/jaegertracing/jaeger` with import path modified. For PoC usage only.
|
||||
59
lib/jaeger/proto/flags.go
Normal file
59
lib/jaeger/proto/flags.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2019 The Jaeger Authors.
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package proto
|
||||
|
||||
const (
|
||||
// SampledFlag is the bit set in Flags in order to define a span as a sampled span
|
||||
SampledFlag = Flags(1)
|
||||
// DebugFlag is the bit set in Flags in order to define a span as a debug span
|
||||
DebugFlag = Flags(2)
|
||||
// FirehoseFlag is the bit in Flags in order to define a span as a firehose span
|
||||
FirehoseFlag = Flags(8)
|
||||
)
|
||||
|
||||
// Flags is a bit map of flags for a span
|
||||
type Flags uint32
|
||||
|
||||
// ------- Flags -------
|
||||
|
||||
// SetSampled sets the Flags as sampled
|
||||
func (f *Flags) SetSampled() {
|
||||
f.setFlags(SampledFlag)
|
||||
}
|
||||
|
||||
// SetDebug set the Flags as sampled
|
||||
func (f *Flags) SetDebug() {
|
||||
f.setFlags(DebugFlag)
|
||||
}
|
||||
|
||||
// SetFirehose set the Flags as firehose enabled
|
||||
func (f *Flags) SetFirehose() {
|
||||
f.setFlags(FirehoseFlag)
|
||||
}
|
||||
|
||||
func (f *Flags) setFlags(bit Flags) {
|
||||
*f |= bit
|
||||
}
|
||||
|
||||
// IsSampled returns true if the Flags denote sampling
|
||||
func (f Flags) IsSampled() bool {
|
||||
return f.checkFlags(SampledFlag)
|
||||
}
|
||||
|
||||
// IsDebug returns true if the Flags denote debugging
|
||||
// Debugging can be useful in testing tracing availability or correctness
|
||||
func (f Flags) IsDebug() bool {
|
||||
return f.checkFlags(DebugFlag)
|
||||
}
|
||||
|
||||
// IsFirehoseEnabled returns true if firehose is enabled
|
||||
// Firehose is used to decide whether to index a span or not
|
||||
func (f Flags) IsFirehoseEnabled() bool {
|
||||
return f.checkFlags(FirehoseFlag)
|
||||
}
|
||||
|
||||
func (f Flags) checkFlags(bit Flags) bool {
|
||||
return f&bit == bit
|
||||
}
|
||||
245
lib/jaeger/proto/ids.go
Normal file
245
lib/jaeger/proto/ids.go
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright (c) 2019 The Jaeger Authors.
|
||||
// Copyright (c) 2018 Uber Technologies, Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
)
|
||||
|
||||
const (
|
||||
// traceIDShortBytesLen indicates length of 64bit traceID when represented as list of bytes
|
||||
traceIDShortBytesLen = 8
|
||||
// traceIDLongBytesLen indicates length of 128bit traceID when represented as list of bytes
|
||||
traceIDLongBytesLen = 16
|
||||
)
|
||||
|
||||
// TraceID is a random 128bit identifier for a trace
|
||||
type TraceID struct {
|
||||
Low uint64 `json:"lo"`
|
||||
High uint64 `json:"hi"`
|
||||
}
|
||||
|
||||
// SpanID is a random 64bit identifier for a span
|
||||
type SpanID uint64
|
||||
|
||||
// ------- TraceID -------
|
||||
|
||||
// NewTraceID creates a new TraceID from two 64bit unsigned ints.
|
||||
func NewTraceID(high, low uint64) TraceID {
|
||||
return TraceID{High: high, Low: low}
|
||||
}
|
||||
|
||||
func (t TraceID) String() string {
|
||||
if t.High == 0 {
|
||||
return fmt.Sprintf("%016x", t.Low)
|
||||
}
|
||||
return fmt.Sprintf("%016x%016x", t.High, t.Low)
|
||||
}
|
||||
|
||||
// TraceIDFromString creates a TraceID from a hexadecimal string
|
||||
func TraceIDFromString(s string) (TraceID, error) {
|
||||
var hi, lo uint64
|
||||
var err error
|
||||
switch {
|
||||
case len(s) > 32:
|
||||
return TraceID{}, fmt.Errorf("TraceID cannot be longer than 32 hex characters: %s", s)
|
||||
case len(s) > 16:
|
||||
hiLen := len(s) - 16
|
||||
if hi, err = strconv.ParseUint(s[0:hiLen], 16, 64); err != nil {
|
||||
return TraceID{}, err
|
||||
}
|
||||
if lo, err = strconv.ParseUint(s[hiLen:], 16, 64); err != nil {
|
||||
return TraceID{}, err
|
||||
}
|
||||
default:
|
||||
if lo, err = strconv.ParseUint(s, 16, 64); err != nil {
|
||||
return TraceID{}, err
|
||||
}
|
||||
}
|
||||
return TraceID{High: hi, Low: lo}, nil
|
||||
}
|
||||
|
||||
// TraceIDFromBytes creates a TraceID from list of bytes
|
||||
func TraceIDFromBytes(data []byte) (TraceID, error) {
|
||||
var t TraceID
|
||||
switch {
|
||||
case len(data) == traceIDLongBytesLen:
|
||||
t.High = binary.BigEndian.Uint64(data[:traceIDShortBytesLen])
|
||||
t.Low = binary.BigEndian.Uint64(data[traceIDShortBytesLen:])
|
||||
case len(data) == traceIDShortBytesLen:
|
||||
t.Low = binary.BigEndian.Uint64(data)
|
||||
default:
|
||||
return TraceID{}, errors.New("invalid length for TraceID")
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// MarshalText is called by encoding/json, which we do not want people to use.
|
||||
func (TraceID) MarshalText() ([]byte, error) {
|
||||
return nil, errors.New("unsupported method TraceID.MarshalText; please use github.com/gogo/protobuf/jsonpb for marshalling")
|
||||
}
|
||||
|
||||
// UnmarshalText is called by encoding/json, which we do not want people to use.
|
||||
func (*TraceID) UnmarshalText([]byte /* text */) error {
|
||||
return errors.New("unsupported method TraceID.UnmarshalText; please use github.com/gogo/protobuf/jsonpb for marshalling")
|
||||
}
|
||||
|
||||
// Size returns the size of this datum in protobuf. It is always 16 bytes.
|
||||
func (*TraceID) Size() int {
|
||||
return 16
|
||||
}
|
||||
|
||||
// MarshalTo converts trace ID into a binary representation. Called by protobuf serialization.
|
||||
func (t *TraceID) MarshalTo(data []byte) (n int, err error) {
|
||||
var b [16]byte
|
||||
binary.BigEndian.PutUint64(b[:8], uint64(t.High))
|
||||
binary.BigEndian.PutUint64(b[8:], uint64(t.Low))
|
||||
return marshalBytes(data, b[:])
|
||||
}
|
||||
|
||||
// Unmarshal inflates this trace ID from binary representation. Called by protobuf serialization.
|
||||
func (t *TraceID) Unmarshal(data []byte) error {
|
||||
var err error
|
||||
*t, err = TraceIDFromBytes(data)
|
||||
return err
|
||||
}
|
||||
|
||||
func marshalBytes(dst []byte, src []byte) (n int, err error) {
|
||||
if len(dst) < len(src) {
|
||||
return 0, errors.New("buffer is too short")
|
||||
}
|
||||
return copy(dst, src), nil
|
||||
}
|
||||
|
||||
// MarshalJSON converts trace id into a base64 string enclosed in quotes.
|
||||
// Used by protobuf JSON serialization.
|
||||
// Example: {high:2, low:1} => "AAAAAAAAAAIAAAAAAAAAAQ==".
|
||||
func (t TraceID) MarshalJSON() ([]byte, error) {
|
||||
var b [16]byte
|
||||
t.MarshalTo(b[:]) // can only error on incorrect buffer size
|
||||
s := make([]byte, 24+2)
|
||||
base64.StdEncoding.Encode(s[1:25], b[:])
|
||||
s[0], s[25] = '"', '"'
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON inflates trace id from base64 string, possibly enclosed in quotes.
|
||||
// Used by protobuf JSON serialization.
|
||||
func (t *TraceID) UnmarshalJSON(data []byte) error {
|
||||
s := string(data)
|
||||
if l := len(s); l > 2 && s[0] == '"' && s[l-1] == '"' {
|
||||
s = s[1 : l-1]
|
||||
}
|
||||
b, err := base64.StdEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot unmarshal TraceID from string '%s': %w", string(data), err)
|
||||
}
|
||||
return t.Unmarshal(b)
|
||||
}
|
||||
|
||||
// ------- SpanID -------
|
||||
|
||||
// NewSpanID creates a new SpanID from a 64bit unsigned int.
|
||||
func NewSpanID(v uint64) SpanID {
|
||||
return SpanID(v)
|
||||
}
|
||||
|
||||
func (s SpanID) String() string {
|
||||
return fmt.Sprintf("%016x", uint64(s))
|
||||
}
|
||||
|
||||
// SpanIDFromString creates a SpanID from a hexadecimal string
|
||||
func SpanIDFromString(s string) (SpanID, error) {
|
||||
if len(s) > 16 {
|
||||
return SpanID(0), fmt.Errorf("SpanID cannot be longer than 16 hex characters: %s", s)
|
||||
}
|
||||
id, err := strconv.ParseUint(s, 16, 64)
|
||||
if err != nil {
|
||||
return SpanID(0), err
|
||||
}
|
||||
return SpanID(id), nil
|
||||
}
|
||||
|
||||
// SpanIDFromBytes creates a SpandID from list of bytes
|
||||
func SpanIDFromBytes(data []byte) (SpanID, error) {
|
||||
if len(data) != traceIDShortBytesLen {
|
||||
return SpanID(0), errors.New("invalid length for SpanID")
|
||||
}
|
||||
return NewSpanID(binary.BigEndian.Uint64(data)), nil
|
||||
}
|
||||
|
||||
// MarshalText is called by encoding/json, which we do not want people to use.
|
||||
func (SpanID) MarshalText() ([]byte, error) {
|
||||
return nil, errors.New("unsupported method SpanID.MarshalText; please use github.com/gogo/protobuf/jsonpb for marshalling")
|
||||
}
|
||||
|
||||
// UnmarshalText is called by encoding/json, which we do not want people to use.
|
||||
func (*SpanID) UnmarshalText([]byte /* text */) error {
|
||||
return errors.New("unsupported method SpanID.UnmarshalText; please use github.com/gogo/protobuf/jsonpb for marshalling")
|
||||
}
|
||||
|
||||
// Size returns the size of this datum in protobuf. It is always 8 bytes.
|
||||
func (*SpanID) Size() int {
|
||||
return 8
|
||||
}
|
||||
|
||||
// MarshalTo converts span ID into a binary representation. Called by protobuf serialization.
|
||||
func (s *SpanID) MarshalTo(data []byte) (n int, err error) {
|
||||
var b [8]byte
|
||||
binary.BigEndian.PutUint64(b[:], uint64(*s))
|
||||
return marshalBytes(data, b[:])
|
||||
}
|
||||
|
||||
// Unmarshal inflates span ID from a binary representation. Called by protobuf serialization.
|
||||
func (s *SpanID) Unmarshal(data []byte) error {
|
||||
var err error
|
||||
*s, err = SpanIDFromBytes(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON converts span id into a base64 string enclosed in quotes.
|
||||
// Used by protobuf JSON serialization.
|
||||
// Example: {1} => "AAAAAAAAAAE=".
|
||||
func (s SpanID) MarshalJSON() ([]byte, error) {
|
||||
var b [8]byte
|
||||
s.MarshalTo(b[:]) // can only error on incorrect buffer size
|
||||
v := make([]byte, 12+2)
|
||||
base64.StdEncoding.Encode(v[1:13], b[:])
|
||||
v[0], v[13] = '"', '"'
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON inflates span id from base64 string, possibly enclosed in quotes.
|
||||
// User by protobuf JSON serialization.
|
||||
//
|
||||
// There appears to be a bug in gogoproto, as this function is only called for numeric values.
|
||||
// https://github.com/gogo/protobuf/issues/411#issuecomment-393856837
|
||||
func (s *SpanID) UnmarshalJSON(data []byte) error {
|
||||
str := string(data)
|
||||
if l := len(str); l > 2 && str[0] == '"' && str[l-1] == '"' {
|
||||
str = str[1 : l-1]
|
||||
}
|
||||
b, err := base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot unmarshal SpanID from string '%s': %w", string(data), err)
|
||||
}
|
||||
return s.Unmarshal(b)
|
||||
}
|
||||
|
||||
// UnmarshalJSONPB inflates span id from base64 string, possibly enclosed in quotes.
|
||||
// User by protobuf JSON serialization.
|
||||
//
|
||||
// TODO: can be removed once this ticket is fixed:
|
||||
//
|
||||
// https://github.com/gogo/protobuf/issues/411#issuecomment-393856837
|
||||
func (s *SpanID) UnmarshalJSONPB(_ *jsonpb.Unmarshaler, b []byte) error {
|
||||
return s.UnmarshalJSON(b)
|
||||
}
|
||||
3420
lib/jaeger/proto/model.pb.go
Normal file
3420
lib/jaeger/proto/model.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
5119
lib/jaeger/proto/storage.pb.go
Normal file
5119
lib/jaeger/proto/storage.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
141
vendor/cloud.google.com/go/auth/CHANGES.md
generated
vendored
141
vendor/cloud.google.com/go/auth/CHANGES.md
generated
vendored
@@ -1,146 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [0.14.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.13.0...auth/v0.14.0) (2025-01-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** Add universe domain support to idtoken ([#11059](https://github.com/googleapis/google-cloud-go/issues/11059)) ([72add7e](https://github.com/googleapis/google-cloud-go/commit/72add7e9f8f455af695e8ef79212a4bd3122fb3a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth/oauth2adapt:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9))
|
||||
* **auth:** Fix copy of delegates in impersonate.NewIDTokenCredentials ([#11386](https://github.com/googleapis/google-cloud-go/issues/11386)) ([ff7ef8e](https://github.com/googleapis/google-cloud-go/commit/ff7ef8e7ade7171bce3e4f30ff10a2e9f6c27ca0)), refs [#11379](https://github.com/googleapis/google-cloud-go/issues/11379)
|
||||
* **auth:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9))
|
||||
|
||||
## [0.13.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.12.1...auth/v0.13.0) (2024-12-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** Add logging support ([#11079](https://github.com/googleapis/google-cloud-go/issues/11079)) ([c80e31d](https://github.com/googleapis/google-cloud-go/commit/c80e31df5ecb33a810be3dfb9d9e27ac531aa91d))
|
||||
* **auth:** Pass logger from auth layer to metadata package ([#11288](https://github.com/googleapis/google-cloud-go/issues/11288)) ([b552efd](https://github.com/googleapis/google-cloud-go/commit/b552efd6ab34e5dfded18438e0fbfd925805614f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Check compute cred type before non-default flag for DP ([#11255](https://github.com/googleapis/google-cloud-go/issues/11255)) ([4347ca1](https://github.com/googleapis/google-cloud-go/commit/4347ca141892be8ae813399b4b437662a103bc90))
|
||||
|
||||
## [0.12.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.12.0...auth/v0.12.1) (2024-12-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Correct typo in link ([#11160](https://github.com/googleapis/google-cloud-go/issues/11160)) ([af6fb46](https://github.com/googleapis/google-cloud-go/commit/af6fb46d7cd694ddbe8c9d63bc4cdcd62b9fb2c1))
|
||||
|
||||
## [0.12.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.11.0...auth/v0.12.0) (2024-12-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** Add support for providing custom certificate URL ([#11006](https://github.com/googleapis/google-cloud-go/issues/11006)) ([ebf3657](https://github.com/googleapis/google-cloud-go/commit/ebf36579724afb375d3974cf1da38f703e3b7dbc)), refs [#11005](https://github.com/googleapis/google-cloud-go/issues/11005)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Ensure endpoints are present in Validator ([#11209](https://github.com/googleapis/google-cloud-go/issues/11209)) ([106cd53](https://github.com/googleapis/google-cloud-go/commit/106cd53309facaef1b8ea78376179f523f6912b9)), refs [#11006](https://github.com/googleapis/google-cloud-go/issues/11006) [#11190](https://github.com/googleapis/google-cloud-go/issues/11190) [#11189](https://github.com/googleapis/google-cloud-go/issues/11189) [#11188](https://github.com/googleapis/google-cloud-go/issues/11188)
|
||||
|
||||
## [0.11.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.2...auth/v0.11.0) (2024-11-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** Add universe domain support to mTLS ([#11159](https://github.com/googleapis/google-cloud-go/issues/11159)) ([117748b](https://github.com/googleapis/google-cloud-go/commit/117748ba1cfd4ae62a6a4feb7e30951cb2bc9344))
|
||||
|
||||
## [0.10.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.1...auth/v0.10.2) (2024-11-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Restore use of grpc.Dial ([#11118](https://github.com/googleapis/google-cloud-go/issues/11118)) ([2456b94](https://github.com/googleapis/google-cloud-go/commit/2456b943b7b8aaabd4d8bfb7572c0f477ae0db45)), refs [#7556](https://github.com/googleapis/google-cloud-go/issues/7556)
|
||||
|
||||
## [0.10.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.0...auth/v0.10.1) (2024-11-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Restore Application Default Credentials support to idtoken ([#11083](https://github.com/googleapis/google-cloud-go/issues/11083)) ([8771f2e](https://github.com/googleapis/google-cloud-go/commit/8771f2ea9807ab822083808e0678392edff3b4f2))
|
||||
* **auth:** Skip impersonate universe domain check if empty ([#11086](https://github.com/googleapis/google-cloud-go/issues/11086)) ([87159c1](https://github.com/googleapis/google-cloud-go/commit/87159c1059d4a18d1367ce62746a838a94964ab6))
|
||||
|
||||
## [0.10.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.9...auth/v0.10.0) (2024-10-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** Add universe domain support to credentials/impersonate ([#10953](https://github.com/googleapis/google-cloud-go/issues/10953)) ([e06cb64](https://github.com/googleapis/google-cloud-go/commit/e06cb6499f7eda3aef08ab18ff197016f667684b))
|
||||
|
||||
## [0.9.9](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.8...auth/v0.9.9) (2024-10-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Fallback cert lookups for missing files ([#11013](https://github.com/googleapis/google-cloud-go/issues/11013)) ([bd76695](https://github.com/googleapis/google-cloud-go/commit/bd766957ec238b7c40ddbabb369e612dc9b07313)), refs [#10844](https://github.com/googleapis/google-cloud-go/issues/10844)
|
||||
* **auth:** Replace MDS endpoint universe_domain with universe-domain ([#11000](https://github.com/googleapis/google-cloud-go/issues/11000)) ([6a1586f](https://github.com/googleapis/google-cloud-go/commit/6a1586f2ce9974684affaea84e7b629313b4d114))
|
||||
|
||||
## [0.9.8](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.7...auth/v0.9.8) (2024-10-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Restore OpenTelemetry handling in transports ([#10968](https://github.com/googleapis/google-cloud-go/issues/10968)) ([08c6d04](https://github.com/googleapis/google-cloud-go/commit/08c6d04901c1a20e219b2d86df41dbaa6d7d7b55)), refs [#10962](https://github.com/googleapis/google-cloud-go/issues/10962)
|
||||
* **auth:** Try talk to plaintext S2A if credentials can not be found for mTLS-S2A ([#10941](https://github.com/googleapis/google-cloud-go/issues/10941)) ([0f0bf2d](https://github.com/googleapis/google-cloud-go/commit/0f0bf2d18c97dd8b65bcf0099f0802b5631c6287))
|
||||
|
||||
## [0.9.7](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.6...auth/v0.9.7) (2024-10-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Restore support for non-default service accounts for DirectPath ([#10937](https://github.com/googleapis/google-cloud-go/issues/10937)) ([a38650e](https://github.com/googleapis/google-cloud-go/commit/a38650edbf420223077498cafa537aec74b37aad)), refs [#10907](https://github.com/googleapis/google-cloud-go/issues/10907)
|
||||
|
||||
## [0.9.6](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.5...auth/v0.9.6) (2024-09-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Make aws credentials provider retrieve fresh credentials ([#10920](https://github.com/googleapis/google-cloud-go/issues/10920)) ([250fbf8](https://github.com/googleapis/google-cloud-go/commit/250fbf87d858d865e399a241b7e537c4ff0c3dd8))
|
||||
|
||||
## [0.9.5](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.4...auth/v0.9.5) (2024-09-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Restore support for GOOGLE_CLOUD_UNIVERSE_DOMAIN env ([#10915](https://github.com/googleapis/google-cloud-go/issues/10915)) ([94caaaa](https://github.com/googleapis/google-cloud-go/commit/94caaaa061362d0e00ef6214afcc8a0a3e7ebfb2))
|
||||
* **auth:** Skip directpath credentials overwrite when it's not on GCE ([#10833](https://github.com/googleapis/google-cloud-go/issues/10833)) ([7e5e8d1](https://github.com/googleapis/google-cloud-go/commit/7e5e8d10b761b0a6e43e19a028528db361bc07b1))
|
||||
* **auth:** Use new context for non-blocking token refresh ([#10919](https://github.com/googleapis/google-cloud-go/issues/10919)) ([cf7102d](https://github.com/googleapis/google-cloud-go/commit/cf7102d33a21be1e5a9d47a49456b3a57c43b350))
|
||||
|
||||
## [0.9.4](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.3...auth/v0.9.4) (2024-09-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Enable self-signed JWT for non-GDU universe domain ([#10831](https://github.com/googleapis/google-cloud-go/issues/10831)) ([f9869f7](https://github.com/googleapis/google-cloud-go/commit/f9869f7903cfd34d1b97c25d0dc5669d2c5138e6))
|
||||
|
||||
## [0.9.3](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.2...auth/v0.9.3) (2024-09-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Choose quota project envvar over file when both present ([#10807](https://github.com/googleapis/google-cloud-go/issues/10807)) ([2d8dd77](https://github.com/googleapis/google-cloud-go/commit/2d8dd7700eff92d4b95027be55e26e1e7aa79181)), refs [#10804](https://github.com/googleapis/google-cloud-go/issues/10804)
|
||||
|
||||
## [0.9.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.1...auth/v0.9.2) (2024-08-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** Handle non-Transport DefaultTransport ([#10733](https://github.com/googleapis/google-cloud-go/issues/10733)) ([98d91dc](https://github.com/googleapis/google-cloud-go/commit/98d91dc8316b247498fab41ab35e57a0446fe556)), refs [#10742](https://github.com/googleapis/google-cloud-go/issues/10742)
|
||||
* **auth:** Make sure quota option takes precedence over env/file ([#10797](https://github.com/googleapis/google-cloud-go/issues/10797)) ([f1b050d](https://github.com/googleapis/google-cloud-go/commit/f1b050d56d804b245cab048c2980d32b0eaceb4e)), refs [#10795](https://github.com/googleapis/google-cloud-go/issues/10795)
|
||||
|
||||
|
||||
### Documentation
|
||||
|
||||
* **auth:** Fix Go doc comment link ([#10751](https://github.com/googleapis/google-cloud-go/issues/10751)) ([015acfa](https://github.com/googleapis/google-cloud-go/commit/015acfab4d172650928bb1119bc2cd6307b9a437))
|
||||
|
||||
## [0.9.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.0...auth/v0.9.1) (2024-08-22)
|
||||
|
||||
|
||||
|
||||
42
vendor/cloud.google.com/go/auth/README.md
generated
vendored
42
vendor/cloud.google.com/go/auth/README.md
generated
vendored
@@ -1,40 +1,4 @@
|
||||
# Google Auth Library for Go
|
||||
# auth
|
||||
|
||||
[](https://pkg.go.dev/cloud.google.com/go/auth)
|
||||
|
||||
## Install
|
||||
|
||||
``` bash
|
||||
go get cloud.google.com/go/auth@latest
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The most common way this library is used is transitively, by default, from any
|
||||
of our Go client libraries.
|
||||
|
||||
### Notable use-cases
|
||||
|
||||
- To create a credential directly please see examples in the
|
||||
[credentials](https://pkg.go.dev/cloud.google.com/go/auth/credentials)
|
||||
package.
|
||||
- To create a authenticated HTTP client please see examples in the
|
||||
[httptransport](https://pkg.go.dev/cloud.google.com/go/auth/httptransport)
|
||||
package.
|
||||
- To create a authenticated gRPC connection please see examples in the
|
||||
[grpctransport](https://pkg.go.dev/cloud.google.com/go/auth/grpctransport)
|
||||
package.
|
||||
- To create an ID token please see examples in the
|
||||
[idtoken](https://pkg.go.dev/cloud.google.com/go/auth/credentials/idtoken)
|
||||
package.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. Please, see the
|
||||
[CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md)
|
||||
document for details.
|
||||
|
||||
Please note that this project is released with a Contributor Code of Conduct.
|
||||
By participating in this project you agree to abide by its terms.
|
||||
See [Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct)
|
||||
for more information.
|
||||
This module is currently EXPERIMENTAL and under active development. It is not
|
||||
yet intended to be used.
|
||||
|
||||
47
vendor/cloud.google.com/go/auth/auth.go
generated
vendored
47
vendor/cloud.google.com/go/auth/auth.go
generated
vendored
@@ -12,11 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package auth provides utilities for managing Google Cloud credentials,
|
||||
// including functionality for creating, caching, and refreshing OAuth2 tokens.
|
||||
// It offers customizable options for different OAuth2 flows, such as 2-legged
|
||||
// (2LO) and 3-legged (3LO) OAuth, along with support for PKCE and automatic
|
||||
// token management.
|
||||
package auth
|
||||
|
||||
import (
|
||||
@@ -24,7 +19,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -33,7 +27,6 @@ import (
|
||||
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/jwt"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -137,9 +130,7 @@ func (t *Token) isEmpty() bool {
|
||||
}
|
||||
|
||||
// Credentials holds Google credentials, including
|
||||
// [Application Default Credentials].
|
||||
//
|
||||
// [Application Default Credentials]: https://developers.google.com/accounts/docs/application-default-credentials
|
||||
// [Application Default Credentials](https://developers.google.com/accounts/docs/application-default-credentials).
|
||||
type Credentials struct {
|
||||
json []byte
|
||||
projectID CredentialsPropertyProvider
|
||||
@@ -229,7 +220,9 @@ type CredentialsOptions struct {
|
||||
UniverseDomainProvider CredentialsPropertyProvider
|
||||
}
|
||||
|
||||
// NewCredentials returns new [Credentials] from the provided options.
|
||||
// NewCredentials returns new [Credentials] from the provided options. Most users
|
||||
// will want to build this object a function from the
|
||||
// [cloud.google.com/go/auth/credentials] package.
|
||||
func NewCredentials(opts *CredentialsOptions) *Credentials {
|
||||
creds := &Credentials{
|
||||
TokenProvider: opts.TokenProvider,
|
||||
@@ -242,8 +235,8 @@ func NewCredentials(opts *CredentialsOptions) *Credentials {
|
||||
return creds
|
||||
}
|
||||
|
||||
// CachedTokenProviderOptions provides options for configuring a cached
|
||||
// [TokenProvider].
|
||||
// CachedTokenProviderOptions provided options for configuring a
|
||||
// CachedTokenProvider.
|
||||
type CachedTokenProviderOptions struct {
|
||||
// DisableAutoRefresh makes the TokenProvider always return the same token,
|
||||
// even if it is expired. The default is false. Optional.
|
||||
@@ -253,7 +246,7 @@ type CachedTokenProviderOptions struct {
|
||||
// seconds. Optional.
|
||||
ExpireEarly time.Duration
|
||||
// DisableAsyncRefresh configures a synchronous workflow that refreshes
|
||||
// tokens in a blocking manner. The default is false. Optional.
|
||||
// stale tokens while blocking. The default is false. Optional.
|
||||
DisableAsyncRefresh bool
|
||||
}
|
||||
|
||||
@@ -280,7 +273,12 @@ func (ctpo *CachedTokenProviderOptions) blockingRefresh() bool {
|
||||
|
||||
// NewCachedTokenProvider wraps a [TokenProvider] to cache the tokens returned
|
||||
// by the underlying provider. By default it will refresh tokens asynchronously
|
||||
// a few minutes before they expire.
|
||||
// (non-blocking mode) within a window that starts 3 minutes and 45 seconds
|
||||
// before they expire. The asynchronous (non-blocking) refresh can be changed to
|
||||
// a synchronous (blocking) refresh using the
|
||||
// CachedTokenProviderOptions.DisableAsyncRefresh option. The time-before-expiry
|
||||
// duration can be configured using the CachedTokenProviderOptions.ExpireEarly
|
||||
// option.
|
||||
func NewCachedTokenProvider(tp TokenProvider, opts *CachedTokenProviderOptions) TokenProvider {
|
||||
if ctp, ok := tp.(*cachedTokenProvider); ok {
|
||||
return ctp
|
||||
@@ -323,9 +321,7 @@ func (c *cachedTokenProvider) tokenNonBlocking(ctx context.Context) (*Token, err
|
||||
defer c.mu.Unlock()
|
||||
return c.cachedToken, nil
|
||||
case stale:
|
||||
// Call tokenAsync with a new Context because the user-provided context
|
||||
// may have a short timeout incompatible with async token refresh.
|
||||
c.tokenAsync(context.Background())
|
||||
c.tokenAsync(ctx)
|
||||
// Return the stale token immediately to not block customer requests to Cloud services.
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
@@ -340,14 +336,13 @@ func (c *cachedTokenProvider) tokenState() tokenState {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
t := c.cachedToken
|
||||
now := timeNow()
|
||||
if t == nil || t.Value == "" {
|
||||
return invalid
|
||||
} else if t.Expiry.IsZero() {
|
||||
return fresh
|
||||
} else if now.After(t.Expiry.Round(0)) {
|
||||
} else if timeNow().After(t.Expiry.Round(0)) {
|
||||
return invalid
|
||||
} else if now.After(t.Expiry.Round(0).Add(-c.expireEarly)) {
|
||||
} else if timeNow().After(t.Expiry.Round(0).Add(-c.expireEarly)) {
|
||||
return stale
|
||||
}
|
||||
return fresh
|
||||
@@ -492,11 +487,6 @@ type Options2LO struct {
|
||||
// UseIDToken requests that the token returned be an ID token if one is
|
||||
// returned from the server. Optional.
|
||||
UseIDToken bool
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func (o *Options2LO) client() *http.Client {
|
||||
@@ -527,13 +517,12 @@ func New2LOTokenProvider(opts *Options2LO) (TokenProvider, error) {
|
||||
if err := opts.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tokenProvider2LO{opts: opts, Client: opts.client(), logger: internallog.New(opts.Logger)}, nil
|
||||
return tokenProvider2LO{opts: opts, Client: opts.client()}, nil
|
||||
}
|
||||
|
||||
type tokenProvider2LO struct {
|
||||
opts *Options2LO
|
||||
Client *http.Client
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (tp tokenProvider2LO) Token(ctx context.Context) (*Token, error) {
|
||||
@@ -568,12 +557,10 @@ func (tp tokenProvider2LO) Token(ctx context.Context) (*Token, error) {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
tp.logger.DebugContext(ctx, "2LO token request", "request", internallog.HTTPRequest(req, []byte(v.Encode())))
|
||||
resp, body, err := internal.DoRequest(tp.Client, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("auth: cannot fetch token: %w", err)
|
||||
}
|
||||
tp.logger.DebugContext(ctx, "2LO token response", "response", internallog.HTTPResponse(resp, body))
|
||||
if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices {
|
||||
return nil, &Error{
|
||||
Response: resp,
|
||||
|
||||
12
vendor/cloud.google.com/go/auth/credentials/compute.go
generated
vendored
12
vendor/cloud.google.com/go/auth/credentials/compute.go
generated
vendored
@@ -37,11 +37,8 @@ var (
|
||||
|
||||
// computeTokenProvider creates a [cloud.google.com/go/auth.TokenProvider] that
|
||||
// uses the metadata service to retrieve tokens.
|
||||
func computeTokenProvider(opts *DetectOptions, client *metadata.Client) auth.TokenProvider {
|
||||
return auth.NewCachedTokenProvider(&computeProvider{
|
||||
scopes: opts.Scopes,
|
||||
client: client,
|
||||
}, &auth.CachedTokenProviderOptions{
|
||||
func computeTokenProvider(opts *DetectOptions) auth.TokenProvider {
|
||||
return auth.NewCachedTokenProvider(computeProvider{scopes: opts.Scopes}, &auth.CachedTokenProviderOptions{
|
||||
ExpireEarly: opts.EarlyTokenRefresh,
|
||||
DisableAsyncRefresh: opts.DisableAsyncRefresh,
|
||||
})
|
||||
@@ -50,7 +47,6 @@ func computeTokenProvider(opts *DetectOptions, client *metadata.Client) auth.Tok
|
||||
// computeProvider fetches tokens from the google cloud metadata service.
|
||||
type computeProvider struct {
|
||||
scopes []string
|
||||
client *metadata.Client
|
||||
}
|
||||
|
||||
type metadataTokenResp struct {
|
||||
@@ -59,7 +55,7 @@ type metadataTokenResp struct {
|
||||
TokenType string `json:"token_type"`
|
||||
}
|
||||
|
||||
func (cs *computeProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
func (cs computeProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
tokenURI, err := url.Parse(computeTokenURI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -69,7 +65,7 @@ func (cs *computeProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
v.Set("scopes", strings.Join(cs.scopes, ","))
|
||||
tokenURI.RawQuery = v.Encode()
|
||||
}
|
||||
tokenJSON, err := cs.client.GetWithContext(ctx, tokenURI.String())
|
||||
tokenJSON, err := metadata.GetWithContext(ctx, tokenURI.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: cannot fetch token: %w", err)
|
||||
}
|
||||
|
||||
25
vendor/cloud.google.com/go/auth/credentials/detect.go
generated
vendored
25
vendor/cloud.google.com/go/auth/credentials/detect.go
generated
vendored
@@ -19,7 +19,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
@@ -28,7 +27,6 @@ import (
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/credsfile"
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -98,17 +96,12 @@ func DetectDefault(opts *DetectOptions) (*auth.Credentials, error) {
|
||||
}
|
||||
|
||||
if OnGCE() {
|
||||
metadataClient := metadata.NewWithOptions(&metadata.Options{
|
||||
Logger: opts.logger(),
|
||||
})
|
||||
return auth.NewCredentials(&auth.CredentialsOptions{
|
||||
TokenProvider: computeTokenProvider(opts, metadataClient),
|
||||
ProjectIDProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) {
|
||||
return metadataClient.ProjectIDWithContext(ctx)
|
||||
TokenProvider: computeTokenProvider(opts),
|
||||
ProjectIDProvider: auth.CredentialsPropertyFunc(func(context.Context) (string, error) {
|
||||
return metadata.ProjectID()
|
||||
}),
|
||||
UniverseDomainProvider: &internal.ComputeUniverseDomainProvider{
|
||||
MetadataClient: metadataClient,
|
||||
},
|
||||
UniverseDomainProvider: &internal.ComputeUniverseDomainProvider{},
|
||||
}), nil
|
||||
}
|
||||
|
||||
@@ -165,11 +158,6 @@ type DetectOptions struct {
|
||||
// The default value is "googleapis.com". This option is ignored for
|
||||
// authentication flows that do not support universe domain. Optional.
|
||||
UniverseDomain string
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func (o *DetectOptions) validate() error {
|
||||
@@ -205,10 +193,6 @@ func (o *DetectOptions) client() *http.Client {
|
||||
return internal.DefaultClient()
|
||||
}
|
||||
|
||||
func (o *DetectOptions) logger() *slog.Logger {
|
||||
return internallog.New(o.Logger)
|
||||
}
|
||||
|
||||
func readCredentialsFile(filename string, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
@@ -269,7 +253,6 @@ func clientCredConfigFromJSON(b []byte, opts *DetectOptions) *auth.Options3LO {
|
||||
AuthURL: c.AuthURI,
|
||||
TokenURL: c.TokenURI,
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
EarlyTokenExpiry: opts.EarlyTokenRefresh,
|
||||
AuthHandlerOpts: handleOpts,
|
||||
// TODO(codyoss): refactor this out. We need to add in auto-detection
|
||||
|
||||
23
vendor/cloud.google.com/go/auth/credentials/filetypes.go
generated
vendored
23
vendor/cloud.google.com/go/auth/credentials/filetypes.go
generated
vendored
@@ -33,7 +33,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var projectID, universeDomain string
|
||||
var projectID, quotaProjectID, universeDomain string
|
||||
var tp auth.TokenProvider
|
||||
switch fileType {
|
||||
case credsfile.ServiceAccountKey:
|
||||
@@ -56,6 +56,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
quotaProjectID = f.QuotaProjectID
|
||||
universeDomain = f.UniverseDomain
|
||||
case credsfile.ExternalAccountKey:
|
||||
f, err := credsfile.ParseExternalAccount(b)
|
||||
@@ -66,6 +67,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
quotaProjectID = f.QuotaProjectID
|
||||
universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain)
|
||||
case credsfile.ExternalAccountAuthorizedUserKey:
|
||||
f, err := credsfile.ParseExternalAccountAuthorizedUser(b)
|
||||
@@ -76,6 +78,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
quotaProjectID = f.QuotaProjectID
|
||||
universeDomain = f.UniverseDomain
|
||||
case credsfile.ImpersonatedServiceAccountKey:
|
||||
f, err := credsfile.ParseImpersonatedServiceAccount(b)
|
||||
@@ -105,9 +108,9 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
TokenProvider: auth.NewCachedTokenProvider(tp, &auth.CachedTokenProviderOptions{
|
||||
ExpireEarly: opts.EarlyTokenRefresh,
|
||||
}),
|
||||
JSON: b,
|
||||
ProjectIDProvider: internalauth.StaticCredentialsProperty(projectID),
|
||||
// TODO(codyoss): only set quota project here if there was a user override
|
||||
JSON: b,
|
||||
ProjectIDProvider: internalauth.StaticCredentialsProperty(projectID),
|
||||
QuotaProjectIDProvider: internalauth.StaticCredentialsProperty(quotaProjectID),
|
||||
UniverseDomainProvider: internalauth.StaticCredentialsProperty(universeDomain),
|
||||
}), nil
|
||||
}
|
||||
@@ -124,14 +127,8 @@ func resolveUniverseDomain(optsUniverseDomain, fileUniverseDomain string) string
|
||||
}
|
||||
|
||||
func handleServiceAccount(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) {
|
||||
ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain)
|
||||
if opts.UseSelfSignedJWT {
|
||||
return configureSelfSignedJWT(f, opts)
|
||||
} else if ud != "" && ud != internalauth.DefaultUniverseDomain {
|
||||
// For non-GDU universe domains, token exchange is impossible and services
|
||||
// must support self-signed JWTs.
|
||||
opts.UseSelfSignedJWT = true
|
||||
return configureSelfSignedJWT(f, opts)
|
||||
}
|
||||
opts2LO := &auth.Options2LO{
|
||||
Email: f.ClientEmail,
|
||||
@@ -141,7 +138,6 @@ func handleServiceAccount(f *credsfile.ServiceAccountFile, opts *DetectOptions)
|
||||
TokenURL: f.TokenURL,
|
||||
Subject: opts.Subject,
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
}
|
||||
if opts2LO.TokenURL == "" {
|
||||
opts2LO.TokenURL = jwtTokenURL
|
||||
@@ -160,7 +156,6 @@ func handleUserCredential(f *credsfile.UserCredentialsFile, opts *DetectOptions)
|
||||
EarlyTokenExpiry: opts.EarlyTokenRefresh,
|
||||
RefreshToken: f.RefreshToken,
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
}
|
||||
return auth.New3LOTokenProvider(opts3LO)
|
||||
}
|
||||
@@ -179,7 +174,6 @@ func handleExternalAccount(f *credsfile.ExternalAccountFile, opts *DetectOptions
|
||||
Scopes: opts.scopes(),
|
||||
WorkforcePoolUserProject: f.WorkforcePoolUserProject,
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
IsDefaultClient: opts.Client == nil,
|
||||
}
|
||||
if f.ServiceAccountImpersonation != nil {
|
||||
@@ -198,7 +192,6 @@ func handleExternalAccountAuthorizedUser(f *credsfile.ExternalAccountAuthorizedU
|
||||
ClientSecret: f.ClientSecret,
|
||||
Scopes: opts.scopes(),
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
}
|
||||
return externalaccountuser.NewTokenProvider(externalOpts)
|
||||
}
|
||||
@@ -218,7 +211,6 @@ func handleImpersonatedServiceAccount(f *credsfile.ImpersonatedServiceAccountFil
|
||||
Tp: tp,
|
||||
Delegates: f.Delegates,
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -226,6 +218,5 @@ func handleGDCHServiceAccount(f *credsfile.GDCHServiceAccountFile, opts *DetectO
|
||||
return gdch.NewTokenProvider(f, &gdch.Options{
|
||||
STSAudience: opts.STSAudience,
|
||||
Client: opts.client(),
|
||||
Logger: opts.logger(),
|
||||
})
|
||||
}
|
||||
|
||||
49
vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go
generated
vendored
49
vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go
generated
vendored
@@ -23,7 +23,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -33,7 +32,6 @@ import (
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -89,7 +87,6 @@ type awsSubjectProvider struct {
|
||||
reqOpts *RequestOptions
|
||||
|
||||
Client *http.Client
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (sp *awsSubjectProvider) subjectToken(ctx context.Context) (string, error) {
|
||||
@@ -97,28 +94,30 @@ func (sp *awsSubjectProvider) subjectToken(ctx context.Context) (string, error)
|
||||
if sp.RegionalCredVerificationURL == "" {
|
||||
sp.RegionalCredVerificationURL = defaultRegionalCredentialVerificationURL
|
||||
}
|
||||
headers := make(map[string]string)
|
||||
if sp.shouldUseMetadataServer() {
|
||||
awsSessionToken, err := sp.getAWSSessionToken(ctx)
|
||||
if sp.requestSigner == nil {
|
||||
headers := make(map[string]string)
|
||||
if sp.shouldUseMetadataServer() {
|
||||
awsSessionToken, err := sp.getAWSSessionToken(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if awsSessionToken != "" {
|
||||
headers[awsIMDSv2SessionTokenHeader] = awsSessionToken
|
||||
}
|
||||
}
|
||||
|
||||
awsSecurityCredentials, err := sp.getSecurityCredentials(ctx, headers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if awsSessionToken != "" {
|
||||
headers[awsIMDSv2SessionTokenHeader] = awsSessionToken
|
||||
if sp.region, err = sp.getRegion(ctx, headers); err != nil {
|
||||
return "", err
|
||||
}
|
||||
sp.requestSigner = &awsRequestSigner{
|
||||
RegionName: sp.region,
|
||||
AwsSecurityCredentials: awsSecurityCredentials,
|
||||
}
|
||||
}
|
||||
|
||||
awsSecurityCredentials, err := sp.getSecurityCredentials(ctx, headers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if sp.region, err = sp.getRegion(ctx, headers); err != nil {
|
||||
return "", err
|
||||
}
|
||||
sp.requestSigner = &awsRequestSigner{
|
||||
RegionName: sp.region,
|
||||
AwsSecurityCredentials: awsSecurityCredentials,
|
||||
}
|
||||
|
||||
// Generate the signed request to AWS STS GetCallerIdentity API.
|
||||
@@ -195,12 +194,10 @@ func (sp *awsSubjectProvider) getAWSSessionToken(ctx context.Context) (string, e
|
||||
}
|
||||
req.Header.Set(awsIMDSv2SessionTTLHeader, awsIMDSv2SessionTTL)
|
||||
|
||||
sp.logger.DebugContext(ctx, "aws session token request", "request", internallog.HTTPRequest(req, nil))
|
||||
resp, body, err := internal.DoRequest(sp.Client, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sp.logger.DebugContext(ctx, "aws session token response", "response", internallog.HTTPResponse(resp, body))
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("credentials: unable to retrieve AWS session token: %s", body)
|
||||
}
|
||||
@@ -230,12 +227,10 @@ func (sp *awsSubjectProvider) getRegion(ctx context.Context, headers map[string]
|
||||
for name, value := range headers {
|
||||
req.Header.Add(name, value)
|
||||
}
|
||||
sp.logger.DebugContext(ctx, "aws region request", "request", internallog.HTTPRequest(req, nil))
|
||||
resp, body, err := internal.DoRequest(sp.Client, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sp.logger.DebugContext(ctx, "aws region response", "response", internallog.HTTPResponse(resp, body))
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("credentials: unable to retrieve AWS region - %s", body)
|
||||
}
|
||||
@@ -290,12 +285,10 @@ func (sp *awsSubjectProvider) getMetadataSecurityCredentials(ctx context.Context
|
||||
for name, value := range headers {
|
||||
req.Header.Add(name, value)
|
||||
}
|
||||
sp.logger.DebugContext(ctx, "aws security credential request", "request", internallog.HTTPRequest(req, nil))
|
||||
resp, body, err := internal.DoRequest(sp.Client, req)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
sp.logger.DebugContext(ctx, "aws security credential response", "response", internallog.HTTPResponse(resp, body))
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return result, fmt.Errorf("credentials: unable to retrieve AWS security credentials - %s", body)
|
||||
}
|
||||
@@ -317,12 +310,10 @@ func (sp *awsSubjectProvider) getMetadataRoleName(ctx context.Context, headers m
|
||||
req.Header.Add(name, value)
|
||||
}
|
||||
|
||||
sp.logger.DebugContext(ctx, "aws metadata role request", "request", internallog.HTTPRequest(req, nil))
|
||||
resp, body, err := internal.DoRequest(sp.Client, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sp.logger.DebugContext(ctx, "aws metadata role response", "response", internallog.HTTPResponse(resp, body))
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("credentials: unable to retrieve AWS role name - %s", body)
|
||||
}
|
||||
|
||||
23
vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go
generated
vendored
23
vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go
generated
vendored
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
"cloud.google.com/go/auth/credentials/internal/impersonate"
|
||||
"cloud.google.com/go/auth/credentials/internal/stsexchange"
|
||||
"cloud.google.com/go/auth/internal/credsfile"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -106,11 +104,6 @@ type Options struct {
|
||||
// This is important for X509 credentials which should create a new client if the default was used
|
||||
// but should respect a client explicitly passed in by the user.
|
||||
IsDefaultClient bool
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// SubjectTokenProvider can be used to supply a subject token to exchange for a
|
||||
@@ -231,7 +224,6 @@ func NewTokenProvider(opts *Options) (auth.TokenProvider, error) {
|
||||
return nil, err
|
||||
}
|
||||
opts.resolveTokenURL()
|
||||
logger := internallog.New(opts.Logger)
|
||||
stp, err := newSubjectTokenProvider(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -246,7 +238,6 @@ func NewTokenProvider(opts *Options) (auth.TokenProvider, error) {
|
||||
client: client,
|
||||
opts: opts,
|
||||
stp: stp,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
if opts.ServiceAccountImpersonationURL == "" {
|
||||
@@ -263,7 +254,6 @@ func NewTokenProvider(opts *Options) (auth.TokenProvider, error) {
|
||||
Scopes: scopes,
|
||||
Tp: auth.NewCachedTokenProvider(tp, nil),
|
||||
TokenLifetimeSeconds: opts.ServiceAccountImpersonationLifetimeSeconds,
|
||||
Logger: logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -279,7 +269,6 @@ type subjectTokenProvider interface {
|
||||
// tokenProvider is the provider that handles external credentials. It is used to retrieve Tokens.
|
||||
type tokenProvider struct {
|
||||
client *http.Client
|
||||
logger *slog.Logger
|
||||
opts *Options
|
||||
stp subjectTokenProvider
|
||||
}
|
||||
@@ -321,7 +310,6 @@ func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
Authentication: clientAuth,
|
||||
Headers: header,
|
||||
ExtraOpts: options,
|
||||
Logger: tp.logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -342,14 +330,12 @@ func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
// newSubjectTokenProvider determines the type of credsfile.CredentialSource needed to create a
|
||||
// subjectTokenProvider
|
||||
func newSubjectTokenProvider(o *Options) (subjectTokenProvider, error) {
|
||||
logger := internallog.New(o.Logger)
|
||||
reqOpts := &RequestOptions{Audience: o.Audience, SubjectTokenType: o.SubjectTokenType}
|
||||
if o.AwsSecurityCredentialsProvider != nil {
|
||||
return &awsSubjectProvider{
|
||||
securityCredentialsProvider: o.AwsSecurityCredentialsProvider,
|
||||
TargetResource: o.Audience,
|
||||
reqOpts: reqOpts,
|
||||
logger: logger,
|
||||
}, nil
|
||||
} else if o.SubjectTokenProvider != nil {
|
||||
return &programmaticProvider{stp: o.SubjectTokenProvider, opts: reqOpts}, nil
|
||||
@@ -366,7 +352,6 @@ func newSubjectTokenProvider(o *Options) (subjectTokenProvider, error) {
|
||||
CredVerificationURL: o.CredentialSource.URL,
|
||||
TargetResource: o.Audience,
|
||||
Client: o.Client,
|
||||
logger: logger,
|
||||
}
|
||||
if o.CredentialSource.IMDSv2SessionTokenURL != "" {
|
||||
awsProvider.IMDSv2SessionTokenURL = o.CredentialSource.IMDSv2SessionTokenURL
|
||||
@@ -377,13 +362,7 @@ func newSubjectTokenProvider(o *Options) (subjectTokenProvider, error) {
|
||||
} else if o.CredentialSource.File != "" {
|
||||
return &fileSubjectProvider{File: o.CredentialSource.File, Format: o.CredentialSource.Format}, nil
|
||||
} else if o.CredentialSource.URL != "" {
|
||||
return &urlSubjectProvider{
|
||||
URL: o.CredentialSource.URL,
|
||||
Headers: o.CredentialSource.Headers,
|
||||
Format: o.CredentialSource.Format,
|
||||
Client: o.Client,
|
||||
Logger: logger,
|
||||
}, nil
|
||||
return &urlSubjectProvider{URL: o.CredentialSource.URL, Headers: o.CredentialSource.Headers, Format: o.CredentialSource.Format, Client: o.Client}, nil
|
||||
} else if o.CredentialSource.Executable != nil {
|
||||
ec := o.CredentialSource.Executable
|
||||
if ec.Command == "" {
|
||||
|
||||
5
vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go
generated
vendored
5
vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go
generated
vendored
@@ -19,12 +19,10 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/credsfile"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -40,7 +38,6 @@ type urlSubjectProvider struct {
|
||||
Headers map[string]string
|
||||
Format *credsfile.Format
|
||||
Client *http.Client
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func (sp *urlSubjectProvider) subjectToken(ctx context.Context) (string, error) {
|
||||
@@ -52,12 +49,10 @@ func (sp *urlSubjectProvider) subjectToken(ctx context.Context) (string, error)
|
||||
for key, val := range sp.Headers {
|
||||
req.Header.Add(key, val)
|
||||
}
|
||||
sp.Logger.DebugContext(ctx, "url subject token request", "request", internallog.HTTPRequest(req, nil))
|
||||
resp, body, err := internal.DoRequest(sp.Client, req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("credentials: invalid response when retrieving subject token: %w", err)
|
||||
}
|
||||
sp.Logger.DebugContext(ctx, "url subject token response", "response", internallog.HTTPResponse(resp, body))
|
||||
if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices {
|
||||
return "", fmt.Errorf("credentials: status code %d: %s", c, body)
|
||||
}
|
||||
|
||||
@@ -17,14 +17,12 @@ package externalaccountuser
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/credentials/internal/stsexchange"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
// Options stores the configuration for fetching tokens with external authorized
|
||||
@@ -53,8 +51,6 @@ type Options struct {
|
||||
|
||||
// Client for token request.
|
||||
Client *http.Client
|
||||
// Logger for logging.
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func (c *Options) validate() bool {
|
||||
@@ -94,7 +90,6 @@ func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
RefreshToken: opts.RefreshToken,
|
||||
Authentication: clientAuth,
|
||||
Headers: headers,
|
||||
Logger: internallog.New(tp.o.Logger),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
17
vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go
generated
vendored
17
vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go
generated
vendored
@@ -16,13 +16,12 @@ package gdch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -33,7 +32,6 @@ import (
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/credsfile"
|
||||
"cloud.google.com/go/auth/internal/jwt"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -53,7 +51,6 @@ var (
|
||||
type Options struct {
|
||||
STSAudience string
|
||||
Client *http.Client
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] from a
|
||||
@@ -65,7 +62,7 @@ func NewTokenProvider(f *credsfile.GDCHServiceAccountFile, o *Options) (auth.Tok
|
||||
if o.STSAudience == "" {
|
||||
return nil, errors.New("credentials: STSAudience must be set for the GDCH auth flows")
|
||||
}
|
||||
signer, err := internal.ParseKey([]byte(f.PrivateKey))
|
||||
pk, err := internal.ParseKey([]byte(f.PrivateKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -78,11 +75,10 @@ func NewTokenProvider(f *credsfile.GDCHServiceAccountFile, o *Options) (auth.Tok
|
||||
serviceIdentity: fmt.Sprintf("system:serviceaccount:%s:%s", f.Project, f.Name),
|
||||
tokenURL: f.TokenURL,
|
||||
aud: o.STSAudience,
|
||||
signer: signer,
|
||||
pk: pk,
|
||||
pkID: f.PrivateKeyID,
|
||||
certPool: certPool,
|
||||
client: o.Client,
|
||||
logger: internallog.New(o.Logger),
|
||||
}
|
||||
return tp, nil
|
||||
}
|
||||
@@ -101,12 +97,11 @@ type gdchProvider struct {
|
||||
serviceIdentity string
|
||||
tokenURL string
|
||||
aud string
|
||||
signer crypto.Signer
|
||||
pk *rsa.PrivateKey
|
||||
pkID string
|
||||
certPool *x509.CertPool
|
||||
|
||||
client *http.Client
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (g gdchProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
@@ -125,7 +120,7 @@ func (g gdchProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
Type: jwt.HeaderType,
|
||||
KeyID: string(g.pkID),
|
||||
}
|
||||
payload, err := jwt.EncodeJWS(&h, &claims, g.signer)
|
||||
payload, err := jwt.EncodeJWS(&h, &claims, g.pk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -141,12 +136,10 @@ func (g gdchProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
g.logger.DebugContext(ctx, "gdch token request", "request", internallog.HTTPRequest(req, []byte(v.Encode())))
|
||||
resp, body, err := internal.DoRequest(g.client, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: cannot fetch token: %w", err)
|
||||
}
|
||||
g.logger.DebugContext(ctx, "gdch token response", "response", internallog.HTTPResponse(resp, body))
|
||||
if c := resp.StatusCode; c < http.StatusOK || c > http.StatusMultipleChoices {
|
||||
return nil, &auth.Error{
|
||||
Response: resp,
|
||||
|
||||
105
vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go
generated
vendored
105
vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go
generated
vendored
@@ -1,105 +0,0 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// 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 impersonate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
var (
|
||||
universeDomainPlaceholder = "UNIVERSE_DOMAIN"
|
||||
iamCredentialsUniverseDomainEndpoint = "https://iamcredentials.UNIVERSE_DOMAIN"
|
||||
)
|
||||
|
||||
// IDTokenIAMOptions provides configuration for [IDTokenIAMOptions.Token].
|
||||
type IDTokenIAMOptions struct {
|
||||
// Client is required.
|
||||
Client *http.Client
|
||||
// Logger is required.
|
||||
Logger *slog.Logger
|
||||
UniverseDomain auth.CredentialsPropertyProvider
|
||||
ServiceAccountEmail string
|
||||
GenerateIDTokenRequest
|
||||
}
|
||||
|
||||
// GenerateIDTokenRequest holds the request to the IAM generateIdToken RPC.
|
||||
type GenerateIDTokenRequest struct {
|
||||
Audience string `json:"audience"`
|
||||
IncludeEmail bool `json:"includeEmail"`
|
||||
// Delegates are the ordered, fully-qualified resource name for service
|
||||
// accounts in a delegation chain. Each service account must be granted
|
||||
// roles/iam.serviceAccountTokenCreator on the next service account in the
|
||||
// chain. The delegates must have the following format:
|
||||
// projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}. The - wildcard
|
||||
// character is required; replacing it with a project ID is invalid.
|
||||
// Optional.
|
||||
Delegates []string `json:"delegates,omitempty"`
|
||||
}
|
||||
|
||||
// GenerateIDTokenResponse holds the response from the IAM generateIdToken RPC.
|
||||
type GenerateIDTokenResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// Token call IAM generateIdToken with the configuration provided in [IDTokenIAMOptions].
|
||||
func (o IDTokenIAMOptions) Token(ctx context.Context) (*auth.Token, error) {
|
||||
universeDomain, err := o.UniverseDomain.GetProperty(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoint := strings.Replace(iamCredentialsUniverseDomainEndpoint, universeDomainPlaceholder, universeDomain, 1)
|
||||
url := fmt.Sprintf("%s/v1/%s:generateIdToken", endpoint, internal.FormatIAMServiceAccountResource(o.ServiceAccountEmail))
|
||||
|
||||
bodyBytes, err := json.Marshal(o.GenerateIDTokenRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("impersonate: unable to marshal request: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(bodyBytes))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("impersonate: unable to create request: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
o.Logger.DebugContext(ctx, "impersonated idtoken request", "request", internallog.HTTPRequest(req, bodyBytes))
|
||||
resp, body, err := internal.DoRequest(o.Client, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("impersonate: unable to generate ID token: %w", err)
|
||||
}
|
||||
o.Logger.DebugContext(ctx, "impersonated idtoken response", "response", internallog.HTTPResponse(resp, body))
|
||||
if c := resp.StatusCode; c < 200 || c > 299 {
|
||||
return nil, fmt.Errorf("impersonate: status code %d: %s", c, body)
|
||||
}
|
||||
|
||||
var tokenResp GenerateIDTokenResponse
|
||||
if err := json.Unmarshal(body, &tokenResp); err != nil {
|
||||
return nil, fmt.Errorf("impersonate: unable to parse response: %w", err)
|
||||
}
|
||||
return &auth.Token{
|
||||
Value: tokenResp.Token,
|
||||
// Generated ID tokens are good for one hour.
|
||||
Expiry: time.Now().Add(1 * time.Hour),
|
||||
}, nil
|
||||
}
|
||||
10
vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go
generated
vendored
10
vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go
generated
vendored
@@ -20,13 +20,11 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -76,11 +74,6 @@ type Options struct {
|
||||
// Client configures the underlying client used to make network requests
|
||||
// when fetching tokens. Required.
|
||||
Client *http.Client
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func (o *Options) validate() error {
|
||||
@@ -95,7 +88,6 @@ func (o *Options) validate() error {
|
||||
|
||||
// Token performs the exchange to get a temporary service account token to allow access to GCP.
|
||||
func (o *Options) Token(ctx context.Context) (*auth.Token, error) {
|
||||
logger := internallog.New(o.Logger)
|
||||
lifetime := defaultTokenLifetime
|
||||
if o.TokenLifetimeSeconds != 0 {
|
||||
lifetime = fmt.Sprintf("%ds", o.TokenLifetimeSeconds)
|
||||
@@ -117,12 +109,10 @@ func (o *Options) Token(ctx context.Context) (*auth.Token, error) {
|
||||
if err := setAuthHeader(ctx, o.Tp, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logger.DebugContext(ctx, "impersonated token request", "request", internallog.HTTPRequest(req, b))
|
||||
resp, body, err := internal.DoRequest(o.Client, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: unable to generate access token: %w", err)
|
||||
}
|
||||
logger.DebugContext(ctx, "impersonated token response", "response", internallog.HTTPResponse(resp, body))
|
||||
if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices {
|
||||
return nil, fmt.Errorf("credentials: status code %d: %s", c, body)
|
||||
}
|
||||
|
||||
6
vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go
generated
vendored
6
vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go
generated
vendored
@@ -19,7 +19,6 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -27,7 +26,6 @@ import (
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -42,7 +40,6 @@ const (
|
||||
// Options stores the configuration for making an sts exchange request.
|
||||
type Options struct {
|
||||
Client *http.Client
|
||||
Logger *slog.Logger
|
||||
Endpoint string
|
||||
Request *TokenRequest
|
||||
Authentication ClientAuthentication
|
||||
@@ -83,7 +80,6 @@ func ExchangeToken(ctx context.Context, opts *Options) (*TokenResponse, error) {
|
||||
func doRequest(ctx context.Context, opts *Options, data url.Values) (*TokenResponse, error) {
|
||||
opts.Authentication.InjectAuthentication(data, opts.Headers)
|
||||
encodedData := data.Encode()
|
||||
logger := internallog.New(opts.Logger)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", opts.Endpoint, strings.NewReader(encodedData))
|
||||
if err != nil {
|
||||
@@ -97,12 +93,10 @@ func doRequest(ctx context.Context, opts *Options, data url.Values) (*TokenRespo
|
||||
}
|
||||
req.Header.Set("Content-Length", strconv.Itoa(len(encodedData)))
|
||||
|
||||
logger.DebugContext(ctx, "sts token request", "request", internallog.HTTPRequest(req, []byte(encodedData)))
|
||||
resp, body, err := internal.DoRequest(opts.Client, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: invalid response from Secure Token Server: %w", err)
|
||||
}
|
||||
logger.DebugContext(ctx, "sts token response", "response", internallog.HTTPResponse(resp, body))
|
||||
if c := resp.StatusCode; c < http.StatusOK || c > http.StatusMultipleChoices {
|
||||
return nil, fmt.Errorf("credentials: status code %d: %s", c, body)
|
||||
}
|
||||
|
||||
20
vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go
generated
vendored
20
vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go
generated
vendored
@@ -16,10 +16,8 @@ package credentials
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"errors"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -37,10 +35,7 @@ var (
|
||||
// configureSelfSignedJWT uses the private key in the service account to create
|
||||
// a JWT without making a network call.
|
||||
func configureSelfSignedJWT(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) {
|
||||
if len(opts.scopes()) == 0 && opts.Audience == "" {
|
||||
return nil, errors.New("credentials: both scopes and audience are empty")
|
||||
}
|
||||
signer, err := internal.ParseKey([]byte(f.PrivateKey))
|
||||
pk, err := internal.ParseKey([]byte(f.PrivateKey))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: could not parse key: %w", err)
|
||||
}
|
||||
@@ -48,9 +43,8 @@ func configureSelfSignedJWT(f *credsfile.ServiceAccountFile, opts *DetectOptions
|
||||
email: f.ClientEmail,
|
||||
audience: opts.Audience,
|
||||
scopes: opts.scopes(),
|
||||
signer: signer,
|
||||
pk: pk,
|
||||
pkID: f.PrivateKeyID,
|
||||
logger: opts.logger(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -58,9 +52,8 @@ type selfSignedTokenProvider struct {
|
||||
email string
|
||||
audience string
|
||||
scopes []string
|
||||
signer crypto.Signer
|
||||
pk *rsa.PrivateKey
|
||||
pkID string
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (tp *selfSignedTokenProvider) Token(context.Context) (*auth.Token, error) {
|
||||
@@ -80,10 +73,9 @@ func (tp *selfSignedTokenProvider) Token(context.Context) (*auth.Token, error) {
|
||||
Type: jwt.HeaderType,
|
||||
KeyID: string(tp.pkID),
|
||||
}
|
||||
tok, err := jwt.EncodeJWS(h, c, tp.signer)
|
||||
msg, err := jwt.EncodeJWS(h, c, tp.pk)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: could not encode JWT: %w", err)
|
||||
}
|
||||
tp.logger.Debug("created self-signed JWT", "token", tok)
|
||||
return &auth.Token{Value: tok, Type: internal.TokenTypeBearer, Expiry: exp}, nil
|
||||
return &auth.Token{Value: msg, Type: internal.TokenTypeBearer, Expiry: exp}, nil
|
||||
}
|
||||
|
||||
9
vendor/cloud.google.com/go/auth/grpctransport/directpath.go
generated
vendored
9
vendor/cloud.google.com/go/auth/grpctransport/directpath.go
generated
vendored
@@ -22,7 +22,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/internal/compute"
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
"google.golang.org/grpc"
|
||||
grpcgoogle "google.golang.org/grpc/credentials/google"
|
||||
)
|
||||
@@ -55,7 +55,7 @@ func checkDirectPathEndPoint(endpoint string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isTokenProviderDirectPathCompatible(tp auth.TokenProvider, o *Options) bool {
|
||||
func isTokenProviderDirectPathCompatible(tp auth.TokenProvider, _ *Options) bool {
|
||||
if tp == nil {
|
||||
return false
|
||||
}
|
||||
@@ -69,9 +69,6 @@ func isTokenProviderDirectPathCompatible(tp auth.TokenProvider, o *Options) bool
|
||||
if tok.MetadataString("auth.google.tokenSource") != "compute-metadata" {
|
||||
return false
|
||||
}
|
||||
if o.InternalOptions != nil && o.InternalOptions.EnableNonDefaultSAForDirectPath {
|
||||
return true
|
||||
}
|
||||
if tok.MetadataString("auth.google.serviceAccount") != "default" {
|
||||
return false
|
||||
}
|
||||
@@ -94,7 +91,7 @@ func isDirectPathXdsUsed(o *Options) bool {
|
||||
// configuration allows the use of direct path. If it does not the provided
|
||||
// grpcOpts and endpoint are returned.
|
||||
func configureDirectPath(grpcOpts []grpc.DialOption, opts *Options, endpoint string, creds *auth.Credentials) ([]grpc.DialOption, string) {
|
||||
if isDirectPathEnabled(endpoint, opts) && compute.OnComputeEngine() && isTokenProviderDirectPathCompatible(creds, opts) {
|
||||
if isDirectPathEnabled(endpoint, opts) && metadata.OnGCE() && isTokenProviderDirectPathCompatible(creds, opts) {
|
||||
// Overwrite all of the previously specific DialOptions, DirectPath uses its own set of credentials and certificates.
|
||||
grpcOpts = []grpc.DialOption{
|
||||
grpc.WithCredentialsBundle(grpcgoogle.NewDefaultCredentialsWithOptions(grpcgoogle.DefaultCredentialsOptions{PerRPCCreds: &grpcCredentialsProvider{creds: creds}}))}
|
||||
|
||||
80
vendor/cloud.google.com/go/auth/grpctransport/grpctransport.go
generated
vendored
80
vendor/cloud.google.com/go/auth/grpctransport/grpctransport.go
generated
vendored
@@ -12,8 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package grpctransport provides functionality for managing gRPC client
|
||||
// connections to Google Cloud services.
|
||||
package grpctransport
|
||||
|
||||
import (
|
||||
@@ -21,21 +19,16 @@ import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/credentials"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"google.golang.org/grpc"
|
||||
grpccreds "google.golang.org/grpc/credentials"
|
||||
grpcinsecure "google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/stats"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,7 +38,7 @@ const (
|
||||
// Check env to decide if using google-c2p resolver for DirectPath traffic.
|
||||
enableDirectPathXdsEnvVar = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS"
|
||||
|
||||
quotaProjectHeaderKey = "X-goog-user-project"
|
||||
quotaProjectHeaderKey = "X-Goog-User-Project"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -53,27 +46,6 @@ var (
|
||||
timeoutDialerOption grpc.DialOption
|
||||
)
|
||||
|
||||
// otelStatsHandler is a singleton otelgrpc.clientHandler to be used across
|
||||
// all dial connections to avoid the memory leak documented in
|
||||
// https://github.com/open-telemetry/opentelemetry-go-contrib/issues/4226
|
||||
//
|
||||
// TODO: When this module depends on a version of otelgrpc containing the fix,
|
||||
// replace this singleton with inline usage for simplicity.
|
||||
// The fix should be in https://github.com/open-telemetry/opentelemetry-go/pull/5797.
|
||||
var (
|
||||
initOtelStatsHandlerOnce sync.Once
|
||||
otelStatsHandler stats.Handler
|
||||
)
|
||||
|
||||
// otelGRPCStatsHandler returns singleton otelStatsHandler for reuse across all
|
||||
// dial connections.
|
||||
func otelGRPCStatsHandler() stats.Handler {
|
||||
initOtelStatsHandlerOnce.Do(func() {
|
||||
otelStatsHandler = otelgrpc.NewClientHandler()
|
||||
})
|
||||
return otelStatsHandler
|
||||
}
|
||||
|
||||
// ClientCertProvider is a function that returns a TLS client certificate to be
|
||||
// used when opening TLS connections. It follows the same semantics as
|
||||
// [crypto/tls.Config.GetClientCertificate].
|
||||
@@ -118,11 +90,6 @@ type Options struct {
|
||||
// APIKey specifies an API key to be used as the basis for authentication.
|
||||
// If set DetectOpts are ignored.
|
||||
APIKey string
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
|
||||
// InternalOptions are NOT meant to be set directly by consumers of this
|
||||
// package, they should only be set by generated client code.
|
||||
@@ -138,10 +105,6 @@ func (o *Options) client() *http.Client {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options) logger() *slog.Logger {
|
||||
return internallog.New(o.Logger)
|
||||
}
|
||||
|
||||
func (o *Options) validate() error {
|
||||
if o == nil {
|
||||
return errors.New("grpctransport: opts required to be non-nil")
|
||||
@@ -183,9 +146,6 @@ func (o *Options) resolveDetectOptions() *credentials.DetectOptions {
|
||||
do.Client = transport.DefaultHTTPClientWithTLS(tlsConfig)
|
||||
do.TokenURL = credentials.GoogleMTLSTokenURL
|
||||
}
|
||||
if do.Logger == nil {
|
||||
do.Logger = o.logger()
|
||||
}
|
||||
return do
|
||||
}
|
||||
|
||||
@@ -254,7 +214,6 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er
|
||||
ClientCertProvider: opts.ClientCertProvider,
|
||||
Client: opts.client(),
|
||||
UniverseDomain: opts.UniverseDomain,
|
||||
Logger: opts.logger(),
|
||||
}
|
||||
if io := opts.InternalOptions; io != nil {
|
||||
tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate
|
||||
@@ -312,10 +271,7 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er
|
||||
if metadata == nil {
|
||||
metadata = make(map[string]string, 1)
|
||||
}
|
||||
// Don't overwrite user specified quota
|
||||
if _, ok := metadata[quotaProjectHeaderKey]; !ok {
|
||||
metadata[quotaProjectHeaderKey] = qp
|
||||
}
|
||||
metadata[quotaProjectHeaderKey] = qp
|
||||
}
|
||||
grpcOpts = append(grpcOpts,
|
||||
grpc.WithPerRPCCredentials(&grpcCredentialsProvider{
|
||||
@@ -332,10 +288,10 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er
|
||||
// Add tracing, but before the other options, so that clients can override the
|
||||
// gRPC stats handler.
|
||||
// This assumes that gRPC options are processed in order, left to right.
|
||||
grpcOpts = addOpenTelemetryStatsHandler(grpcOpts, opts)
|
||||
grpcOpts = addOCStatsHandler(grpcOpts, opts)
|
||||
grpcOpts = append(grpcOpts, opts.GRPCDialOpts...)
|
||||
|
||||
return grpc.Dial(endpoint, grpcOpts...)
|
||||
return grpc.DialContext(ctx, endpoint, grpcOpts...)
|
||||
}
|
||||
|
||||
// grpcKeyProvider satisfies https://pkg.go.dev/google.golang.org/grpc/credentials#PerRPCCredentials.
|
||||
@@ -369,23 +325,15 @@ type grpcCredentialsProvider struct {
|
||||
clientUniverseDomain string
|
||||
}
|
||||
|
||||
// getClientUniverseDomain returns the default service domain for a given Cloud
|
||||
// universe, with the following precedence:
|
||||
//
|
||||
// 1. A non-empty option.WithUniverseDomain or similar client option.
|
||||
// 2. A non-empty environment variable GOOGLE_CLOUD_UNIVERSE_DOMAIN.
|
||||
// 3. The default value "googleapis.com".
|
||||
//
|
||||
// This is the universe domain configured for the client, which will be compared
|
||||
// to the universe domain that is separately configured for the credentials.
|
||||
// getClientUniverseDomain returns the default service domain for a given Cloud universe.
|
||||
// The default value is "googleapis.com". This is the universe domain
|
||||
// configured for the client, which will be compared to the universe domain
|
||||
// that is separately configured for the credentials.
|
||||
func (c *grpcCredentialsProvider) getClientUniverseDomain() string {
|
||||
if c.clientUniverseDomain != "" {
|
||||
return c.clientUniverseDomain
|
||||
if c.clientUniverseDomain == "" {
|
||||
return internal.DefaultUniverseDomain
|
||||
}
|
||||
if envUD := os.Getenv(internal.UniverseDomainEnvVar); envUD != "" {
|
||||
return envUD
|
||||
}
|
||||
return internal.DefaultUniverseDomain
|
||||
return c.clientUniverseDomain
|
||||
}
|
||||
|
||||
func (c *grpcCredentialsProvider) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
|
||||
@@ -430,9 +378,9 @@ func (c *grpcCredentialsProvider) RequireTransportSecurity() bool {
|
||||
return c.secure
|
||||
}
|
||||
|
||||
func addOpenTelemetryStatsHandler(dialOpts []grpc.DialOption, opts *Options) []grpc.DialOption {
|
||||
func addOCStatsHandler(dialOpts []grpc.DialOption, opts *Options) []grpc.DialOption {
|
||||
if opts.DisableTelemetry {
|
||||
return dialOpts
|
||||
}
|
||||
return append(dialOpts, grpc.WithStatsHandler(otelGRPCStatsHandler()))
|
||||
return append(dialOpts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
|
||||
}
|
||||
|
||||
27
vendor/cloud.google.com/go/auth/httptransport/httptransport.go
generated
vendored
27
vendor/cloud.google.com/go/auth/httptransport/httptransport.go
generated
vendored
@@ -12,22 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package httptransport provides functionality for managing HTTP client
|
||||
// connections to Google Cloud services.
|
||||
package httptransport
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
detect "cloud.google.com/go/auth/credentials"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
// ClientCertProvider is a function that returns a TLS client certificate to be
|
||||
@@ -71,11 +67,6 @@ type Options struct {
|
||||
// configured for the client, which will be compared to the universe domain
|
||||
// that is separately configured for the credentials.
|
||||
UniverseDomain string
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
|
||||
// InternalOptions are NOT meant to be set directly by consumers of this
|
||||
// package, they should only be set by generated client code.
|
||||
@@ -108,10 +99,6 @@ func (o *Options) client() *http.Client {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options) logger() *slog.Logger {
|
||||
return internallog.New(o.Logger)
|
||||
}
|
||||
|
||||
func (o *Options) resolveDetectOptions() *detect.DetectOptions {
|
||||
io := o.InternalOptions
|
||||
// soft-clone these so we are not updating a ref the user holds and may reuse
|
||||
@@ -136,9 +123,6 @@ func (o *Options) resolveDetectOptions() *detect.DetectOptions {
|
||||
do.Client = transport.DefaultHTTPClientWithTLS(tlsConfig)
|
||||
do.TokenURL = detect.GoogleMTLSTokenURL
|
||||
}
|
||||
if do.Logger == nil {
|
||||
do.Logger = o.logger()
|
||||
}
|
||||
return do
|
||||
}
|
||||
|
||||
@@ -161,21 +145,14 @@ type InternalOptions struct {
|
||||
// service.
|
||||
DefaultScopes []string
|
||||
// SkipValidation bypasses validation on Options. It should only be used
|
||||
// internally for clients that need more control over their transport.
|
||||
// internally for clients that needs more control over their transport.
|
||||
SkipValidation bool
|
||||
// SkipUniverseDomainValidation skips the verification that the universe
|
||||
// domain configured for the client matches the universe domain configured
|
||||
// for the credentials. It should only be used internally for clients that
|
||||
// need more control over their transport. The default is false.
|
||||
SkipUniverseDomainValidation bool
|
||||
}
|
||||
|
||||
// AddAuthorizationMiddleware adds a middleware to the provided client's
|
||||
// transport that sets the Authorization header with the value produced by the
|
||||
// provided [cloud.google.com/go/auth.Credentials]. An error is returned only
|
||||
// if client or creds is nil.
|
||||
//
|
||||
// This function does not support setting a universe domain value on the client.
|
||||
func AddAuthorizationMiddleware(client *http.Client, creds *auth.Credentials) error {
|
||||
if client == nil || creds == nil {
|
||||
return fmt.Errorf("httptransport: client and tp must not be nil")
|
||||
@@ -194,6 +171,7 @@ func AddAuthorizationMiddleware(client *http.Client, creds *auth.Credentials) er
|
||||
client.Transport = &authTransport{
|
||||
creds: creds,
|
||||
base: base,
|
||||
// TODO(quartzmo): Somehow set clientUniverseDomain from impersonate calls.
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -211,7 +189,6 @@ func NewClient(opts *Options) (*http.Client, error) {
|
||||
ClientCertProvider: opts.ClientCertProvider,
|
||||
Client: opts.client(),
|
||||
UniverseDomain: opts.UniverseDomain,
|
||||
Logger: opts.logger(),
|
||||
}
|
||||
if io := opts.InternalOptions; io != nil {
|
||||
tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate
|
||||
|
||||
93
vendor/cloud.google.com/go/auth/httptransport/trace.go
generated
vendored
Normal file
93
vendor/cloud.google.com/go/auth/httptransport/trace.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// 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 httptransport
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
"go.opencensus.io/trace/propagation"
|
||||
)
|
||||
|
||||
const (
|
||||
httpHeaderMaxSize = 200
|
||||
cloudTraceHeader = `X-Cloud-Trace-Context`
|
||||
)
|
||||
|
||||
// asserts the httpFormat fulfills this foreign interface
|
||||
var _ propagation.HTTPFormat = (*httpFormat)(nil)
|
||||
|
||||
// httpFormat implements propagation.httpFormat to propagate
|
||||
// traces in HTTP headers for Google Cloud Platform and Cloud Trace.
|
||||
type httpFormat struct{}
|
||||
|
||||
// SpanContextFromRequest extracts a Cloud Trace span context from incoming requests.
|
||||
func (f *httpFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) {
|
||||
h := req.Header.Get(cloudTraceHeader)
|
||||
// See https://cloud.google.com/trace/docs/faq for the header HTTPFormat.
|
||||
// Return if the header is empty or missing, or if the header is unreasonably
|
||||
// large, to avoid making unnecessary copies of a large string.
|
||||
if h == "" || len(h) > httpHeaderMaxSize {
|
||||
return trace.SpanContext{}, false
|
||||
}
|
||||
|
||||
// Parse the trace id field.
|
||||
slash := strings.Index(h, `/`)
|
||||
if slash == -1 {
|
||||
return trace.SpanContext{}, false
|
||||
}
|
||||
tid, h := h[:slash], h[slash+1:]
|
||||
|
||||
buf, err := hex.DecodeString(tid)
|
||||
if err != nil {
|
||||
return trace.SpanContext{}, false
|
||||
}
|
||||
copy(sc.TraceID[:], buf)
|
||||
|
||||
// Parse the span id field.
|
||||
spanstr := h
|
||||
semicolon := strings.Index(h, `;`)
|
||||
if semicolon != -1 {
|
||||
spanstr, h = h[:semicolon], h[semicolon+1:]
|
||||
}
|
||||
sid, err := strconv.ParseUint(spanstr, 10, 64)
|
||||
if err != nil {
|
||||
return trace.SpanContext{}, false
|
||||
}
|
||||
binary.BigEndian.PutUint64(sc.SpanID[:], sid)
|
||||
|
||||
// Parse the options field, options field is optional.
|
||||
if !strings.HasPrefix(h, "o=") {
|
||||
return sc, true
|
||||
}
|
||||
o, err := strconv.ParseUint(h[2:], 10, 32)
|
||||
if err != nil {
|
||||
return trace.SpanContext{}, false
|
||||
}
|
||||
sc.TraceOptions = trace.TraceOptions(o)
|
||||
return sc, true
|
||||
}
|
||||
|
||||
// SpanContextToRequest modifies the given request to include a Cloud Trace header.
|
||||
func (f *httpFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) {
|
||||
sid := binary.BigEndian.Uint64(sc.SpanID[:])
|
||||
header := fmt.Sprintf("%s/%d;o=%d", hex.EncodeToString(sc.TraceID[:]), sid, int64(sc.TraceOptions))
|
||||
req.Header.Set(cloudTraceHeader, header)
|
||||
}
|
||||
65
vendor/cloud.google.com/go/auth/httptransport/transport.go
generated
vendored
65
vendor/cloud.google.com/go/auth/httptransport/transport.go
generated
vendored
@@ -19,7 +19,6 @@ import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
@@ -27,12 +26,12 @@ import (
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"cloud.google.com/go/auth/internal/transport/cert"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
const (
|
||||
quotaProjectHeaderKey = "X-goog-user-project"
|
||||
quotaProjectHeaderKey = "X-Goog-User-Project"
|
||||
)
|
||||
|
||||
func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, error) {
|
||||
@@ -42,7 +41,7 @@ func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, err
|
||||
headers: headers,
|
||||
}
|
||||
var trans http.RoundTripper = ht
|
||||
trans = addOpenTelemetryTransport(trans, opts)
|
||||
trans = addOCTransport(trans, opts)
|
||||
switch {
|
||||
case opts.DisableAuthentication:
|
||||
// Do nothing.
|
||||
@@ -77,21 +76,13 @@ func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, err
|
||||
if headers == nil {
|
||||
headers = make(map[string][]string, 1)
|
||||
}
|
||||
// Don't overwrite user specified quota
|
||||
if v := headers.Get(quotaProjectHeaderKey); v == "" {
|
||||
headers.Set(quotaProjectHeaderKey, qp)
|
||||
}
|
||||
}
|
||||
var skipUD bool
|
||||
if iOpts := opts.InternalOptions; iOpts != nil {
|
||||
skipUD = iOpts.SkipUniverseDomainValidation
|
||||
headers.Set(quotaProjectHeaderKey, qp)
|
||||
}
|
||||
creds.TokenProvider = auth.NewCachedTokenProvider(creds.TokenProvider, nil)
|
||||
trans = &authTransport{
|
||||
base: trans,
|
||||
creds: creds,
|
||||
clientUniverseDomain: opts.UniverseDomain,
|
||||
skipUniverseDomainValidation: skipUD,
|
||||
base: trans,
|
||||
creds: creds,
|
||||
clientUniverseDomain: opts.UniverseDomain,
|
||||
}
|
||||
}
|
||||
return trans, nil
|
||||
@@ -103,11 +94,7 @@ func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, err
|
||||
// http.DefaultTransport.
|
||||
// If TLSCertificate is available, set TLSClientConfig as well.
|
||||
func defaultBaseTransport(clientCertSource cert.Provider, dialTLSContext func(context.Context, string, string) (net.Conn, error)) http.RoundTripper {
|
||||
defaultTransport, ok := http.DefaultTransport.(*http.Transport)
|
||||
if !ok {
|
||||
defaultTransport = transport.BaseTransport()
|
||||
}
|
||||
trans := defaultTransport.Clone()
|
||||
trans := http.DefaultTransport.(*http.Transport).Clone()
|
||||
trans.MaxIdleConnsPerHost = 100
|
||||
|
||||
if clientCertSource != nil {
|
||||
@@ -168,37 +155,29 @@ func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return rt.RoundTrip(&newReq)
|
||||
}
|
||||
|
||||
func addOpenTelemetryTransport(trans http.RoundTripper, opts *Options) http.RoundTripper {
|
||||
func addOCTransport(trans http.RoundTripper, opts *Options) http.RoundTripper {
|
||||
if opts.DisableTelemetry {
|
||||
return trans
|
||||
}
|
||||
return otelhttp.NewTransport(trans)
|
||||
return &ochttp.Transport{
|
||||
Base: trans,
|
||||
Propagation: &httpFormat{},
|
||||
}
|
||||
}
|
||||
|
||||
type authTransport struct {
|
||||
creds *auth.Credentials
|
||||
base http.RoundTripper
|
||||
clientUniverseDomain string
|
||||
skipUniverseDomainValidation bool
|
||||
creds *auth.Credentials
|
||||
base http.RoundTripper
|
||||
clientUniverseDomain string
|
||||
}
|
||||
|
||||
// getClientUniverseDomain returns the default service domain for a given Cloud
|
||||
// universe, with the following precedence:
|
||||
//
|
||||
// 1. A non-empty option.WithUniverseDomain or similar client option.
|
||||
// 2. A non-empty environment variable GOOGLE_CLOUD_UNIVERSE_DOMAIN.
|
||||
// 3. The default value "googleapis.com".
|
||||
//
|
||||
// This is the universe domain configured for the client, which will be compared
|
||||
// to the universe domain that is separately configured for the credentials.
|
||||
// getClientUniverseDomain returns the universe domain configured for the client.
|
||||
// The default value is "googleapis.com".
|
||||
func (t *authTransport) getClientUniverseDomain() string {
|
||||
if t.clientUniverseDomain != "" {
|
||||
return t.clientUniverseDomain
|
||||
if t.clientUniverseDomain == "" {
|
||||
return internal.DefaultUniverseDomain
|
||||
}
|
||||
if envUD := os.Getenv(internal.UniverseDomainEnvVar); envUD != "" {
|
||||
return envUD
|
||||
}
|
||||
return internal.DefaultUniverseDomain
|
||||
return t.clientUniverseDomain
|
||||
}
|
||||
|
||||
// RoundTrip authorizes and authenticates the request with an
|
||||
@@ -218,7 +197,7 @@ func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !t.skipUniverseDomainValidation && token.MetadataString("auth.google.tokenSource") != "compute-metadata" {
|
||||
if token.MetadataString("auth.google.tokenSource") != "compute-metadata" {
|
||||
credentialsUniverseDomain, err := t.creds.UniverseDomain(req.Context())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
65
vendor/cloud.google.com/go/auth/internal/compute/compute.go
generated
vendored
65
vendor/cloud.google.com/go/auth/internal/compute/compute.go
generated
vendored
@@ -1,65 +0,0 @@
|
||||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"log"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
vmOnGCEOnce sync.Once
|
||||
vmOnGCE bool
|
||||
)
|
||||
|
||||
// OnComputeEngine returns whether the client is running on GCE.
|
||||
//
|
||||
// This is a copy of the gRPC internal googlecloud.OnGCE() func at:
|
||||
// https://github.com/grpc/grpc-go/blob/master/internal/googlecloud/googlecloud.go
|
||||
// The functionality is similar to the metadata.OnGCE() func at:
|
||||
// https://github.com/googleapis/google-cloud-go/blob/main/compute/metadata/metadata.go
|
||||
// The difference is that OnComputeEngine() does not perform HTTP or DNS check on the metadata server.
|
||||
// In particular, OnComputeEngine() will return false on Serverless.
|
||||
func OnComputeEngine() bool {
|
||||
vmOnGCEOnce.Do(func() {
|
||||
mf, err := manufacturer()
|
||||
if err != nil {
|
||||
log.Printf("Failed to read manufacturer, vmOnGCE=false: %v", err)
|
||||
return
|
||||
}
|
||||
vmOnGCE = isRunningOnGCE(mf, runtime.GOOS)
|
||||
})
|
||||
return vmOnGCE
|
||||
}
|
||||
|
||||
// isRunningOnGCE checks whether the local system, without doing a network request, is
|
||||
// running on GCP.
|
||||
func isRunningOnGCE(manufacturer []byte, goos string) bool {
|
||||
name := string(manufacturer)
|
||||
switch goos {
|
||||
case "linux":
|
||||
name = strings.TrimSpace(name)
|
||||
return name == "Google" || name == "Google Compute Engine"
|
||||
case "windows":
|
||||
name = strings.Replace(name, " ", "", -1)
|
||||
name = strings.Replace(name, "\n", "", -1)
|
||||
name = strings.Replace(name, "\r", "", -1)
|
||||
return name == "Google"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
46
vendor/cloud.google.com/go/auth/internal/compute/manufacturer_windows.go
generated
vendored
46
vendor/cloud.google.com/go/auth/internal/compute/manufacturer_windows.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
windowsCheckCommand = "powershell.exe"
|
||||
windowsCheckCommandArgs = "Get-WmiObject -Class Win32_BIOS"
|
||||
powershellOutputFilter = "Manufacturer"
|
||||
windowsManufacturerRegex = ":(.*)"
|
||||
)
|
||||
|
||||
func manufacturer() ([]byte, error) {
|
||||
cmd := exec.Command(windowsCheckCommand, windowsCheckCommandArgs)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, line := range strings.Split(strings.TrimSuffix(string(out), "\n"), "\n") {
|
||||
if strings.HasPrefix(line, powershellOutputFilter) {
|
||||
re := regexp.MustCompile(windowsManufacturerRegex)
|
||||
name := re.FindString(line)
|
||||
name = strings.TrimLeft(name, ":")
|
||||
return []byte(name), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("cannot determine the machine's manufacturer")
|
||||
}
|
||||
38
vendor/cloud.google.com/go/auth/internal/internal.go
generated
vendored
38
vendor/cloud.google.com/go/auth/internal/internal.go
generated
vendored
@@ -16,7 +16,7 @@ package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
@@ -38,11 +38,8 @@ const (
|
||||
// QuotaProjectEnvVar is the environment variable for setting the quota
|
||||
// project.
|
||||
QuotaProjectEnvVar = "GOOGLE_CLOUD_QUOTA_PROJECT"
|
||||
// UniverseDomainEnvVar is the environment variable for setting the default
|
||||
// service domain for a given Cloud universe.
|
||||
UniverseDomainEnvVar = "GOOGLE_CLOUD_UNIVERSE_DOMAIN"
|
||||
projectEnvVar = "GOOGLE_CLOUD_PROJECT"
|
||||
maxBodySize = 1 << 20
|
||||
projectEnvVar = "GOOGLE_CLOUD_PROJECT"
|
||||
maxBodySize = 1 << 20
|
||||
|
||||
// DefaultUniverseDomain is the default value for universe domain.
|
||||
// Universe domain is the default service domain for a given Cloud universe.
|
||||
@@ -72,27 +69,25 @@ func DefaultClient() *http.Client {
|
||||
}
|
||||
|
||||
// ParseKey converts the binary contents of a private key file
|
||||
// to an crypto.Signer. It detects whether the private key is in a
|
||||
// to an *rsa.PrivateKey. It detects whether the private key is in a
|
||||
// PEM container or not. If so, it extracts the the private key
|
||||
// from PEM container before conversion. It only supports PEM
|
||||
// containers with no passphrase.
|
||||
func ParseKey(key []byte) (crypto.Signer, error) {
|
||||
func ParseKey(key []byte) (*rsa.PrivateKey, error) {
|
||||
block, _ := pem.Decode(key)
|
||||
if block != nil {
|
||||
key = block.Bytes
|
||||
}
|
||||
var parsedKey crypto.PrivateKey
|
||||
var err error
|
||||
parsedKey, err = x509.ParsePKCS8PrivateKey(key)
|
||||
parsedKey, err := x509.ParsePKCS8PrivateKey(key)
|
||||
if err != nil {
|
||||
parsedKey, err = x509.ParsePKCS1PrivateKey(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8: %w", err)
|
||||
}
|
||||
}
|
||||
parsed, ok := parsedKey.(crypto.Signer)
|
||||
parsed, ok := parsedKey.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errors.New("private key is not a signer")
|
||||
return nil, errors.New("private key is invalid")
|
||||
}
|
||||
return parsed, nil
|
||||
}
|
||||
@@ -181,7 +176,6 @@ func (p StaticProperty) GetProperty(context.Context) (string, error) {
|
||||
// ComputeUniverseDomainProvider fetches the credentials universe domain from
|
||||
// the google cloud metadata service.
|
||||
type ComputeUniverseDomainProvider struct {
|
||||
MetadataClient *metadata.Client
|
||||
universeDomainOnce sync.Once
|
||||
universeDomain string
|
||||
universeDomainErr error
|
||||
@@ -191,7 +185,7 @@ type ComputeUniverseDomainProvider struct {
|
||||
// metadata service.
|
||||
func (c *ComputeUniverseDomainProvider) GetProperty(ctx context.Context) (string, error) {
|
||||
c.universeDomainOnce.Do(func() {
|
||||
c.universeDomain, c.universeDomainErr = getMetadataUniverseDomain(ctx, c.MetadataClient)
|
||||
c.universeDomain, c.universeDomainErr = getMetadataUniverseDomain(ctx)
|
||||
})
|
||||
if c.universeDomainErr != nil {
|
||||
return "", c.universeDomainErr
|
||||
@@ -200,14 +194,14 @@ func (c *ComputeUniverseDomainProvider) GetProperty(ctx context.Context) (string
|
||||
}
|
||||
|
||||
// httpGetMetadataUniverseDomain is a package var for unit test substitution.
|
||||
var httpGetMetadataUniverseDomain = func(ctx context.Context, client *metadata.Client) (string, error) {
|
||||
var httpGetMetadataUniverseDomain = func(ctx context.Context) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
|
||||
defer cancel()
|
||||
return client.GetWithContext(ctx, "universe/universe-domain")
|
||||
return metadata.GetWithContext(ctx, "universe/universe_domain")
|
||||
}
|
||||
|
||||
func getMetadataUniverseDomain(ctx context.Context, client *metadata.Client) (string, error) {
|
||||
universeDomain, err := httpGetMetadataUniverseDomain(ctx, client)
|
||||
func getMetadataUniverseDomain(ctx context.Context) (string, error) {
|
||||
universeDomain, err := httpGetMetadataUniverseDomain(ctx)
|
||||
if err == nil {
|
||||
return universeDomain, nil
|
||||
}
|
||||
@@ -217,9 +211,3 @@ func getMetadataUniverseDomain(ctx context.Context, client *metadata.Client) (st
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
// FormatIAMServiceAccountResource sets a service account name in an IAM resource
|
||||
// name.
|
||||
func FormatIAMServiceAccountResource(name string) string {
|
||||
return fmt.Sprintf("projects/-/serviceAccounts/%s", name)
|
||||
}
|
||||
|
||||
4
vendor/cloud.google.com/go/auth/internal/jwt/jwt.go
generated
vendored
4
vendor/cloud.google.com/go/auth/internal/jwt/jwt.go
generated
vendored
@@ -111,7 +111,7 @@ func (c *Claims) encode() (string, error) {
|
||||
}
|
||||
|
||||
// EncodeJWS encodes the data using the provided key as a JSON web signature.
|
||||
func EncodeJWS(header *Header, c *Claims, signer crypto.Signer) (string, error) {
|
||||
func EncodeJWS(header *Header, c *Claims, key *rsa.PrivateKey) (string, error) {
|
||||
head, err := header.encode()
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -123,7 +123,7 @@ func EncodeJWS(header *Header, c *Claims, signer crypto.Signer) (string, error)
|
||||
ss := fmt.Sprintf("%s.%s", head, claims)
|
||||
h := sha256.New()
|
||||
h.Write([]byte(ss))
|
||||
sig, err := signer.Sign(rand.Reader, h.Sum(nil), crypto.SHA256)
|
||||
sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
56
vendor/cloud.google.com/go/auth/internal/transport/cba.go
generated
vendored
56
vendor/cloud.google.com/go/auth/internal/transport/cba.go
generated
vendored
@@ -20,7 +20,6 @@ import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -52,19 +51,22 @@ const (
|
||||
mtlsMDSKey = "/run/google-mds-mtls/client.key"
|
||||
)
|
||||
|
||||
var (
|
||||
errUniverseNotSupportedMTLS = errors.New("mTLS is not supported in any universe other than googleapis.com")
|
||||
)
|
||||
|
||||
// Options is a struct that is duplicated information from the individual
|
||||
// transport packages in order to avoid cyclic deps. It correlates 1:1 with
|
||||
// fields on httptransport.Options and grpctransport.Options.
|
||||
type Options struct {
|
||||
Endpoint string
|
||||
DefaultEndpointTemplate string
|
||||
DefaultMTLSEndpoint string
|
||||
DefaultEndpointTemplate string
|
||||
ClientCertProvider cert.Provider
|
||||
Client *http.Client
|
||||
UniverseDomain string
|
||||
EnableDirectPath bool
|
||||
EnableDirectPathXds bool
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// getUniverseDomain returns the default service domain for a given Cloud
|
||||
@@ -92,16 +94,6 @@ func (o *Options) defaultEndpoint() string {
|
||||
return strings.Replace(o.DefaultEndpointTemplate, universeDomainPlaceholder, o.getUniverseDomain(), 1)
|
||||
}
|
||||
|
||||
// defaultMTLSEndpoint returns the DefaultMTLSEndpointTemplate merged with the
|
||||
// universe domain if the DefaultMTLSEndpointTemplate is set, otherwise returns an
|
||||
// empty string.
|
||||
func (o *Options) defaultMTLSEndpoint() string {
|
||||
if o.DefaultMTLSEndpoint == "" {
|
||||
return ""
|
||||
}
|
||||
return strings.Replace(o.DefaultMTLSEndpoint, universeDomainPlaceholder, o.getUniverseDomain(), 1)
|
||||
}
|
||||
|
||||
// mergedEndpoint merges a user-provided Endpoint of format host[:port] with the
|
||||
// default endpoint.
|
||||
func (o *Options) mergedEndpoint() (string, error) {
|
||||
@@ -141,11 +133,7 @@ func GetGRPCTransportCredsAndEndpoint(opts *Options) (credentials.TransportCrede
|
||||
transportCredsForS2A, err = loadMTLSMDSTransportCreds(mtlsMDSRoot, mtlsMDSKey)
|
||||
if err != nil {
|
||||
log.Printf("Loading MTLS MDS credentials failed: %v", err)
|
||||
if config.s2aAddress != "" {
|
||||
s2aAddr = config.s2aAddress
|
||||
} else {
|
||||
return defaultTransportCreds, config.endpoint, nil
|
||||
}
|
||||
return defaultTransportCreds, config.endpoint, nil
|
||||
}
|
||||
} else if config.s2aAddress != "" {
|
||||
s2aAddr = config.s2aAddress
|
||||
@@ -189,11 +177,7 @@ func GetHTTPTransportConfig(opts *Options) (cert.Provider, func(context.Context,
|
||||
transportCredsForS2A, err = loadMTLSMDSTransportCreds(mtlsMDSRoot, mtlsMDSKey)
|
||||
if err != nil {
|
||||
log.Printf("Loading MTLS MDS credentials failed: %v", err)
|
||||
if config.s2aAddress != "" {
|
||||
s2aAddr = config.s2aAddress
|
||||
} else {
|
||||
return config.clientCertSource, nil, nil
|
||||
}
|
||||
return config.clientCertSource, nil, nil
|
||||
}
|
||||
} else if config.s2aAddress != "" {
|
||||
s2aAddr = config.s2aAddress
|
||||
@@ -264,9 +248,12 @@ func getTransportConfig(opts *Options) (*transportConfig, error) {
|
||||
if !shouldUseS2A(clientCertSource, opts) {
|
||||
return &defaultTransportConfig, nil
|
||||
}
|
||||
if !opts.isUniverseDomainGDU() {
|
||||
return nil, errUniverseNotSupportedMTLS
|
||||
}
|
||||
|
||||
s2aAddress := GetS2AAddress(opts.Logger)
|
||||
mtlsS2AAddress := GetMTLSS2AAddress(opts.Logger)
|
||||
s2aAddress := GetS2AAddress()
|
||||
mtlsS2AAddress := GetMTLSS2AAddress()
|
||||
if s2aAddress == "" && mtlsS2AAddress == "" {
|
||||
return &defaultTransportConfig, nil
|
||||
}
|
||||
@@ -275,7 +262,7 @@ func getTransportConfig(opts *Options) (*transportConfig, error) {
|
||||
endpoint: endpoint,
|
||||
s2aAddress: s2aAddress,
|
||||
mtlsS2AAddress: mtlsS2AAddress,
|
||||
s2aMTLSEndpoint: opts.defaultMTLSEndpoint(),
|
||||
s2aMTLSEndpoint: opts.DefaultMTLSEndpoint,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -321,23 +308,24 @@ type transportConfig struct {
|
||||
// getEndpoint returns the endpoint for the service, taking into account the
|
||||
// user-provided endpoint override "settings.Endpoint".
|
||||
//
|
||||
// If no endpoint override is specified, we will either return the default
|
||||
// endpoint or the default mTLS endpoint if a client certificate is available.
|
||||
// If no endpoint override is specified, we will either return the default endpoint or
|
||||
// the default mTLS endpoint if a client certificate is available.
|
||||
//
|
||||
// You can override the default endpoint choice (mTLS vs. regular) by setting
|
||||
// the GOOGLE_API_USE_MTLS_ENDPOINT environment variable.
|
||||
// You can override the default endpoint choice (mtls vs. regular) by setting the
|
||||
// GOOGLE_API_USE_MTLS_ENDPOINT environment variable.
|
||||
//
|
||||
// If the endpoint override is an address (host:port) rather than full base
|
||||
// URL (ex. https://...), then the user-provided address will be merged into
|
||||
// the default endpoint. For example, WithEndpoint("myhost:8000") and
|
||||
// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return
|
||||
// "https://myhost:8080/bar/baz". Note that this does not apply to the mTLS
|
||||
// endpoint.
|
||||
// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return "https://myhost:8080/bar/baz"
|
||||
func getEndpoint(opts *Options, clientCertSource cert.Provider) (string, error) {
|
||||
if opts.Endpoint == "" {
|
||||
mtlsMode := getMTLSMode()
|
||||
if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) {
|
||||
return opts.defaultMTLSEndpoint(), nil
|
||||
if !opts.isUniverseDomainGDU() {
|
||||
return "", errUniverseNotSupportedMTLS
|
||||
}
|
||||
return opts.DefaultMTLSEndpoint, nil
|
||||
}
|
||||
return opts.defaultEndpoint(), nil
|
||||
}
|
||||
|
||||
8
vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go
generated
vendored
8
vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go
generated
vendored
@@ -16,6 +16,7 @@ package cert
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
|
||||
"github.com/googleapis/enterprise-certificate-proxy/client"
|
||||
)
|
||||
@@ -36,9 +37,10 @@ type ecpSource struct {
|
||||
func NewEnterpriseCertificateProxyProvider(configFilePath string) (Provider, error) {
|
||||
key, err := client.Cred(configFilePath)
|
||||
if err != nil {
|
||||
// TODO(codyoss): once this is fixed upstream can handle this error a
|
||||
// little better here. But be safe for now and assume unavailable.
|
||||
return nil, errSourceUnavailable
|
||||
if errors.Is(err, client.ErrCredUnavailable) {
|
||||
return nil, errSourceUnavailable
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return (&ecpSource{
|
||||
|
||||
10
vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go
generated
vendored
10
vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go
generated
vendored
@@ -62,11 +62,11 @@ func NewSecureConnectProvider(configFilePath string) (Provider, error) {
|
||||
|
||||
file, err := os.ReadFile(configFilePath)
|
||||
if err != nil {
|
||||
// Config file missing means Secure Connect is not supported.
|
||||
// There are non-os.ErrNotExist errors that may be returned.
|
||||
// (e.g. if the home directory is /dev/null, *nix systems will
|
||||
// return ENOTDIR instead of ENOENT)
|
||||
return nil, errSourceUnavailable
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
// Config file missing means Secure Connect is not supported.
|
||||
return nil, errSourceUnavailable
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var metadata secureConnectMetadata
|
||||
|
||||
5
vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go
generated
vendored
5
vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go
generated
vendored
@@ -82,7 +82,10 @@ func (s *workloadSource) getClientCertificate(info *tls.CertificateRequestInfo)
|
||||
func getCertAndKeyFiles(configFilePath string) (string, string, error) {
|
||||
jsonFile, err := os.Open(configFilePath)
|
||||
if err != nil {
|
||||
return "", "", errSourceUnavailable
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return "", "", errSourceUnavailable
|
||||
}
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
byteValue, err := io.ReadAll(jsonFile)
|
||||
|
||||
25
vendor/cloud.google.com/go/auth/internal/transport/s2a.go
generated
vendored
25
vendor/cloud.google.com/go/auth/internal/transport/s2a.go
generated
vendored
@@ -15,11 +15,9 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -40,8 +38,8 @@ var (
|
||||
|
||||
// GetS2AAddress returns the S2A address to be reached via plaintext connection.
|
||||
// Returns empty string if not set or invalid.
|
||||
func GetS2AAddress(logger *slog.Logger) string {
|
||||
getMetadataMTLSAutoConfig(logger)
|
||||
func GetS2AAddress() string {
|
||||
getMetadataMTLSAutoConfig()
|
||||
if !mtlsConfiguration.valid() {
|
||||
return ""
|
||||
}
|
||||
@@ -50,8 +48,8 @@ func GetS2AAddress(logger *slog.Logger) string {
|
||||
|
||||
// GetMTLSS2AAddress returns the S2A address to be reached via MTLS connection.
|
||||
// Returns empty string if not set or invalid.
|
||||
func GetMTLSS2AAddress(logger *slog.Logger) string {
|
||||
getMetadataMTLSAutoConfig(logger)
|
||||
func GetMTLSS2AAddress() string {
|
||||
getMetadataMTLSAutoConfig()
|
||||
if !mtlsConfiguration.valid() {
|
||||
return ""
|
||||
}
|
||||
@@ -75,25 +73,22 @@ type s2aAddresses struct {
|
||||
MTLSAddress string `json:"mtls_address"`
|
||||
}
|
||||
|
||||
func getMetadataMTLSAutoConfig(logger *slog.Logger) {
|
||||
func getMetadataMTLSAutoConfig() {
|
||||
var err error
|
||||
mtlsOnce.Do(func() {
|
||||
mtlsConfiguration, err = queryConfig(logger)
|
||||
mtlsConfiguration, err = queryConfig()
|
||||
if err != nil {
|
||||
log.Printf("Getting MTLS config failed: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var httpGetMetadataMTLSConfig = func(logger *slog.Logger) (string, error) {
|
||||
metadataClient := metadata.NewWithOptions(&metadata.Options{
|
||||
Logger: logger,
|
||||
})
|
||||
return metadataClient.GetWithContext(context.Background(), configEndpointSuffix)
|
||||
var httpGetMetadataMTLSConfig = func() (string, error) {
|
||||
return metadata.Get(configEndpointSuffix)
|
||||
}
|
||||
|
||||
func queryConfig(logger *slog.Logger) (*mtlsConfig, error) {
|
||||
resp, err := httpGetMetadataMTLSConfig(logger)
|
||||
func queryConfig() (*mtlsConfig, error) {
|
||||
resp, err := httpGetMetadataMTLSConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("querying MTLS config from MDS endpoint failed: %w", err)
|
||||
}
|
||||
|
||||
7
vendor/cloud.google.com/go/auth/internal/transport/transport.go
generated
vendored
7
vendor/cloud.google.com/go/auth/internal/transport/transport.go
generated
vendored
@@ -49,7 +49,6 @@ func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOpt
|
||||
// These fields are are pointer types that we just want to use exactly
|
||||
// as the user set, copy the ref
|
||||
Client: oldDo.Client,
|
||||
Logger: oldDo.Logger,
|
||||
AuthHandlerOptions: oldDo.AuthHandlerOptions,
|
||||
}
|
||||
|
||||
@@ -82,14 +81,12 @@ func ValidateUniverseDomain(clientUniverseDomain, credentialsUniverseDomain stri
|
||||
|
||||
// DefaultHTTPClientWithTLS constructs an HTTPClient using the provided tlsConfig, to support mTLS.
|
||||
func DefaultHTTPClientWithTLS(tlsConfig *tls.Config) *http.Client {
|
||||
trans := BaseTransport()
|
||||
trans := baseTransport()
|
||||
trans.TLSClientConfig = tlsConfig
|
||||
return &http.Client{Transport: trans}
|
||||
}
|
||||
|
||||
// BaseTransport returns a default [http.Transport] which can be used if
|
||||
// [http.DefaultTransport] has been overwritten.
|
||||
func BaseTransport() *http.Transport {
|
||||
func baseTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
|
||||
21
vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md
generated
vendored
21
vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md
generated
vendored
@@ -1,26 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [0.2.7](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.6...auth/oauth2adapt/v0.2.7) (2025-01-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth/oauth2adapt:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9))
|
||||
|
||||
## [0.2.6](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.5...auth/oauth2adapt/v0.2.6) (2024-11-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth/oauth2adapt:** Copy map in tokenSourceAdapter.Token ([#11164](https://github.com/googleapis/google-cloud-go/issues/11164)) ([8cb0cbc](https://github.com/googleapis/google-cloud-go/commit/8cb0cbccdc32886dfb3af49fee04012937d114d2)), refs [#11161](https://github.com/googleapis/google-cloud-go/issues/11161)
|
||||
|
||||
## [0.2.5](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.4...auth/oauth2adapt/v0.2.5) (2024-10-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth/oauth2adapt:** Convert token metadata where possible ([#11062](https://github.com/googleapis/google-cloud-go/issues/11062)) ([34bf1c1](https://github.com/googleapis/google-cloud-go/commit/34bf1c164465d66745c0cfdf7cd10a8e2da92e52))
|
||||
|
||||
## [0.2.4](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.3...auth/oauth2adapt/v0.2.4) (2024-08-08)
|
||||
|
||||
|
||||
|
||||
46
vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go
generated
vendored
46
vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go
generated
vendored
@@ -26,13 +26,6 @@ import (
|
||||
"golang.org/x/oauth2/google"
|
||||
)
|
||||
|
||||
const (
|
||||
oauth2TokenSourceKey = "oauth2.google.tokenSource"
|
||||
oauth2ServiceAccountKey = "oauth2.google.serviceAccount"
|
||||
authTokenSourceKey = "auth.google.tokenSource"
|
||||
authServiceAccountKey = "auth.google.serviceAccount"
|
||||
)
|
||||
|
||||
// TokenProviderFromTokenSource converts any [golang.org/x/oauth2.TokenSource]
|
||||
// into a [cloud.google.com/go/auth.TokenProvider].
|
||||
func TokenProviderFromTokenSource(ts oauth2.TokenSource) auth.TokenProvider {
|
||||
@@ -54,21 +47,10 @@ func (tp *tokenProviderAdapter) Token(context.Context) (*auth.Token, error) {
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
// Preserve compute token metadata, for both types of tokens.
|
||||
metadata := map[string]interface{}{}
|
||||
if val, ok := tok.Extra(oauth2TokenSourceKey).(string); ok {
|
||||
metadata[authTokenSourceKey] = val
|
||||
metadata[oauth2TokenSourceKey] = val
|
||||
}
|
||||
if val, ok := tok.Extra(oauth2ServiceAccountKey).(string); ok {
|
||||
metadata[authServiceAccountKey] = val
|
||||
metadata[oauth2ServiceAccountKey] = val
|
||||
}
|
||||
return &auth.Token{
|
||||
Value: tok.AccessToken,
|
||||
Type: tok.Type(),
|
||||
Expiry: tok.Expiry,
|
||||
Metadata: metadata,
|
||||
Value: tok.AccessToken,
|
||||
Type: tok.Type(),
|
||||
Expiry: tok.Expiry,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -94,29 +76,11 @@ func (ts *tokenSourceAdapter) Token() (*oauth2.Token, error) {
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
tok2 := &oauth2.Token{
|
||||
return &oauth2.Token{
|
||||
AccessToken: tok.Value,
|
||||
TokenType: tok.Type,
|
||||
Expiry: tok.Expiry,
|
||||
}
|
||||
// Preserve token metadata.
|
||||
m := tok.Metadata
|
||||
if m != nil {
|
||||
// Copy map to avoid concurrent map writes error (#11161).
|
||||
metadata := make(map[string]interface{}, len(m)+2)
|
||||
for k, v := range m {
|
||||
metadata[k] = v
|
||||
}
|
||||
// Append compute token metadata in converted form.
|
||||
if val, ok := metadata[authTokenSourceKey].(string); ok && val != "" {
|
||||
metadata[oauth2TokenSourceKey] = val
|
||||
}
|
||||
if val, ok := metadata[authServiceAccountKey].(string); ok && val != "" {
|
||||
metadata[oauth2ServiceAccountKey] = val
|
||||
}
|
||||
tok2 = tok2.WithExtra(metadata)
|
||||
}
|
||||
return tok2, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AuthCredentialsFromOauth2Credentials converts a [golang.org/x/oauth2/google.Credentials]
|
||||
|
||||
14
vendor/cloud.google.com/go/auth/threelegged.go
generated
vendored
14
vendor/cloud.google.com/go/auth/threelegged.go
generated
vendored
@@ -20,7 +20,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
// AuthorizationHandler is a 3-legged-OAuth helper that prompts the user for
|
||||
@@ -71,11 +69,6 @@ type Options3LO struct {
|
||||
// AuthHandlerOpts provides a set of options for doing a
|
||||
// 3-legged OAuth2 flow with a custom [AuthorizationHandler]. Optional.
|
||||
AuthHandlerOpts *AuthorizationHandlerOptions
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func (o *Options3LO) validate() error {
|
||||
@@ -103,10 +96,6 @@ func (o *Options3LO) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options3LO) logger() *slog.Logger {
|
||||
return internallog.New(o.Logger)
|
||||
}
|
||||
|
||||
// PKCEOptions holds parameters to support PKCE.
|
||||
type PKCEOptions struct {
|
||||
// Challenge is the un-padded, base64-url-encoded string of the encrypted code verifier.
|
||||
@@ -304,15 +293,12 @@ func fetchToken(ctx context.Context, o *Options3LO, v url.Values) (*Token, strin
|
||||
if o.AuthStyle == StyleInHeader {
|
||||
req.SetBasicAuth(url.QueryEscape(o.ClientID), url.QueryEscape(o.ClientSecret))
|
||||
}
|
||||
logger := o.logger()
|
||||
|
||||
logger.DebugContext(ctx, "3LO token request", "request", internallog.HTTPRequest(req, []byte(v.Encode())))
|
||||
// Make request
|
||||
resp, body, err := internal.DoRequest(o.client(), req)
|
||||
if err != nil {
|
||||
return nil, refreshToken, err
|
||||
}
|
||||
logger.DebugContext(ctx, "3LO token response", "response", internallog.HTTPResponse(resp, body))
|
||||
failureStatus := resp.StatusCode < 200 || resp.StatusCode > 299
|
||||
tokError := &Error{
|
||||
Response: resp,
|
||||
|
||||
29
vendor/cloud.google.com/go/iam/CHANGES.md
generated
vendored
29
vendor/cloud.google.com/go/iam/CHANGES.md
generated
vendored
@@ -1,35 +1,6 @@
|
||||
# Changes
|
||||
|
||||
|
||||
## [1.3.1](https://github.com/googleapis/google-cloud-go/compare/iam/v1.3.0...iam/v1.3.1) (2025-01-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **iam:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9))
|
||||
|
||||
## [1.3.0](https://github.com/googleapis/google-cloud-go/compare/iam/v1.2.2...iam/v1.3.0) (2024-12-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **iam:** Add ResourcePolicyMember to google/iam/v1 ([8dedb87](https://github.com/googleapis/google-cloud-go/commit/8dedb878c070cc1e92d62bb9b32358425e3ceffb))
|
||||
|
||||
## [1.2.2](https://github.com/googleapis/google-cloud-go/compare/iam/v1.2.1...iam/v1.2.2) (2024-10-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **iam:** Update google.golang.org/api to v0.203.0 ([8bb87d5](https://github.com/googleapis/google-cloud-go/commit/8bb87d56af1cba736e0fe243979723e747e5e11e))
|
||||
* **iam:** WARNING: On approximately Dec 1, 2024, an update to Protobuf will change service registration function signatures to use an interface instead of a concrete type in generated .pb.go files. This change is expected to affect very few if any users of this client library. For more information, see https://togithub.com/googleapis/google-cloud-go/issues/11020. ([8bb87d5](https://github.com/googleapis/google-cloud-go/commit/8bb87d56af1cba736e0fe243979723e747e5e11e))
|
||||
|
||||
## [1.2.1](https://github.com/googleapis/google-cloud-go/compare/iam/v1.2.0...iam/v1.2.1) (2024-09-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **iam:** Bump dependencies ([2ddeb15](https://github.com/googleapis/google-cloud-go/commit/2ddeb1544a53188a7592046b98913982f1b0cf04))
|
||||
|
||||
## [1.2.0](https://github.com/googleapis/google-cloud-go/compare/iam/v1.1.13...iam/v1.2.0) (2024-08-20)
|
||||
|
||||
|
||||
|
||||
103
vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go
generated
vendored
103
vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go
generated
vendored
@@ -14,7 +14,7 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.34.2
|
||||
// protoc v4.25.3
|
||||
// source: google/iam/v1/iam_policy.proto
|
||||
|
||||
@@ -65,9 +65,11 @@ type SetIamPolicyRequest struct {
|
||||
|
||||
func (x *SetIamPolicyRequest) Reset() {
|
||||
*x = SetIamPolicyRequest{}
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetIamPolicyRequest) String() string {
|
||||
@@ -78,7 +80,7 @@ func (*SetIamPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetIamPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -130,9 +132,11 @@ type GetIamPolicyRequest struct {
|
||||
|
||||
func (x *GetIamPolicyRequest) Reset() {
|
||||
*x = GetIamPolicyRequest{}
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetIamPolicyRequest) String() string {
|
||||
@@ -143,7 +147,7 @@ func (*GetIamPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetIamPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -190,9 +194,11 @@ type TestIamPermissionsRequest struct {
|
||||
|
||||
func (x *TestIamPermissionsRequest) Reset() {
|
||||
*x = TestIamPermissionsRequest{}
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TestIamPermissionsRequest) String() string {
|
||||
@@ -203,7 +209,7 @@ func (*TestIamPermissionsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *TestIamPermissionsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -245,9 +251,11 @@ type TestIamPermissionsResponse struct {
|
||||
|
||||
func (x *TestIamPermissionsResponse) Reset() {
|
||||
*x = TestIamPermissionsResponse{}
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TestIamPermissionsResponse) String() string {
|
||||
@@ -258,7 +266,7 @@ func (*TestIamPermissionsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *TestIamPermissionsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_iam_policy_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -355,15 +363,16 @@ var file_google_iam_v1_iam_policy_proto_rawDesc = []byte{
|
||||
0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72,
|
||||
0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1e, 0xca, 0x41, 0x1b, 0x69, 0x61, 0x6d,
|
||||
0x2d, 0x6d, 0x65, 0x74, 0x61, 0x2d, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x42, 0x7c, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x42, 0x7f, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x49,
|
||||
0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69,
|
||||
0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70, 0x62, 0xaa, 0x02, 0x13, 0x47, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d, 0x2e, 0x56, 0x31,
|
||||
0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c,
|
||||
0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xaa, 0x02, 0x13,
|
||||
0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d,
|
||||
0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f,
|
||||
0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -412,6 +421,56 @@ func file_google_iam_v1_iam_policy_proto_init() {
|
||||
}
|
||||
file_google_iam_v1_options_proto_init()
|
||||
file_google_iam_v1_policy_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_google_iam_v1_iam_policy_proto_msgTypes[0].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*SetIamPolicyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_iam_policy_proto_msgTypes[1].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*GetIamPolicyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_iam_policy_proto_msgTypes[2].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*TestIamPermissionsRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_iam_policy_proto_msgTypes[3].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*TestIamPermissionsResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
||||
26
vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go
generated
vendored
26
vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go
generated
vendored
@@ -14,7 +14,7 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.34.2
|
||||
// protoc v4.25.3
|
||||
// source: google/iam/v1/options.proto
|
||||
|
||||
@@ -64,9 +64,11 @@ type GetPolicyOptions struct {
|
||||
|
||||
func (x *GetPolicyOptions) Reset() {
|
||||
*x = GetPolicyOptions{}
|
||||
mi := &file_google_iam_v1_options_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_options_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetPolicyOptions) String() string {
|
||||
@@ -77,7 +79,7 @@ func (*GetPolicyOptions) ProtoMessage() {}
|
||||
|
||||
func (x *GetPolicyOptions) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_options_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -150,6 +152,20 @@ func file_google_iam_v1_options_proto_init() {
|
||||
if File_google_iam_v1_options_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_google_iam_v1_options_proto_msgTypes[0].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*GetPolicyOptions); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
||||
158
vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go
generated
vendored
158
vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go
generated
vendored
@@ -14,7 +14,7 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.34.2
|
||||
// protoc v4.25.3
|
||||
// source: google/iam/v1/policy.proto
|
||||
|
||||
@@ -337,9 +337,11 @@ type Policy struct {
|
||||
|
||||
func (x *Policy) Reset() {
|
||||
*x = Policy{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Policy) String() string {
|
||||
@@ -350,7 +352,7 @@ func (*Policy) ProtoMessage() {}
|
||||
|
||||
func (x *Policy) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -460,9 +462,11 @@ type Binding struct {
|
||||
|
||||
func (x *Binding) Reset() {
|
||||
*x = Binding{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Binding) String() string {
|
||||
@@ -473,7 +477,7 @@ func (*Binding) ProtoMessage() {}
|
||||
|
||||
func (x *Binding) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -575,9 +579,11 @@ type AuditConfig struct {
|
||||
|
||||
func (x *AuditConfig) Reset() {
|
||||
*x = AuditConfig{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuditConfig) String() string {
|
||||
@@ -588,7 +594,7 @@ func (*AuditConfig) ProtoMessage() {}
|
||||
|
||||
func (x *AuditConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -652,9 +658,11 @@ type AuditLogConfig struct {
|
||||
|
||||
func (x *AuditLogConfig) Reset() {
|
||||
*x = AuditLogConfig{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuditLogConfig) String() string {
|
||||
@@ -665,7 +673,7 @@ func (*AuditLogConfig) ProtoMessage() {}
|
||||
|
||||
func (x *AuditLogConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -708,9 +716,11 @@ type PolicyDelta struct {
|
||||
|
||||
func (x *PolicyDelta) Reset() {
|
||||
*x = PolicyDelta{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PolicyDelta) String() string {
|
||||
@@ -721,7 +731,7 @@ func (*PolicyDelta) ProtoMessage() {}
|
||||
|
||||
func (x *PolicyDelta) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -774,9 +784,11 @@ type BindingDelta struct {
|
||||
|
||||
func (x *BindingDelta) Reset() {
|
||||
*x = BindingDelta{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BindingDelta) String() string {
|
||||
@@ -787,7 +799,7 @@ func (*BindingDelta) ProtoMessage() {}
|
||||
|
||||
func (x *BindingDelta) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -857,9 +869,11 @@ type AuditConfigDelta struct {
|
||||
|
||||
func (x *AuditConfigDelta) Reset() {
|
||||
*x = AuditConfigDelta{}
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuditConfigDelta) String() string {
|
||||
@@ -870,7 +884,7 @@ func (*AuditConfigDelta) ProtoMessage() {}
|
||||
|
||||
func (x *AuditConfigDelta) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_policy_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -1058,6 +1072,92 @@ func file_google_iam_v1_policy_proto_init() {
|
||||
if File_google_iam_v1_policy_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_google_iam_v1_policy_proto_msgTypes[0].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Policy); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_policy_proto_msgTypes[1].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Binding); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_policy_proto_msgTypes[2].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuditConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_policy_proto_msgTypes[3].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuditLogConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_policy_proto_msgTypes[4].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PolicyDelta); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_policy_proto_msgTypes[5].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*BindingDelta); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_google_iam_v1_policy_proto_msgTypes[6].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuditConfigDelta); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
||||
185
vendor/cloud.google.com/go/iam/apiv1/iampb/resource_policy_member.pb.go
generated
vendored
185
vendor/cloud.google.com/go/iam/apiv1/iampb/resource_policy_member.pb.go
generated
vendored
@@ -1,185 +0,0 @@
|
||||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc v4.25.3
|
||||
// source: google/iam/v1/resource_policy_member.proto
|
||||
|
||||
package iampb
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Output-only policy member strings of a Google Cloud resource's built-in
|
||||
// identity.
|
||||
type ResourcePolicyMember struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// IAM policy binding member referring to a Google Cloud resource by
|
||||
// user-assigned name (https://google.aip.dev/122). If a resource is deleted
|
||||
// and recreated with the same name, the binding will be applicable to the new
|
||||
// resource.
|
||||
//
|
||||
// Example:
|
||||
// `principal://parametermanager.googleapis.com/projects/12345/name/locations/us-central1-a/parameters/my-parameter`
|
||||
IamPolicyNamePrincipal string `protobuf:"bytes,1,opt,name=iam_policy_name_principal,json=iamPolicyNamePrincipal,proto3" json:"iam_policy_name_principal,omitempty"`
|
||||
// IAM policy binding member referring to a Google Cloud resource by
|
||||
// system-assigned unique identifier (https://google.aip.dev/148#uid). If a
|
||||
// resource is deleted and recreated with the same name, the binding will not
|
||||
// be applicable to the new resource
|
||||
//
|
||||
// Example:
|
||||
// `principal://parametermanager.googleapis.com/projects/12345/uid/locations/us-central1-a/parameters/a918fed5`
|
||||
IamPolicyUidPrincipal string `protobuf:"bytes,2,opt,name=iam_policy_uid_principal,json=iamPolicyUidPrincipal,proto3" json:"iam_policy_uid_principal,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ResourcePolicyMember) Reset() {
|
||||
*x = ResourcePolicyMember{}
|
||||
mi := &file_google_iam_v1_resource_policy_member_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ResourcePolicyMember) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ResourcePolicyMember) ProtoMessage() {}
|
||||
|
||||
func (x *ResourcePolicyMember) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_iam_v1_resource_policy_member_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResourcePolicyMember.ProtoReflect.Descriptor instead.
|
||||
func (*ResourcePolicyMember) Descriptor() ([]byte, []int) {
|
||||
return file_google_iam_v1_resource_policy_member_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ResourcePolicyMember) GetIamPolicyNamePrincipal() string {
|
||||
if x != nil {
|
||||
return x.IamPolicyNamePrincipal
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResourcePolicyMember) GetIamPolicyUidPrincipal() string {
|
||||
if x != nil {
|
||||
return x.IamPolicyUidPrincipal
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_google_iam_v1_resource_policy_member_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_google_iam_v1_resource_policy_member_proto_rawDesc = []byte{
|
||||
0x0a, 0x2a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f,
|
||||
0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65,
|
||||
0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x01, 0x0a,
|
||||
0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d,
|
||||
0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x19, 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x16, 0x69,
|
||||
0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x69, 0x6e,
|
||||
0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x18, 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x5f, 0x75, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x15, 0x69, 0x61,
|
||||
0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x42, 0x87, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x19, 0x52, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69, 0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70,
|
||||
0x62, 0xaa, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2e, 0x49, 0x61, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescOnce sync.Once
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescData = file_google_iam_v1_resource_policy_member_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_google_iam_v1_resource_policy_member_proto_rawDescGZIP() []byte {
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescOnce.Do(func() {
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_resource_policy_member_proto_rawDescData)
|
||||
})
|
||||
return file_google_iam_v1_resource_policy_member_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_google_iam_v1_resource_policy_member_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_google_iam_v1_resource_policy_member_proto_goTypes = []any{
|
||||
(*ResourcePolicyMember)(nil), // 0: google.iam.v1.ResourcePolicyMember
|
||||
}
|
||||
var file_google_iam_v1_resource_policy_member_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_google_iam_v1_resource_policy_member_proto_init() }
|
||||
func file_google_iam_v1_resource_policy_member_proto_init() {
|
||||
if File_google_iam_v1_resource_policy_member_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_google_iam_v1_resource_policy_member_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_google_iam_v1_resource_policy_member_proto_goTypes,
|
||||
DependencyIndexes: file_google_iam_v1_resource_policy_member_proto_depIdxs,
|
||||
MessageInfos: file_google_iam_v1_resource_policy_member_proto_msgTypes,
|
||||
}.Build()
|
||||
File_google_iam_v1_resource_policy_member_proto = out.File
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDesc = nil
|
||||
file_google_iam_v1_resource_policy_member_proto_goTypes = nil
|
||||
file_google_iam_v1_resource_policy_member_proto_depIdxs = nil
|
||||
}
|
||||
108
vendor/cloud.google.com/go/internal/.repo-metadata-full.json
generated
vendored
108
vendor/cloud.google.com/go/internal/.repo-metadata-full.json
generated
vendored
@@ -179,16 +179,6 @@
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/apihub/apiv1": {
|
||||
"api_shortname": "apihub",
|
||||
"distribution_name": "cloud.google.com/go/apihub/apiv1",
|
||||
"description": "API hub API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/apihub/latest/apiv1",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/apikeys/apiv2": {
|
||||
"api_shortname": "apikeys",
|
||||
"distribution_name": "cloud.google.com/go/apikeys/apiv2",
|
||||
@@ -569,16 +559,6 @@
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/bigquery/storage/apiv1alpha": {
|
||||
"api_shortname": "bigquerystorage",
|
||||
"distribution_name": "cloud.google.com/go/bigquery/storage/apiv1alpha",
|
||||
"description": "BigQuery Storage API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/bigquery/latest/storage/apiv1alpha",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/bigquery/storage/apiv1beta1": {
|
||||
"api_shortname": "bigquerystorage",
|
||||
"distribution_name": "cloud.google.com/go/bigquery/storage/apiv1beta1",
|
||||
@@ -1029,16 +1009,6 @@
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/datastore/apiv1": {
|
||||
"api_shortname": "datastore",
|
||||
"distribution_name": "cloud.google.com/go/datastore/apiv1",
|
||||
"description": "Cloud Datastore API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/datastore/latest/apiv1",
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/datastream/apiv1": {
|
||||
"api_shortname": "datastream",
|
||||
"distribution_name": "cloud.google.com/go/datastream/apiv1",
|
||||
@@ -1359,16 +1329,6 @@
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/gkeconnect/gateway/apiv1": {
|
||||
"api_shortname": "connectgateway",
|
||||
"distribution_name": "cloud.google.com/go/gkeconnect/gateway/apiv1",
|
||||
"description": "Connect Gateway API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/gkeconnect/latest/gateway/apiv1",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/gkeconnect/gateway/apiv1beta1": {
|
||||
"api_shortname": "connectgateway",
|
||||
"distribution_name": "cloud.google.com/go/gkeconnect/gateway/apiv1beta1",
|
||||
@@ -1392,7 +1352,7 @@
|
||||
"cloud.google.com/go/gkemulticloud/apiv1": {
|
||||
"api_shortname": "gkemulticloud",
|
||||
"distribution_name": "cloud.google.com/go/gkemulticloud/apiv1",
|
||||
"description": "GKE Multi-Cloud API",
|
||||
"description": "Anthos Multi-Cloud API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/gkemulticloud/latest/apiv1",
|
||||
@@ -1592,7 +1552,7 @@
|
||||
"cloud.google.com/go/managedkafka/apiv1": {
|
||||
"api_shortname": "managedkafka",
|
||||
"distribution_name": "cloud.google.com/go/managedkafka/apiv1",
|
||||
"description": "Managed Service for Apache Kafka API",
|
||||
"description": "Apache Kafka for BigQuery API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/managedkafka/latest/apiv1",
|
||||
@@ -1609,16 +1569,6 @@
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/maps/areainsights/apiv1": {
|
||||
"api_shortname": "areainsights",
|
||||
"distribution_name": "cloud.google.com/go/maps/areainsights/apiv1",
|
||||
"description": "Places Insights API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/maps/latest/areainsights/apiv1",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/maps/fleetengine/apiv1": {
|
||||
"api_shortname": "fleetengine",
|
||||
"distribution_name": "cloud.google.com/go/maps/fleetengine/apiv1",
|
||||
@@ -1709,26 +1659,6 @@
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/memorystore/apiv1": {
|
||||
"api_shortname": "memorystore",
|
||||
"distribution_name": "cloud.google.com/go/memorystore/apiv1",
|
||||
"description": "Memorystore API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/memorystore/latest/apiv1",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/memorystore/apiv1beta": {
|
||||
"api_shortname": "memorystore",
|
||||
"distribution_name": "cloud.google.com/go/memorystore/apiv1beta",
|
||||
"description": "Memorystore API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/memorystore/latest/apiv1beta",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/metastore/apiv1": {
|
||||
"api_shortname": "metastore",
|
||||
"distribution_name": "cloud.google.com/go/metastore/apiv1",
|
||||
@@ -1776,7 +1706,7 @@
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/monitoring/latest/apiv3/v2",
|
||||
"release_level": "preview",
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/monitoring/dashboard/apiv1": {
|
||||
@@ -1899,16 +1829,6 @@
|
||||
"release_level": "stable",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/oracledatabase/apiv1": {
|
||||
"api_shortname": "oracledatabase",
|
||||
"distribution_name": "cloud.google.com/go/oracledatabase/apiv1",
|
||||
"description": "Oracle Database@Google Cloud API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/oracledatabase/latest/apiv1",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/orchestration/airflow/service/apiv1": {
|
||||
"api_shortname": "composer",
|
||||
"distribution_name": "cloud.google.com/go/orchestration/airflow/service/apiv1",
|
||||
@@ -1999,16 +1919,6 @@
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/parallelstore/apiv1": {
|
||||
"api_shortname": "parallelstore",
|
||||
"distribution_name": "cloud.google.com/go/parallelstore/apiv1",
|
||||
"description": "Parallelstore API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/parallelstore/latest/apiv1",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/parallelstore/apiv1beta": {
|
||||
"api_shortname": "parallelstore",
|
||||
"distribution_name": "cloud.google.com/go/parallelstore/apiv1beta",
|
||||
@@ -2432,7 +2342,7 @@
|
||||
"cloud.google.com/go/securitycentermanagement/apiv1": {
|
||||
"api_shortname": "securitycentermanagement",
|
||||
"distribution_name": "cloud.google.com/go/securitycentermanagement/apiv1",
|
||||
"description": "Security Command Center Management API",
|
||||
"description": "Security Center Management API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/securitycentermanagement/latest/apiv1",
|
||||
@@ -2629,16 +2539,6 @@
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/shopping/merchant/reviews/apiv1beta": {
|
||||
"api_shortname": "merchantapi",
|
||||
"distribution_name": "cloud.google.com/go/shopping/merchant/reviews/apiv1beta",
|
||||
"description": "Merchant API",
|
||||
"language": "go",
|
||||
"client_library_type": "generated",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/shopping/latest/merchant/reviews/apiv1beta",
|
||||
"release_level": "preview",
|
||||
"library_type": "GAPIC_AUTO"
|
||||
},
|
||||
"cloud.google.com/go/spanner": {
|
||||
"api_shortname": "spanner",
|
||||
"distribution_name": "cloud.google.com/go/spanner",
|
||||
|
||||
208
vendor/cloud.google.com/go/internal/trace/trace.go
generated
vendored
208
vendor/cloud.google.com/go/internal/trace/trace.go
generated
vendored
@@ -18,39 +18,143 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
ottrace "go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/genproto/googleapis/rpc/code"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
// Deprecated: The default experimental tracing support for OpenCensus is
|
||||
// now deprecated in the Google Cloud client libraries for Go.
|
||||
// TelemetryPlatformTracingOpenCensus is the value to which the environment
|
||||
// variable GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING should be
|
||||
// set to enable OpenCensus tracing.
|
||||
TelemetryPlatformTracingOpenCensus = "opencensus"
|
||||
// TelemetryPlatformTracingOpenTelemetry is the value to which the environment
|
||||
// variable GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING should be
|
||||
// set to enable OpenTelemetry tracing.
|
||||
TelemetryPlatformTracingOpenTelemetry = "opentelemetry"
|
||||
// TelemetryPlatformTracingVar is the name of the environment
|
||||
// variable that can be set to change the default tracing from OpenTelemetry
|
||||
// to OpenCensus.
|
||||
//
|
||||
// The default experimental tracing support for OpenCensus is now deprecated
|
||||
// in the Google Cloud client libraries for Go.
|
||||
TelemetryPlatformTracingVar = "GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING"
|
||||
// OpenTelemetryTracerName is the name given to the OpenTelemetry Tracer
|
||||
// when it is obtained from the OpenTelemetry TracerProvider.
|
||||
OpenTelemetryTracerName = "cloud.google.com/go"
|
||||
)
|
||||
|
||||
// StartSpan adds an OpenTelemetry span to the trace with the given name.
|
||||
var (
|
||||
// openCensusTracingEnabledMu guards access to openCensusTracingEnabled field
|
||||
openCensusTracingEnabledMu = sync.RWMutex{}
|
||||
// openCensusTracingEnabled is true if the environment variable
|
||||
// GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING is set to the
|
||||
// case-insensitive value "opencensus".
|
||||
openCensusTracingEnabled bool = strings.EqualFold(strings.TrimSpace(
|
||||
os.Getenv(TelemetryPlatformTracingVar)), TelemetryPlatformTracingOpenCensus)
|
||||
)
|
||||
|
||||
// SetOpenTelemetryTracingEnabledField programmatically sets the value provided
|
||||
// by GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING for the purpose of
|
||||
// unit testing. Do not invoke it directly. Intended for use only in unit tests.
|
||||
// Restore original value after each test.
|
||||
//
|
||||
// The default experimental tracing support for OpenCensus is now deprecated in
|
||||
// the Google Cloud client libraries for Go.
|
||||
func SetOpenTelemetryTracingEnabledField(enabled bool) {
|
||||
openCensusTracingEnabledMu.Lock()
|
||||
defer openCensusTracingEnabledMu.Unlock()
|
||||
openCensusTracingEnabled = !enabled
|
||||
}
|
||||
|
||||
// Deprecated: The default experimental tracing support for OpenCensus is now
|
||||
// deprecated in the Google Cloud client libraries for Go.
|
||||
//
|
||||
// IsOpenCensusTracingEnabled returns true if the environment variable
|
||||
// GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING is set to the
|
||||
// case-insensitive value "opencensus".
|
||||
func IsOpenCensusTracingEnabled() bool {
|
||||
openCensusTracingEnabledMu.RLock()
|
||||
defer openCensusTracingEnabledMu.RUnlock()
|
||||
return openCensusTracingEnabled
|
||||
}
|
||||
|
||||
// IsOpenTelemetryTracingEnabled returns true if the environment variable
|
||||
// GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING is NOT set to the
|
||||
// case-insensitive value "opencensus".
|
||||
func IsOpenTelemetryTracingEnabled() bool {
|
||||
return !IsOpenCensusTracingEnabled()
|
||||
}
|
||||
|
||||
// StartSpan adds a span to the trace with the given name. If IsOpenCensusTracingEnabled
|
||||
// returns true, the span will be an OpenCensus span. If IsOpenTelemetryTracingEnabled
|
||||
// returns true, the span will be an OpenTelemetry span. Set the environment variable
|
||||
// GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING to the case-insensitive
|
||||
// value "opencensus" before loading the package to use OpenCensus tracing.
|
||||
// The default was OpenCensus until May 29, 2024, at which time the default was
|
||||
// changed to "opencensus". Explicitly setting the environment variable to
|
||||
// "opencensus" is required to continue using OpenCensus tracing.
|
||||
//
|
||||
// The default experimental tracing support for OpenCensus is now deprecated in
|
||||
// the Google Cloud client libraries for Go.
|
||||
func StartSpan(ctx context.Context, name string) context.Context {
|
||||
ctx, _ = otel.GetTracerProvider().Tracer(OpenTelemetryTracerName).Start(ctx, name)
|
||||
if IsOpenTelemetryTracingEnabled() {
|
||||
ctx, _ = otel.GetTracerProvider().Tracer(OpenTelemetryTracerName).Start(ctx, name)
|
||||
} else {
|
||||
ctx, _ = trace.StartSpan(ctx, name)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
// EndSpan ends an OpenTelemetry span with the given error.
|
||||
// EndSpan ends a span with the given error. If IsOpenCensusTracingEnabled
|
||||
// returns true, the span will be an OpenCensus span. If IsOpenTelemetryTracingEnabled
|
||||
// returns true, the span will be an OpenTelemetry span. Set the environment variable
|
||||
// GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING to the case-insensitive
|
||||
// value "opencensus" before loading the package to use OpenCensus tracing.
|
||||
// The default was OpenCensus until May 29, 2024, at which time the default was
|
||||
// changed to "opencensus". Explicitly setting the environment variable to
|
||||
// "opencensus" is required to continue using OpenCensus tracing.
|
||||
//
|
||||
// The default experimental tracing support for OpenCensus is now deprecated in
|
||||
// the Google Cloud client libraries for Go.
|
||||
func EndSpan(ctx context.Context, err error) {
|
||||
span := trace.SpanFromContext(ctx)
|
||||
if err != nil {
|
||||
span.SetStatus(codes.Error, toOpenTelemetryStatusDescription(err))
|
||||
span.RecordError(err)
|
||||
if IsOpenTelemetryTracingEnabled() {
|
||||
span := ottrace.SpanFromContext(ctx)
|
||||
if err != nil {
|
||||
span.SetStatus(codes.Error, toOpenTelemetryStatusDescription(err))
|
||||
span.RecordError(err)
|
||||
}
|
||||
span.End()
|
||||
} else {
|
||||
span := trace.FromContext(ctx)
|
||||
if err != nil {
|
||||
span.SetStatus(toStatus(err))
|
||||
}
|
||||
span.End()
|
||||
}
|
||||
}
|
||||
|
||||
// toStatus converts an error to an equivalent OpenCensus status.
|
||||
func toStatus(err error) trace.Status {
|
||||
var err2 *googleapi.Error
|
||||
if ok := errors.As(err, &err2); ok {
|
||||
return trace.Status{Code: httpStatusCodeToOCCode(err2.Code), Message: err2.Message}
|
||||
} else if s, ok := status.FromError(err); ok {
|
||||
return trace.Status{Code: int32(s.Code()), Message: s.Message()}
|
||||
} else {
|
||||
return trace.Status{Code: int32(code.Code_UNKNOWN), Message: err.Error()}
|
||||
}
|
||||
span.End()
|
||||
}
|
||||
|
||||
// toOpenTelemetryStatus converts an error to an equivalent OpenTelemetry status description.
|
||||
@@ -65,13 +169,87 @@ func toOpenTelemetryStatusDescription(err error) string {
|
||||
}
|
||||
}
|
||||
|
||||
// TracePrintf retrieves the current OpenTelemetry span from context, then calls
|
||||
// Span.AddEvent. The expected span must be an OpenTelemetry span. The default
|
||||
// experimental tracing support for OpenCensus is now deprecated in the Google
|
||||
// Cloud client libraries for Go.
|
||||
// TODO(deklerk): switch to using OpenCensus function when it becomes available.
|
||||
// Reference: https://github.com/googleapis/googleapis/blob/26b634d2724ac5dd30ae0b0cbfb01f07f2e4050e/google/rpc/code.proto
|
||||
func httpStatusCodeToOCCode(httpStatusCode int) int32 {
|
||||
switch httpStatusCode {
|
||||
case 200:
|
||||
return int32(code.Code_OK)
|
||||
case 499:
|
||||
return int32(code.Code_CANCELLED)
|
||||
case 500:
|
||||
return int32(code.Code_UNKNOWN) // Could also be Code_INTERNAL, Code_DATA_LOSS
|
||||
case 400:
|
||||
return int32(code.Code_INVALID_ARGUMENT) // Could also be Code_OUT_OF_RANGE
|
||||
case 504:
|
||||
return int32(code.Code_DEADLINE_EXCEEDED)
|
||||
case 404:
|
||||
return int32(code.Code_NOT_FOUND)
|
||||
case 409:
|
||||
return int32(code.Code_ALREADY_EXISTS) // Could also be Code_ABORTED
|
||||
case 403:
|
||||
return int32(code.Code_PERMISSION_DENIED)
|
||||
case 401:
|
||||
return int32(code.Code_UNAUTHENTICATED)
|
||||
case 429:
|
||||
return int32(code.Code_RESOURCE_EXHAUSTED)
|
||||
case 501:
|
||||
return int32(code.Code_UNIMPLEMENTED)
|
||||
case 503:
|
||||
return int32(code.Code_UNAVAILABLE)
|
||||
default:
|
||||
return int32(code.Code_UNKNOWN)
|
||||
}
|
||||
}
|
||||
|
||||
// TracePrintf retrieves the current OpenCensus or OpenTelemetry span from context, then:
|
||||
// * calls Span.Annotatef if OpenCensus is enabled; or
|
||||
// * calls Span.AddEvent if OpenTelemetry is enabled.
|
||||
//
|
||||
// If IsOpenCensusTracingEnabled returns true, the expected span must be an
|
||||
// OpenCensus span. If IsOpenTelemetryTracingEnabled returns true, the expected
|
||||
// span must be an OpenTelemetry span. Set the environment variable
|
||||
// GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING to the case-insensitive
|
||||
// value "opencensus" before loading the package to use OpenCensus tracing.
|
||||
// The default was OpenCensus until May 29, 2024, at which time the default was
|
||||
// changed to "opencensus". Explicitly setting the environment variable to
|
||||
// "opencensus" is required to continue using OpenCensus tracing.
|
||||
//
|
||||
// The default experimental tracing support for OpenCensus is now deprecated in
|
||||
// the Google Cloud client libraries for Go.
|
||||
func TracePrintf(ctx context.Context, attrMap map[string]interface{}, format string, args ...interface{}) {
|
||||
attrs := otAttrs(attrMap)
|
||||
trace.SpanFromContext(ctx).AddEvent(fmt.Sprintf(format, args...), trace.WithAttributes(attrs...))
|
||||
if IsOpenTelemetryTracingEnabled() {
|
||||
attrs := otAttrs(attrMap)
|
||||
ottrace.SpanFromContext(ctx).AddEvent(fmt.Sprintf(format, args...), ottrace.WithAttributes(attrs...))
|
||||
} else {
|
||||
attrs := ocAttrs(attrMap)
|
||||
// TODO: (odeke-em): perhaps just pass around spans due to the cost
|
||||
// incurred from using trace.FromContext(ctx) yet we could avoid
|
||||
// throwing away the work done by ctx, span := trace.StartSpan.
|
||||
trace.FromContext(ctx).Annotatef(attrs, format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// ocAttrs converts a generic map to OpenCensus attributes.
|
||||
func ocAttrs(attrMap map[string]interface{}) []trace.Attribute {
|
||||
var attrs []trace.Attribute
|
||||
for k, v := range attrMap {
|
||||
var a trace.Attribute
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
a = trace.StringAttribute(k, v)
|
||||
case bool:
|
||||
a = trace.BoolAttribute(k, v)
|
||||
case int:
|
||||
a = trace.Int64Attribute(k, int64(v))
|
||||
case int64:
|
||||
a = trace.Int64Attribute(k, v)
|
||||
default:
|
||||
a = trace.StringAttribute(k, fmt.Sprintf("%#v", v))
|
||||
}
|
||||
attrs = append(attrs, a)
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
// otAttrs converts a generic map to OpenTelemetry attributes.
|
||||
|
||||
15
vendor/github.com/go-kit/log/.gitignore
generated
vendored
Normal file
15
vendor/github.com/go-kit/log/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
21
vendor/github.com/go-kit/log/LICENSE
generated
vendored
Normal file
21
vendor/github.com/go-kit/log/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Go kit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
156
vendor/github.com/go-kit/log/README.md
generated
vendored
Normal file
156
vendor/github.com/go-kit/log/README.md
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
# package log
|
||||
|
||||
[](https://pkg.go.dev/github.com/go-kit/log)
|
||||
[](https://goreportcard.com/report/go-kit/log)
|
||||
[](https://github.com/go-kit/log/actions/workflows/test.yml)
|
||||
[](https://coveralls.io/github/go-kit/log?branch=main)
|
||||
|
||||
`package log` provides a minimal interface for structured logging in services.
|
||||
It may be wrapped to encode conventions, enforce type-safety, provide leveled
|
||||
logging, and so on. It can be used for both typical application log events,
|
||||
and log-structured data streams.
|
||||
|
||||
## Structured logging
|
||||
|
||||
Structured logging is, basically, conceding to the reality that logs are
|
||||
_data_, and warrant some level of schematic rigor. Using a stricter,
|
||||
key/value-oriented message format for our logs, containing contextual and
|
||||
semantic information, makes it much easier to get insight into the
|
||||
operational activity of the systems we build. Consequently, `package log` is
|
||||
of the strong belief that "[the benefits of structured logging outweigh the
|
||||
minimal effort involved](https://www.thoughtworks.com/radar/techniques/structured-logging)".
|
||||
|
||||
Migrating from unstructured to structured logging is probably a lot easier
|
||||
than you'd expect.
|
||||
|
||||
```go
|
||||
// Unstructured
|
||||
log.Printf("HTTP server listening on %s", addr)
|
||||
|
||||
// Structured
|
||||
logger.Log("transport", "HTTP", "addr", addr, "msg", "listening")
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Typical application logging
|
||||
|
||||
```go
|
||||
w := log.NewSyncWriter(os.Stderr)
|
||||
logger := log.NewLogfmtLogger(w)
|
||||
logger.Log("question", "what is the meaning of life?", "answer", 42)
|
||||
|
||||
// Output:
|
||||
// question="what is the meaning of life?" answer=42
|
||||
```
|
||||
|
||||
### Contextual Loggers
|
||||
|
||||
```go
|
||||
func main() {
|
||||
var logger log.Logger
|
||||
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
|
||||
logger = log.With(logger, "instance_id", 123)
|
||||
|
||||
logger.Log("msg", "starting")
|
||||
NewWorker(log.With(logger, "component", "worker")).Run()
|
||||
NewSlacker(log.With(logger, "component", "slacker")).Run()
|
||||
}
|
||||
|
||||
// Output:
|
||||
// instance_id=123 msg=starting
|
||||
// instance_id=123 component=worker msg=running
|
||||
// instance_id=123 component=slacker msg=running
|
||||
```
|
||||
|
||||
### Interact with stdlib logger
|
||||
|
||||
Redirect stdlib logger to Go kit logger.
|
||||
|
||||
```go
|
||||
import (
|
||||
"os"
|
||||
stdlog "log"
|
||||
kitlog "github.com/go-kit/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout))
|
||||
stdlog.SetOutput(kitlog.NewStdlibAdapter(logger))
|
||||
stdlog.Print("I sure like pie")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"}
|
||||
```
|
||||
|
||||
Or, if, for legacy reasons, you need to pipe all of your logging through the
|
||||
stdlib log package, you can redirect Go kit logger to the stdlib logger.
|
||||
|
||||
```go
|
||||
logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{})
|
||||
logger.Log("legacy", true, "msg", "at least it's something")
|
||||
|
||||
// Output:
|
||||
// 2016/01/01 12:34:56 legacy=true msg="at least it's something"
|
||||
```
|
||||
|
||||
### Timestamps and callers
|
||||
|
||||
```go
|
||||
var logger log.Logger
|
||||
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
|
||||
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
|
||||
|
||||
logger.Log("msg", "hello")
|
||||
|
||||
// Output:
|
||||
// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello
|
||||
```
|
||||
|
||||
## Levels
|
||||
|
||||
Log levels are supported via the [level package](https://godoc.org/github.com/go-kit/log/level).
|
||||
|
||||
## Supported output formats
|
||||
|
||||
- [Logfmt](https://brandur.org/logfmt) ([see also](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write))
|
||||
- JSON
|
||||
|
||||
## Enhancements
|
||||
|
||||
`package log` is centered on the one-method Logger interface.
|
||||
|
||||
```go
|
||||
type Logger interface {
|
||||
Log(keyvals ...interface{}) error
|
||||
}
|
||||
```
|
||||
|
||||
This interface, and its supporting code like is the product of much iteration
|
||||
and evaluation. For more details on the evolution of the Logger interface,
|
||||
see [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1),
|
||||
a talk by [Chris Hines](https://github.com/ChrisHines).
|
||||
Also, please see
|
||||
[#63](https://github.com/go-kit/kit/issues/63),
|
||||
[#76](https://github.com/go-kit/kit/pull/76),
|
||||
[#131](https://github.com/go-kit/kit/issues/131),
|
||||
[#157](https://github.com/go-kit/kit/pull/157),
|
||||
[#164](https://github.com/go-kit/kit/issues/164), and
|
||||
[#252](https://github.com/go-kit/kit/pull/252)
|
||||
to review historical conversations about package log and the Logger interface.
|
||||
|
||||
Value-add packages and suggestions,
|
||||
like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/log/level),
|
||||
are of course welcome. Good proposals should
|
||||
|
||||
- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/log#With),
|
||||
- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/log#Caller) in any wrapped contextual loggers, and
|
||||
- Be friendly to packages that accept only an unadorned log.Logger.
|
||||
|
||||
## Benchmarks & comparisons
|
||||
|
||||
There are a few Go logging benchmarks and comparisons that include Go kit's package log.
|
||||
|
||||
- [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) includes kit/log
|
||||
- [uber-common/zap](https://github.com/uber-common/zap), a zero-alloc logging library, includes a comparison with kit/log
|
||||
116
vendor/github.com/go-kit/log/doc.go
generated
vendored
Normal file
116
vendor/github.com/go-kit/log/doc.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// Package log provides a structured logger.
|
||||
//
|
||||
// Structured logging produces logs easily consumed later by humans or
|
||||
// machines. Humans might be interested in debugging errors, or tracing
|
||||
// specific requests. Machines might be interested in counting interesting
|
||||
// events, or aggregating information for off-line processing. In both cases,
|
||||
// it is important that the log messages are structured and actionable.
|
||||
// Package log is designed to encourage both of these best practices.
|
||||
//
|
||||
// Basic Usage
|
||||
//
|
||||
// The fundamental interface is Logger. Loggers create log events from
|
||||
// key/value data. The Logger interface has a single method, Log, which
|
||||
// accepts a sequence of alternating key/value pairs, which this package names
|
||||
// keyvals.
|
||||
//
|
||||
// type Logger interface {
|
||||
// Log(keyvals ...interface{}) error
|
||||
// }
|
||||
//
|
||||
// Here is an example of a function using a Logger to create log events.
|
||||
//
|
||||
// func RunTask(task Task, logger log.Logger) string {
|
||||
// logger.Log("taskID", task.ID, "event", "starting task")
|
||||
// ...
|
||||
// logger.Log("taskID", task.ID, "event", "task complete")
|
||||
// }
|
||||
//
|
||||
// The keys in the above example are "taskID" and "event". The values are
|
||||
// task.ID, "starting task", and "task complete". Every key is followed
|
||||
// immediately by its value.
|
||||
//
|
||||
// Keys are usually plain strings. Values may be any type that has a sensible
|
||||
// encoding in the chosen log format. With structured logging it is a good
|
||||
// idea to log simple values without formatting them. This practice allows
|
||||
// the chosen logger to encode values in the most appropriate way.
|
||||
//
|
||||
// Contextual Loggers
|
||||
//
|
||||
// A contextual logger stores keyvals that it includes in all log events.
|
||||
// Building appropriate contextual loggers reduces repetition and aids
|
||||
// consistency in the resulting log output. With, WithPrefix, and WithSuffix
|
||||
// add context to a logger. We can use With to improve the RunTask example.
|
||||
//
|
||||
// func RunTask(task Task, logger log.Logger) string {
|
||||
// logger = log.With(logger, "taskID", task.ID)
|
||||
// logger.Log("event", "starting task")
|
||||
// ...
|
||||
// taskHelper(task.Cmd, logger)
|
||||
// ...
|
||||
// logger.Log("event", "task complete")
|
||||
// }
|
||||
//
|
||||
// The improved version emits the same log events as the original for the
|
||||
// first and last calls to Log. Passing the contextual logger to taskHelper
|
||||
// enables each log event created by taskHelper to include the task.ID even
|
||||
// though taskHelper does not have access to that value. Using contextual
|
||||
// loggers this way simplifies producing log output that enables tracing the
|
||||
// life cycle of individual tasks. (See the Contextual example for the full
|
||||
// code of the above snippet.)
|
||||
//
|
||||
// Dynamic Contextual Values
|
||||
//
|
||||
// A Valuer function stored in a contextual logger generates a new value each
|
||||
// time an event is logged. The Valuer example demonstrates how this feature
|
||||
// works.
|
||||
//
|
||||
// Valuers provide the basis for consistently logging timestamps and source
|
||||
// code location. The log package defines several valuers for that purpose.
|
||||
// See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and
|
||||
// DefaultCaller. A common logger initialization sequence that ensures all log
|
||||
// entries contain a timestamp and source location looks like this:
|
||||
//
|
||||
// logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout))
|
||||
// logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
|
||||
//
|
||||
// Concurrent Safety
|
||||
//
|
||||
// Applications with multiple goroutines want each log event written to the
|
||||
// same logger to remain separate from other log events. Package log provides
|
||||
// two simple solutions for concurrent safe logging.
|
||||
//
|
||||
// NewSyncWriter wraps an io.Writer and serializes each call to its Write
|
||||
// method. Using a SyncWriter has the benefit that the smallest practical
|
||||
// portion of the logging logic is performed within a mutex, but it requires
|
||||
// the formatting Logger to make only one call to Write per log event.
|
||||
//
|
||||
// NewSyncLogger wraps any Logger and serializes each call to its Log method.
|
||||
// Using a SyncLogger has the benefit that it guarantees each log event is
|
||||
// handled atomically within the wrapped logger, but it typically serializes
|
||||
// both the formatting and output logic. Use a SyncLogger if the formatting
|
||||
// logger may perform multiple writes per log event.
|
||||
//
|
||||
// Error Handling
|
||||
//
|
||||
// This package relies on the practice of wrapping or decorating loggers with
|
||||
// other loggers to provide composable pieces of functionality. It also means
|
||||
// that Logger.Log must return an error because some
|
||||
// implementations—especially those that output log data to an io.Writer—may
|
||||
// encounter errors that cannot be handled locally. This in turn means that
|
||||
// Loggers that wrap other loggers should return errors from the wrapped
|
||||
// logger up the stack.
|
||||
//
|
||||
// Fortunately, the decorator pattern also provides a way to avoid the
|
||||
// necessity to check for errors every time an application calls Logger.Log.
|
||||
// An application required to panic whenever its Logger encounters
|
||||
// an error could initialize its logger as follows.
|
||||
//
|
||||
// fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout))
|
||||
// logger := log.LoggerFunc(func(keyvals ...interface{}) error {
|
||||
// if err := fmtlogger.Log(keyvals...); err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// return nil
|
||||
// })
|
||||
package log
|
||||
91
vendor/github.com/go-kit/log/json_logger.go
generated
vendored
Normal file
91
vendor/github.com/go-kit/log/json_logger.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type jsonLogger struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// NewJSONLogger returns a Logger that encodes keyvals to the Writer as a
|
||||
// single JSON object. Each log event produces no more than one call to
|
||||
// w.Write. The passed Writer must be safe for concurrent use by multiple
|
||||
// goroutines if the returned Logger will be used concurrently.
|
||||
func NewJSONLogger(w io.Writer) Logger {
|
||||
return &jsonLogger{w}
|
||||
}
|
||||
|
||||
func (l *jsonLogger) Log(keyvals ...interface{}) error {
|
||||
n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd
|
||||
m := make(map[string]interface{}, n)
|
||||
for i := 0; i < len(keyvals); i += 2 {
|
||||
k := keyvals[i]
|
||||
var v interface{} = ErrMissingValue
|
||||
if i+1 < len(keyvals) {
|
||||
v = keyvals[i+1]
|
||||
}
|
||||
merge(m, k, v)
|
||||
}
|
||||
enc := json.NewEncoder(l.Writer)
|
||||
enc.SetEscapeHTML(false)
|
||||
return enc.Encode(m)
|
||||
}
|
||||
|
||||
func merge(dst map[string]interface{}, k, v interface{}) {
|
||||
var key string
|
||||
switch x := k.(type) {
|
||||
case string:
|
||||
key = x
|
||||
case fmt.Stringer:
|
||||
key = safeString(x)
|
||||
default:
|
||||
key = fmt.Sprint(x)
|
||||
}
|
||||
|
||||
// We want json.Marshaler and encoding.TextMarshaller to take priority over
|
||||
// err.Error() and v.String(). But json.Marshall (called later) does that by
|
||||
// default so we force a no-op if it's one of those 2 case.
|
||||
switch x := v.(type) {
|
||||
case json.Marshaler:
|
||||
case encoding.TextMarshaler:
|
||||
case error:
|
||||
v = safeError(x)
|
||||
case fmt.Stringer:
|
||||
v = safeString(x)
|
||||
}
|
||||
|
||||
dst[key] = v
|
||||
}
|
||||
|
||||
func safeString(str fmt.Stringer) (s string) {
|
||||
defer func() {
|
||||
if panicVal := recover(); panicVal != nil {
|
||||
if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
s = "NULL"
|
||||
} else {
|
||||
s = fmt.Sprintf("PANIC in String method: %v", panicVal)
|
||||
}
|
||||
}
|
||||
}()
|
||||
s = str.String()
|
||||
return
|
||||
}
|
||||
|
||||
func safeError(err error) (s interface{}) {
|
||||
defer func() {
|
||||
if panicVal := recover(); panicVal != nil {
|
||||
if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
s = nil
|
||||
} else {
|
||||
s = fmt.Sprintf("PANIC in Error method: %v", panicVal)
|
||||
}
|
||||
}
|
||||
}()
|
||||
s = err.Error()
|
||||
return
|
||||
}
|
||||
33
vendor/github.com/go-kit/log/level/doc.go
generated
vendored
Normal file
33
vendor/github.com/go-kit/log/level/doc.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Package level implements leveled logging on top of Go kit's log package. To
|
||||
// use the level package, create a logger as per normal in your func main, and
|
||||
// wrap it with level.NewFilter.
|
||||
//
|
||||
// var logger log.Logger
|
||||
// logger = log.NewLogfmtLogger(os.Stderr)
|
||||
// logger = level.NewFilter(logger, level.AllowInfo()) // <--
|
||||
// logger = log.With(logger, "ts", log.DefaultTimestampUTC)
|
||||
//
|
||||
// It's also possible to configure log level from a string. For instance from
|
||||
// a flag, environment variable or configuration file.
|
||||
//
|
||||
// fs := flag.NewFlagSet("myprogram")
|
||||
// lvl := fs.String("log", "info", "debug, info, warn, error")
|
||||
//
|
||||
// var logger log.Logger
|
||||
// logger = log.NewLogfmtLogger(os.Stderr)
|
||||
// logger = level.NewFilter(logger, level.Allow(level.ParseDefault(*lvl, level.InfoValue()))) // <--
|
||||
// logger = log.With(logger, "ts", log.DefaultTimestampUTC)
|
||||
//
|
||||
// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error
|
||||
// helper methods to emit leveled log events.
|
||||
//
|
||||
// logger.Log("foo", "bar") // as normal, no level
|
||||
// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get())
|
||||
// if value > 100 {
|
||||
// level.Error(logger).Log("value", value)
|
||||
// }
|
||||
//
|
||||
// NewFilter allows precise control over what happens when a log event is
|
||||
// emitted without a level key, or if a squelched level is used. Check the
|
||||
// Option functions for details.
|
||||
package level
|
||||
256
vendor/github.com/go-kit/log/level/level.go
generated
vendored
Normal file
256
vendor/github.com/go-kit/log/level/level.go
generated
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
package level
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
)
|
||||
|
||||
// ErrInvalidLevelString is returned whenever an invalid string is passed to Parse.
|
||||
var ErrInvalidLevelString = errors.New("invalid level string")
|
||||
|
||||
// Error returns a logger that includes a Key/ErrorValue pair.
|
||||
func Error(logger log.Logger) log.Logger {
|
||||
return log.WithPrefix(logger, Key(), ErrorValue())
|
||||
}
|
||||
|
||||
// Warn returns a logger that includes a Key/WarnValue pair.
|
||||
func Warn(logger log.Logger) log.Logger {
|
||||
return log.WithPrefix(logger, Key(), WarnValue())
|
||||
}
|
||||
|
||||
// Info returns a logger that includes a Key/InfoValue pair.
|
||||
func Info(logger log.Logger) log.Logger {
|
||||
return log.WithPrefix(logger, Key(), InfoValue())
|
||||
}
|
||||
|
||||
// Debug returns a logger that includes a Key/DebugValue pair.
|
||||
func Debug(logger log.Logger) log.Logger {
|
||||
return log.WithPrefix(logger, Key(), DebugValue())
|
||||
}
|
||||
|
||||
// NewFilter wraps next and implements level filtering. See the commentary on
|
||||
// the Option functions for a detailed description of how to configure levels.
|
||||
// If no options are provided, all leveled log events created with Debug,
|
||||
// Info, Warn or Error helper methods are squelched and non-leveled log
|
||||
// events are passed to next unmodified.
|
||||
func NewFilter(next log.Logger, options ...Option) log.Logger {
|
||||
l := &logger{
|
||||
next: next,
|
||||
}
|
||||
for _, option := range options {
|
||||
option(l)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
type logger struct {
|
||||
next log.Logger
|
||||
allowed level
|
||||
squelchNoLevel bool
|
||||
errNotAllowed error
|
||||
errNoLevel error
|
||||
}
|
||||
|
||||
func (l *logger) Log(keyvals ...interface{}) error {
|
||||
var hasLevel, levelAllowed bool
|
||||
for i := 1; i < len(keyvals); i += 2 {
|
||||
if v, ok := keyvals[i].(*levelValue); ok {
|
||||
hasLevel = true
|
||||
levelAllowed = l.allowed&v.level != 0
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasLevel && l.squelchNoLevel {
|
||||
return l.errNoLevel
|
||||
}
|
||||
if hasLevel && !levelAllowed {
|
||||
return l.errNotAllowed
|
||||
}
|
||||
return l.next.Log(keyvals...)
|
||||
}
|
||||
|
||||
// Option sets a parameter for the leveled logger.
|
||||
type Option func(*logger)
|
||||
|
||||
// Allow the provided log level to pass.
|
||||
func Allow(v Value) Option {
|
||||
switch v {
|
||||
case debugValue:
|
||||
return AllowDebug()
|
||||
case infoValue:
|
||||
return AllowInfo()
|
||||
case warnValue:
|
||||
return AllowWarn()
|
||||
case errorValue:
|
||||
return AllowError()
|
||||
default:
|
||||
return AllowNone()
|
||||
}
|
||||
}
|
||||
|
||||
// AllowAll is an alias for AllowDebug.
|
||||
func AllowAll() Option {
|
||||
return AllowDebug()
|
||||
}
|
||||
|
||||
// AllowDebug allows error, warn, info and debug level log events to pass.
|
||||
func AllowDebug() Option {
|
||||
return allowed(levelError | levelWarn | levelInfo | levelDebug)
|
||||
}
|
||||
|
||||
// AllowInfo allows error, warn and info level log events to pass.
|
||||
func AllowInfo() Option {
|
||||
return allowed(levelError | levelWarn | levelInfo)
|
||||
}
|
||||
|
||||
// AllowWarn allows error and warn level log events to pass.
|
||||
func AllowWarn() Option {
|
||||
return allowed(levelError | levelWarn)
|
||||
}
|
||||
|
||||
// AllowError allows only error level log events to pass.
|
||||
func AllowError() Option {
|
||||
return allowed(levelError)
|
||||
}
|
||||
|
||||
// AllowNone allows no leveled log events to pass.
|
||||
func AllowNone() Option {
|
||||
return allowed(0)
|
||||
}
|
||||
|
||||
func allowed(allowed level) Option {
|
||||
return func(l *logger) { l.allowed = allowed }
|
||||
}
|
||||
|
||||
// Parse a string to its corresponding level value. Valid strings are "debug",
|
||||
// "info", "warn", and "error". Strings are normalized via strings.TrimSpace and
|
||||
// strings.ToLower.
|
||||
func Parse(level string) (Value, error) {
|
||||
switch strings.TrimSpace(strings.ToLower(level)) {
|
||||
case debugValue.name:
|
||||
return debugValue, nil
|
||||
case infoValue.name:
|
||||
return infoValue, nil
|
||||
case warnValue.name:
|
||||
return warnValue, nil
|
||||
case errorValue.name:
|
||||
return errorValue, nil
|
||||
default:
|
||||
return nil, ErrInvalidLevelString
|
||||
}
|
||||
}
|
||||
|
||||
// ParseDefault calls Parse and returns the default Value on error.
|
||||
func ParseDefault(level string, def Value) Value {
|
||||
v, err := Parse(level)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// ErrNotAllowed sets the error to return from Log when it squelches a log
|
||||
// event disallowed by the configured Allow[Level] option. By default,
|
||||
// ErrNotAllowed is nil; in this case the log event is squelched with no
|
||||
// error.
|
||||
func ErrNotAllowed(err error) Option {
|
||||
return func(l *logger) { l.errNotAllowed = err }
|
||||
}
|
||||
|
||||
// SquelchNoLevel instructs Log to squelch log events with no level, so that
|
||||
// they don't proceed through to the wrapped logger. If SquelchNoLevel is set
|
||||
// to true and a log event is squelched in this way, the error value
|
||||
// configured with ErrNoLevel is returned to the caller.
|
||||
func SquelchNoLevel(squelch bool) Option {
|
||||
return func(l *logger) { l.squelchNoLevel = squelch }
|
||||
}
|
||||
|
||||
// ErrNoLevel sets the error to return from Log when it squelches a log event
|
||||
// with no level. By default, ErrNoLevel is nil; in this case the log event is
|
||||
// squelched with no error.
|
||||
func ErrNoLevel(err error) Option {
|
||||
return func(l *logger) { l.errNoLevel = err }
|
||||
}
|
||||
|
||||
// NewInjector wraps next and returns a logger that adds a Key/level pair to
|
||||
// the beginning of log events that don't already contain a level. In effect,
|
||||
// this gives a default level to logs without a level.
|
||||
func NewInjector(next log.Logger, level Value) log.Logger {
|
||||
return &injector{
|
||||
next: next,
|
||||
level: level,
|
||||
}
|
||||
}
|
||||
|
||||
type injector struct {
|
||||
next log.Logger
|
||||
level interface{}
|
||||
}
|
||||
|
||||
func (l *injector) Log(keyvals ...interface{}) error {
|
||||
for i := 1; i < len(keyvals); i += 2 {
|
||||
if _, ok := keyvals[i].(*levelValue); ok {
|
||||
return l.next.Log(keyvals...)
|
||||
}
|
||||
}
|
||||
kvs := make([]interface{}, len(keyvals)+2)
|
||||
kvs[0], kvs[1] = key, l.level
|
||||
copy(kvs[2:], keyvals)
|
||||
return l.next.Log(kvs...)
|
||||
}
|
||||
|
||||
// Value is the interface that each of the canonical level values implement.
|
||||
// It contains unexported methods that prevent types from other packages from
|
||||
// implementing it and guaranteeing that NewFilter can distinguish the levels
|
||||
// defined in this package from all other values.
|
||||
type Value interface {
|
||||
String() string
|
||||
levelVal()
|
||||
}
|
||||
|
||||
// Key returns the unique key added to log events by the loggers in this
|
||||
// package.
|
||||
func Key() interface{} { return key }
|
||||
|
||||
// ErrorValue returns the unique value added to log events by Error.
|
||||
func ErrorValue() Value { return errorValue }
|
||||
|
||||
// WarnValue returns the unique value added to log events by Warn.
|
||||
func WarnValue() Value { return warnValue }
|
||||
|
||||
// InfoValue returns the unique value added to log events by Info.
|
||||
func InfoValue() Value { return infoValue }
|
||||
|
||||
// DebugValue returns the unique value added to log events by Debug.
|
||||
func DebugValue() Value { return debugValue }
|
||||
|
||||
var (
|
||||
// key is of type interface{} so that it allocates once during package
|
||||
// initialization and avoids allocating every time the value is added to a
|
||||
// []interface{} later.
|
||||
key interface{} = "level"
|
||||
|
||||
errorValue = &levelValue{level: levelError, name: "error"}
|
||||
warnValue = &levelValue{level: levelWarn, name: "warn"}
|
||||
infoValue = &levelValue{level: levelInfo, name: "info"}
|
||||
debugValue = &levelValue{level: levelDebug, name: "debug"}
|
||||
)
|
||||
|
||||
type level byte
|
||||
|
||||
const (
|
||||
levelDebug level = 1 << iota
|
||||
levelInfo
|
||||
levelWarn
|
||||
levelError
|
||||
)
|
||||
|
||||
type levelValue struct {
|
||||
name string
|
||||
level
|
||||
}
|
||||
|
||||
func (v *levelValue) String() string { return v.name }
|
||||
func (v *levelValue) levelVal() {}
|
||||
179
vendor/github.com/go-kit/log/log.go
generated
vendored
Normal file
179
vendor/github.com/go-kit/log/log.go
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
package log
|
||||
|
||||
import "errors"
|
||||
|
||||
// Logger is the fundamental interface for all log operations. Log creates a
|
||||
// log event from keyvals, a variadic sequence of alternating keys and values.
|
||||
// Implementations must be safe for concurrent use by multiple goroutines. In
|
||||
// particular, any implementation of Logger that appends to keyvals or
|
||||
// modifies or retains any of its elements must make a copy first.
|
||||
type Logger interface {
|
||||
Log(keyvals ...interface{}) error
|
||||
}
|
||||
|
||||
// ErrMissingValue is appended to keyvals slices with odd length to substitute
|
||||
// the missing value.
|
||||
var ErrMissingValue = errors.New("(MISSING)")
|
||||
|
||||
// With returns a new contextual logger with keyvals prepended to those passed
|
||||
// to calls to Log. If logger is also a contextual logger created by With,
|
||||
// WithPrefix, or WithSuffix, keyvals is appended to the existing context.
|
||||
//
|
||||
// The returned Logger replaces all value elements (odd indexes) containing a
|
||||
// Valuer with their generated value for each call to its Log method.
|
||||
func With(logger Logger, keyvals ...interface{}) Logger {
|
||||
if len(keyvals) == 0 {
|
||||
return logger
|
||||
}
|
||||
l := newContext(logger)
|
||||
kvs := append(l.keyvals, keyvals...)
|
||||
if len(kvs)%2 != 0 {
|
||||
kvs = append(kvs, ErrMissingValue)
|
||||
}
|
||||
return &context{
|
||||
logger: l.logger,
|
||||
// Limiting the capacity of the stored keyvals ensures that a new
|
||||
// backing array is created if the slice must grow in Log or With.
|
||||
// Using the extra capacity without copying risks a data race that
|
||||
// would violate the Logger interface contract.
|
||||
keyvals: kvs[:len(kvs):len(kvs)],
|
||||
hasValuer: l.hasValuer || containsValuer(keyvals),
|
||||
sKeyvals: l.sKeyvals,
|
||||
sHasValuer: l.sHasValuer,
|
||||
}
|
||||
}
|
||||
|
||||
// WithPrefix returns a new contextual logger with keyvals prepended to those
|
||||
// passed to calls to Log. If logger is also a contextual logger created by
|
||||
// With, WithPrefix, or WithSuffix, keyvals is prepended to the existing context.
|
||||
//
|
||||
// The returned Logger replaces all value elements (odd indexes) containing a
|
||||
// Valuer with their generated value for each call to its Log method.
|
||||
func WithPrefix(logger Logger, keyvals ...interface{}) Logger {
|
||||
if len(keyvals) == 0 {
|
||||
return logger
|
||||
}
|
||||
l := newContext(logger)
|
||||
// Limiting the capacity of the stored keyvals ensures that a new
|
||||
// backing array is created if the slice must grow in Log or With.
|
||||
// Using the extra capacity without copying risks a data race that
|
||||
// would violate the Logger interface contract.
|
||||
n := len(l.keyvals) + len(keyvals)
|
||||
if len(keyvals)%2 != 0 {
|
||||
n++
|
||||
}
|
||||
kvs := make([]interface{}, 0, n)
|
||||
kvs = append(kvs, keyvals...)
|
||||
if len(kvs)%2 != 0 {
|
||||
kvs = append(kvs, ErrMissingValue)
|
||||
}
|
||||
kvs = append(kvs, l.keyvals...)
|
||||
return &context{
|
||||
logger: l.logger,
|
||||
keyvals: kvs,
|
||||
hasValuer: l.hasValuer || containsValuer(keyvals),
|
||||
sKeyvals: l.sKeyvals,
|
||||
sHasValuer: l.sHasValuer,
|
||||
}
|
||||
}
|
||||
|
||||
// WithSuffix returns a new contextual logger with keyvals appended to those
|
||||
// passed to calls to Log. If logger is also a contextual logger created by
|
||||
// With, WithPrefix, or WithSuffix, keyvals is appended to the existing context.
|
||||
//
|
||||
// The returned Logger replaces all value elements (odd indexes) containing a
|
||||
// Valuer with their generated value for each call to its Log method.
|
||||
func WithSuffix(logger Logger, keyvals ...interface{}) Logger {
|
||||
if len(keyvals) == 0 {
|
||||
return logger
|
||||
}
|
||||
l := newContext(logger)
|
||||
// Limiting the capacity of the stored keyvals ensures that a new
|
||||
// backing array is created if the slice must grow in Log or With.
|
||||
// Using the extra capacity without copying risks a data race that
|
||||
// would violate the Logger interface contract.
|
||||
n := len(l.sKeyvals) + len(keyvals)
|
||||
if len(keyvals)%2 != 0 {
|
||||
n++
|
||||
}
|
||||
kvs := make([]interface{}, 0, n)
|
||||
kvs = append(kvs, keyvals...)
|
||||
if len(kvs)%2 != 0 {
|
||||
kvs = append(kvs, ErrMissingValue)
|
||||
}
|
||||
kvs = append(l.sKeyvals, kvs...)
|
||||
return &context{
|
||||
logger: l.logger,
|
||||
keyvals: l.keyvals,
|
||||
hasValuer: l.hasValuer,
|
||||
sKeyvals: kvs,
|
||||
sHasValuer: l.sHasValuer || containsValuer(keyvals),
|
||||
}
|
||||
}
|
||||
|
||||
// context is the Logger implementation returned by With, WithPrefix, and
|
||||
// WithSuffix. It wraps a Logger and holds keyvals that it includes in all
|
||||
// log events. Its Log method calls bindValues to generate values for each
|
||||
// Valuer in the context keyvals.
|
||||
//
|
||||
// A context must always have the same number of stack frames between calls to
|
||||
// its Log method and the eventual binding of Valuers to their value. This
|
||||
// requirement comes from the functional requirement to allow a context to
|
||||
// resolve application call site information for a Caller stored in the
|
||||
// context. To do this we must be able to predict the number of logging
|
||||
// functions on the stack when bindValues is called.
|
||||
//
|
||||
// Two implementation details provide the needed stack depth consistency.
|
||||
//
|
||||
// 1. newContext avoids introducing an additional layer when asked to
|
||||
// wrap another context.
|
||||
// 2. With, WithPrefix, and WithSuffix avoid introducing an additional
|
||||
// layer by returning a newly constructed context with a merged keyvals
|
||||
// rather than simply wrapping the existing context.
|
||||
type context struct {
|
||||
logger Logger
|
||||
keyvals []interface{}
|
||||
sKeyvals []interface{} // suffixes
|
||||
hasValuer bool
|
||||
sHasValuer bool
|
||||
}
|
||||
|
||||
func newContext(logger Logger) *context {
|
||||
if c, ok := logger.(*context); ok {
|
||||
return c
|
||||
}
|
||||
return &context{logger: logger}
|
||||
}
|
||||
|
||||
// Log replaces all value elements (odd indexes) containing a Valuer in the
|
||||
// stored context with their generated value, appends keyvals, and passes the
|
||||
// result to the wrapped Logger.
|
||||
func (l *context) Log(keyvals ...interface{}) error {
|
||||
kvs := append(l.keyvals, keyvals...)
|
||||
if len(kvs)%2 != 0 {
|
||||
kvs = append(kvs, ErrMissingValue)
|
||||
}
|
||||
if l.hasValuer {
|
||||
// If no keyvals were appended above then we must copy l.keyvals so
|
||||
// that future log events will reevaluate the stored Valuers.
|
||||
if len(keyvals) == 0 {
|
||||
kvs = append([]interface{}{}, l.keyvals...)
|
||||
}
|
||||
bindValues(kvs[:(len(l.keyvals))])
|
||||
}
|
||||
kvs = append(kvs, l.sKeyvals...)
|
||||
if l.sHasValuer {
|
||||
bindValues(kvs[len(kvs)-len(l.sKeyvals):])
|
||||
}
|
||||
return l.logger.Log(kvs...)
|
||||
}
|
||||
|
||||
// LoggerFunc is an adapter to allow use of ordinary functions as Loggers. If
|
||||
// f is a function with the appropriate signature, LoggerFunc(f) is a Logger
|
||||
// object that calls f.
|
||||
type LoggerFunc func(...interface{}) error
|
||||
|
||||
// Log implements Logger by calling f(keyvals...).
|
||||
func (f LoggerFunc) Log(keyvals ...interface{}) error {
|
||||
return f(keyvals...)
|
||||
}
|
||||
62
vendor/github.com/go-kit/log/logfmt_logger.go
generated
vendored
Normal file
62
vendor/github.com/go-kit/log/logfmt_logger.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/go-logfmt/logfmt"
|
||||
)
|
||||
|
||||
type logfmtEncoder struct {
|
||||
*logfmt.Encoder
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
func (l *logfmtEncoder) Reset() {
|
||||
l.Encoder.Reset()
|
||||
l.buf.Reset()
|
||||
}
|
||||
|
||||
var logfmtEncoderPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
var enc logfmtEncoder
|
||||
enc.Encoder = logfmt.NewEncoder(&enc.buf)
|
||||
return &enc
|
||||
},
|
||||
}
|
||||
|
||||
type logfmtLogger struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in
|
||||
// logfmt format. Each log event produces no more than one call to w.Write.
|
||||
// The passed Writer must be safe for concurrent use by multiple goroutines if
|
||||
// the returned Logger will be used concurrently.
|
||||
func NewLogfmtLogger(w io.Writer) Logger {
|
||||
return &logfmtLogger{w}
|
||||
}
|
||||
|
||||
func (l logfmtLogger) Log(keyvals ...interface{}) error {
|
||||
enc := logfmtEncoderPool.Get().(*logfmtEncoder)
|
||||
enc.Reset()
|
||||
defer logfmtEncoderPool.Put(enc)
|
||||
|
||||
if err := enc.EncodeKeyvals(keyvals...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add newline to the end of the buffer
|
||||
if err := enc.EndRecord(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The Logger interface requires implementations to be safe for concurrent
|
||||
// use by multiple goroutines. For this implementation that means making
|
||||
// only one call to l.w.Write() for each call to Log.
|
||||
if _, err := l.w.Write(enc.buf.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
8
vendor/github.com/go-kit/log/nop_logger.go
generated
vendored
Normal file
8
vendor/github.com/go-kit/log/nop_logger.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
package log
|
||||
|
||||
type nopLogger struct{}
|
||||
|
||||
// NewNopLogger returns a logger that doesn't do anything.
|
||||
func NewNopLogger() Logger { return nopLogger{} }
|
||||
|
||||
func (nopLogger) Log(...interface{}) error { return nil }
|
||||
1
vendor/github.com/go-kit/log/staticcheck.conf
generated
vendored
Normal file
1
vendor/github.com/go-kit/log/staticcheck.conf
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
checks = ["all"]
|
||||
151
vendor/github.com/go-kit/log/stdlib.go
generated
vendored
Normal file
151
vendor/github.com/go-kit/log/stdlib.go
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's
|
||||
// designed to be passed to a Go kit logger as the writer, for cases where
|
||||
// it's necessary to redirect all Go kit log output to the stdlib logger.
|
||||
//
|
||||
// If you have any choice in the matter, you shouldn't use this. Prefer to
|
||||
// redirect the stdlib log to the Go kit logger via NewStdlibAdapter.
|
||||
type StdlibWriter struct{}
|
||||
|
||||
// Write implements io.Writer.
|
||||
func (w StdlibWriter) Write(p []byte) (int, error) {
|
||||
log.Print(strings.TrimSpace(string(p)))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// StdlibAdapter wraps a Logger and allows it to be passed to the stdlib
|
||||
// logger's SetOutput. It will extract date/timestamps, filenames, and
|
||||
// messages, and place them under relevant keys.
|
||||
type StdlibAdapter struct {
|
||||
Logger
|
||||
timestampKey string
|
||||
fileKey string
|
||||
messageKey string
|
||||
prefix string
|
||||
joinPrefixToMsg bool
|
||||
}
|
||||
|
||||
// StdlibAdapterOption sets a parameter for the StdlibAdapter.
|
||||
type StdlibAdapterOption func(*StdlibAdapter)
|
||||
|
||||
// TimestampKey sets the key for the timestamp field. By default, it's "ts".
|
||||
func TimestampKey(key string) StdlibAdapterOption {
|
||||
return func(a *StdlibAdapter) { a.timestampKey = key }
|
||||
}
|
||||
|
||||
// FileKey sets the key for the file and line field. By default, it's "caller".
|
||||
func FileKey(key string) StdlibAdapterOption {
|
||||
return func(a *StdlibAdapter) { a.fileKey = key }
|
||||
}
|
||||
|
||||
// MessageKey sets the key for the actual log message. By default, it's "msg".
|
||||
func MessageKey(key string) StdlibAdapterOption {
|
||||
return func(a *StdlibAdapter) { a.messageKey = key }
|
||||
}
|
||||
|
||||
// Prefix configures the adapter to parse a prefix from stdlib log events. If
|
||||
// you provide a non-empty prefix to the stdlib logger, then your should provide
|
||||
// that same prefix to the adapter via this option.
|
||||
//
|
||||
// By default, the prefix isn't included in the msg key. Set joinPrefixToMsg to
|
||||
// true if you want to include the parsed prefix in the msg.
|
||||
func Prefix(prefix string, joinPrefixToMsg bool) StdlibAdapterOption {
|
||||
return func(a *StdlibAdapter) { a.prefix = prefix; a.joinPrefixToMsg = joinPrefixToMsg }
|
||||
}
|
||||
|
||||
// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed
|
||||
// logger. It's designed to be passed to log.SetOutput.
|
||||
func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer {
|
||||
a := StdlibAdapter{
|
||||
Logger: logger,
|
||||
timestampKey: "ts",
|
||||
fileKey: "caller",
|
||||
messageKey: "msg",
|
||||
}
|
||||
for _, option := range options {
|
||||
option(&a)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (a StdlibAdapter) Write(p []byte) (int, error) {
|
||||
p = a.handlePrefix(p)
|
||||
|
||||
result := subexps(p)
|
||||
keyvals := []interface{}{}
|
||||
var timestamp string
|
||||
if date, ok := result["date"]; ok && date != "" {
|
||||
timestamp = date
|
||||
}
|
||||
if time, ok := result["time"]; ok && time != "" {
|
||||
if timestamp != "" {
|
||||
timestamp += " "
|
||||
}
|
||||
timestamp += time
|
||||
}
|
||||
if timestamp != "" {
|
||||
keyvals = append(keyvals, a.timestampKey, timestamp)
|
||||
}
|
||||
if file, ok := result["file"]; ok && file != "" {
|
||||
keyvals = append(keyvals, a.fileKey, file)
|
||||
}
|
||||
if msg, ok := result["msg"]; ok {
|
||||
msg = a.handleMessagePrefix(msg)
|
||||
keyvals = append(keyvals, a.messageKey, msg)
|
||||
}
|
||||
if err := a.Logger.Log(keyvals...); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (a StdlibAdapter) handlePrefix(p []byte) []byte {
|
||||
if a.prefix != "" {
|
||||
p = bytes.TrimPrefix(p, []byte(a.prefix))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (a StdlibAdapter) handleMessagePrefix(msg string) string {
|
||||
if a.prefix == "" {
|
||||
return msg
|
||||
}
|
||||
|
||||
msg = strings.TrimPrefix(msg, a.prefix)
|
||||
if a.joinPrefixToMsg {
|
||||
msg = a.prefix + msg
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
const (
|
||||
logRegexpDate = `(?P<date>[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?`
|
||||
logRegexpTime = `(?P<time>[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)?[ ]?`
|
||||
logRegexpFile = `(?P<file>.+?:[0-9]+)?`
|
||||
logRegexpMsg = `(: )?(?P<msg>(?s:.*))`
|
||||
)
|
||||
|
||||
var (
|
||||
logRegexp = regexp.MustCompile(logRegexpDate + logRegexpTime + logRegexpFile + logRegexpMsg)
|
||||
)
|
||||
|
||||
func subexps(line []byte) map[string]string {
|
||||
m := logRegexp.FindSubmatch(line)
|
||||
if len(m) < len(logRegexp.SubexpNames()) {
|
||||
return map[string]string{}
|
||||
}
|
||||
result := map[string]string{}
|
||||
for i, name := range logRegexp.SubexpNames() {
|
||||
result[name] = strings.TrimRight(string(m[i]), "\n")
|
||||
}
|
||||
return result
|
||||
}
|
||||
113
vendor/github.com/go-kit/log/sync.go
generated
vendored
Normal file
113
vendor/github.com/go-kit/log/sync.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// SwapLogger wraps another logger that may be safely replaced while other
|
||||
// goroutines use the SwapLogger concurrently. The zero value for a SwapLogger
|
||||
// will discard all log events without error.
|
||||
//
|
||||
// SwapLogger serves well as a package global logger that can be changed by
|
||||
// importers.
|
||||
type SwapLogger struct {
|
||||
logger atomic.Value
|
||||
}
|
||||
|
||||
type loggerStruct struct {
|
||||
Logger
|
||||
}
|
||||
|
||||
// Log implements the Logger interface by forwarding keyvals to the currently
|
||||
// wrapped logger. It does not log anything if the wrapped logger is nil.
|
||||
func (l *SwapLogger) Log(keyvals ...interface{}) error {
|
||||
s, ok := l.logger.Load().(loggerStruct)
|
||||
if !ok || s.Logger == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Log(keyvals...)
|
||||
}
|
||||
|
||||
// Swap replaces the currently wrapped logger with logger. Swap may be called
|
||||
// concurrently with calls to Log from other goroutines.
|
||||
func (l *SwapLogger) Swap(logger Logger) {
|
||||
l.logger.Store(loggerStruct{logger})
|
||||
}
|
||||
|
||||
// NewSyncWriter returns a new writer that is safe for concurrent use by
|
||||
// multiple goroutines. Writes to the returned writer are passed on to w. If
|
||||
// another write is already in progress, the calling goroutine blocks until
|
||||
// the writer is available.
|
||||
//
|
||||
// If w implements the following interface, so does the returned writer.
|
||||
//
|
||||
// interface {
|
||||
// Fd() uintptr
|
||||
// }
|
||||
func NewSyncWriter(w io.Writer) io.Writer {
|
||||
switch w := w.(type) {
|
||||
case fdWriter:
|
||||
return &fdSyncWriter{fdWriter: w}
|
||||
default:
|
||||
return &syncWriter{Writer: w}
|
||||
}
|
||||
}
|
||||
|
||||
// syncWriter synchronizes concurrent writes to an io.Writer.
|
||||
type syncWriter struct {
|
||||
sync.Mutex
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// Write writes p to the underlying io.Writer. If another write is already in
|
||||
// progress, the calling goroutine blocks until the syncWriter is available.
|
||||
func (w *syncWriter) Write(p []byte) (n int, err error) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
return w.Writer.Write(p)
|
||||
}
|
||||
|
||||
// fdWriter is an io.Writer that also has an Fd method. The most common
|
||||
// example of an fdWriter is an *os.File.
|
||||
type fdWriter interface {
|
||||
io.Writer
|
||||
Fd() uintptr
|
||||
}
|
||||
|
||||
// fdSyncWriter synchronizes concurrent writes to an fdWriter.
|
||||
type fdSyncWriter struct {
|
||||
sync.Mutex
|
||||
fdWriter
|
||||
}
|
||||
|
||||
// Write writes p to the underlying io.Writer. If another write is already in
|
||||
// progress, the calling goroutine blocks until the fdSyncWriter is available.
|
||||
func (w *fdSyncWriter) Write(p []byte) (n int, err error) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
return w.fdWriter.Write(p)
|
||||
}
|
||||
|
||||
// syncLogger provides concurrent safe logging for another Logger.
|
||||
type syncLogger struct {
|
||||
mu sync.Mutex
|
||||
logger Logger
|
||||
}
|
||||
|
||||
// NewSyncLogger returns a logger that synchronizes concurrent use of the
|
||||
// wrapped logger. When multiple goroutines use the SyncLogger concurrently
|
||||
// only one goroutine will be allowed to log to the wrapped logger at a time.
|
||||
// The other goroutines will block until the logger is available.
|
||||
func NewSyncLogger(logger Logger) Logger {
|
||||
return &syncLogger{logger: logger}
|
||||
}
|
||||
|
||||
// Log logs keyvals to the underlying Logger. If another log is already in
|
||||
// progress, the calling goroutine blocks until the syncLogger is available.
|
||||
func (l *syncLogger) Log(keyvals ...interface{}) error {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
return l.logger.Log(keyvals...)
|
||||
}
|
||||
110
vendor/github.com/go-kit/log/value.go
generated
vendored
Normal file
110
vendor/github.com/go-kit/log/value.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Valuer generates a log value. When passed to With, WithPrefix, or
|
||||
// WithSuffix in a value element (odd indexes), it represents a dynamic
|
||||
// value which is re-evaluated with each log event.
|
||||
type Valuer func() interface{}
|
||||
|
||||
// bindValues replaces all value elements (odd indexes) containing a Valuer
|
||||
// with their generated value.
|
||||
func bindValues(keyvals []interface{}) {
|
||||
for i := 1; i < len(keyvals); i += 2 {
|
||||
if v, ok := keyvals[i].(Valuer); ok {
|
||||
keyvals[i] = v()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// containsValuer returns true if any of the value elements (odd indexes)
|
||||
// contain a Valuer.
|
||||
func containsValuer(keyvals []interface{}) bool {
|
||||
for i := 1; i < len(keyvals); i += 2 {
|
||||
if _, ok := keyvals[i].(Valuer); ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Timestamp returns a timestamp Valuer. It invokes the t function to get the
|
||||
// time; unless you are doing something tricky, pass time.Now.
|
||||
//
|
||||
// Most users will want to use DefaultTimestamp or DefaultTimestampUTC, which
|
||||
// are TimestampFormats that use the RFC3339Nano format.
|
||||
func Timestamp(t func() time.Time) Valuer {
|
||||
return func() interface{} { return t() }
|
||||
}
|
||||
|
||||
// TimestampFormat returns a timestamp Valuer with a custom time format. It
|
||||
// invokes the t function to get the time to format; unless you are doing
|
||||
// something tricky, pass time.Now. The layout string is passed to
|
||||
// Time.Format.
|
||||
//
|
||||
// Most users will want to use DefaultTimestamp or DefaultTimestampUTC, which
|
||||
// are TimestampFormats that use the RFC3339Nano format.
|
||||
func TimestampFormat(t func() time.Time, layout string) Valuer {
|
||||
return func() interface{} {
|
||||
return timeFormat{
|
||||
time: t(),
|
||||
layout: layout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A timeFormat represents an instant in time and a layout used when
|
||||
// marshaling to a text format.
|
||||
type timeFormat struct {
|
||||
time time.Time
|
||||
layout string
|
||||
}
|
||||
|
||||
func (tf timeFormat) String() string {
|
||||
return tf.time.Format(tf.layout)
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaller.
|
||||
func (tf timeFormat) MarshalText() (text []byte, err error) {
|
||||
// The following code adapted from the standard library time.Time.Format
|
||||
// method. Using the same undocumented magic constant to extend the size
|
||||
// of the buffer as seen there.
|
||||
b := make([]byte, 0, len(tf.layout)+10)
|
||||
b = tf.time.AppendFormat(b, tf.layout)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Caller returns a Valuer that returns a file and line from a specified depth
|
||||
// in the callstack. Users will probably want to use DefaultCaller.
|
||||
func Caller(depth int) Valuer {
|
||||
return func() interface{} {
|
||||
_, file, line, _ := runtime.Caller(depth)
|
||||
idx := strings.LastIndexByte(file, '/')
|
||||
// using idx+1 below handles both of following cases:
|
||||
// idx == -1 because no "/" was found, or
|
||||
// idx >= 0 and we want to start at the character after the found "/".
|
||||
return file[idx+1:] + ":" + strconv.Itoa(line)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultTimestamp is a Valuer that returns the current wallclock time,
|
||||
// respecting time zones, when bound.
|
||||
DefaultTimestamp = TimestampFormat(time.Now, time.RFC3339Nano)
|
||||
|
||||
// DefaultTimestampUTC is a Valuer that returns the current time in UTC
|
||||
// when bound.
|
||||
DefaultTimestampUTC = TimestampFormat(
|
||||
func() time.Time { return time.Now().UTC() },
|
||||
time.RFC3339Nano,
|
||||
)
|
||||
|
||||
// DefaultCaller is a Valuer that returns the file and line where the Log
|
||||
// method was invoked. It can only be used with log.With.
|
||||
DefaultCaller = Caller(3)
|
||||
)
|
||||
1
vendor/github.com/go-logfmt/logfmt/.gitignore
generated
vendored
Normal file
1
vendor/github.com/go-logfmt/logfmt/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vscode/
|
||||
82
vendor/github.com/go-logfmt/logfmt/CHANGELOG.md
generated
vendored
Normal file
82
vendor/github.com/go-logfmt/logfmt/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.6.0] - 2023-01-30
|
||||
|
||||
[0.6.0]: https://github.com/go-logfmt/logfmt/compare/v0.5.1...v0.6.0
|
||||
|
||||
### Added
|
||||
|
||||
- NewDecoderSize by [@alexanderjophus]
|
||||
|
||||
## [0.5.1] - 2021-08-18
|
||||
|
||||
[0.5.1]: https://github.com/go-logfmt/logfmt/compare/v0.5.0...v0.5.1
|
||||
|
||||
### Changed
|
||||
|
||||
- Update the `go.mod` file for Go 1.17 as described in the [Go 1.17 release
|
||||
notes](https://golang.org/doc/go1.17#go-command)
|
||||
|
||||
## [0.5.0] - 2020-01-03
|
||||
|
||||
[0.5.0]: https://github.com/go-logfmt/logfmt/compare/v0.4.0...v0.5.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Remove the dependency on github.com/kr/logfmt by [@ChrisHines]
|
||||
- Move fuzz code to github.com/go-logfmt/fuzzlogfmt by [@ChrisHines]
|
||||
|
||||
## [0.4.0] - 2018-11-21
|
||||
|
||||
[0.4.0]: https://github.com/go-logfmt/logfmt/compare/v0.3.0...v0.4.0
|
||||
|
||||
### Added
|
||||
|
||||
- Go module support by [@ChrisHines]
|
||||
- CHANGELOG by [@ChrisHines]
|
||||
|
||||
### Changed
|
||||
|
||||
- Drop invalid runes from keys instead of returning ErrInvalidKey by [@ChrisHines]
|
||||
- On panic while printing, attempt to print panic value by [@bboreham]
|
||||
|
||||
## [0.3.0] - 2016-11-15
|
||||
|
||||
[0.3.0]: https://github.com/go-logfmt/logfmt/compare/v0.2.0...v0.3.0
|
||||
|
||||
### Added
|
||||
|
||||
- Pool buffers for quoted strings and byte slices by [@nussjustin]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fuzz fix, quote invalid UTF-8 values by [@judwhite]
|
||||
|
||||
## [0.2.0] - 2016-05-08
|
||||
|
||||
[0.2.0]: https://github.com/go-logfmt/logfmt/compare/v0.1.0...v0.2.0
|
||||
|
||||
### Added
|
||||
|
||||
- Encoder.EncodeKeyvals by [@ChrisHines]
|
||||
|
||||
## [0.1.0] - 2016-03-28
|
||||
|
||||
[0.1.0]: https://github.com/go-logfmt/logfmt/commits/v0.1.0
|
||||
|
||||
### Added
|
||||
|
||||
- Encoder by [@ChrisHines]
|
||||
- Decoder by [@ChrisHines]
|
||||
- MarshalKeyvals by [@ChrisHines]
|
||||
|
||||
[@ChrisHines]: https://github.com/ChrisHines
|
||||
[@bboreham]: https://github.com/bboreham
|
||||
[@judwhite]: https://github.com/judwhite
|
||||
[@nussjustin]: https://github.com/nussjustin
|
||||
[@alexanderjophus]: https://github.com/alexanderjophus
|
||||
22
vendor/github.com/go-logfmt/logfmt/LICENSE
generated
vendored
Normal file
22
vendor/github.com/go-logfmt/logfmt/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 go-logfmt
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
41
vendor/github.com/go-logfmt/logfmt/README.md
generated
vendored
Normal file
41
vendor/github.com/go-logfmt/logfmt/README.md
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# logfmt
|
||||
|
||||
[](https://pkg.go.dev/github.com/go-logfmt/logfmt)
|
||||
[](https://goreportcard.com/report/go-logfmt/logfmt)
|
||||
[](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml)
|
||||
[](https://coveralls.io/github/go-logfmt/logfmt?branch=main)
|
||||
|
||||
Package logfmt implements utilities to marshal and unmarshal data in the [logfmt
|
||||
format][fmt]. It provides an API similar to [encoding/json][json] and
|
||||
[encoding/xml][xml].
|
||||
|
||||
[fmt]: https://brandur.org/logfmt
|
||||
[json]: https://pkg.go.dev/encoding/json
|
||||
[xml]: https://pkg.go.dev/encoding/xml
|
||||
|
||||
The logfmt format was first documented by Brandur Leach in [this
|
||||
article][origin]. The format has not been formally standardized. The most
|
||||
authoritative public specification to date has been the documentation of a Go
|
||||
Language [package][parser] written by Blake Mizerany and Keith Rarick.
|
||||
|
||||
[origin]: https://brandur.org/logfmt
|
||||
[parser]: https://pkg.go.dev/github.com/kr/logfmt
|
||||
|
||||
## Goals
|
||||
|
||||
This project attempts to conform as closely as possible to the prior art, while
|
||||
also removing ambiguity where necessary to provide well behaved encoder and
|
||||
decoder implementations.
|
||||
|
||||
## Non-goals
|
||||
|
||||
This project does not attempt to formally standardize the logfmt format. In the
|
||||
event that logfmt is standardized this project would take conforming to the
|
||||
standard as a goal.
|
||||
|
||||
## Versioning
|
||||
|
||||
This project publishes releases according to the Go language guidelines for
|
||||
[developing and publishing modules][pub].
|
||||
|
||||
[pub]: https://go.dev/doc/modules/developing
|
||||
254
vendor/github.com/go-logfmt/logfmt/decode.go
generated
vendored
Normal file
254
vendor/github.com/go-logfmt/logfmt/decode.go
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
package logfmt
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// A Decoder reads and decodes logfmt records from an input stream.
|
||||
type Decoder struct {
|
||||
pos int
|
||||
key []byte
|
||||
value []byte
|
||||
lineNum int
|
||||
s *bufio.Scanner
|
||||
err error
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder that reads from r.
|
||||
//
|
||||
// The decoder introduces its own buffering and may read data from r beyond
|
||||
// the logfmt records requested.
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
dec := &Decoder{
|
||||
s: bufio.NewScanner(r),
|
||||
}
|
||||
return dec
|
||||
}
|
||||
|
||||
// NewDecoderSize returns a new decoder that reads from r.
|
||||
//
|
||||
// The decoder introduces its own buffering and may read data from r beyond
|
||||
// the logfmt records requested.
|
||||
// The size argument specifies the size of the initial buffer that the
|
||||
// Decoder will use to read records from r.
|
||||
// If a log line is longer than the size argument, the Decoder will return
|
||||
// a bufio.ErrTooLong error.
|
||||
func NewDecoderSize(r io.Reader, size int) *Decoder {
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Buffer(make([]byte, 0, size), size)
|
||||
dec := &Decoder{
|
||||
s: scanner,
|
||||
}
|
||||
return dec
|
||||
}
|
||||
|
||||
// ScanRecord advances the Decoder to the next record, which can then be
|
||||
// parsed with the ScanKeyval method. It returns false when decoding stops,
|
||||
// either by reaching the end of the input or an error. After ScanRecord
|
||||
// returns false, the Err method will return any error that occurred during
|
||||
// decoding, except that if it was io.EOF, Err will return nil.
|
||||
func (dec *Decoder) ScanRecord() bool {
|
||||
if dec.err != nil {
|
||||
return false
|
||||
}
|
||||
if !dec.s.Scan() {
|
||||
dec.err = dec.s.Err()
|
||||
return false
|
||||
}
|
||||
dec.lineNum++
|
||||
dec.pos = 0
|
||||
return true
|
||||
}
|
||||
|
||||
// ScanKeyval advances the Decoder to the next key/value pair of the current
|
||||
// record, which can then be retrieved with the Key and Value methods. It
|
||||
// returns false when decoding stops, either by reaching the end of the
|
||||
// current record or an error.
|
||||
func (dec *Decoder) ScanKeyval() bool {
|
||||
dec.key, dec.value = nil, nil
|
||||
if dec.err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
line := dec.s.Bytes()
|
||||
|
||||
// garbage
|
||||
for p, c := range line[dec.pos:] {
|
||||
if c > ' ' {
|
||||
dec.pos += p
|
||||
goto key
|
||||
}
|
||||
}
|
||||
dec.pos = len(line)
|
||||
return false
|
||||
|
||||
key:
|
||||
const invalidKeyError = "invalid key"
|
||||
|
||||
start, multibyte := dec.pos, false
|
||||
for p, c := range line[dec.pos:] {
|
||||
switch {
|
||||
case c == '=':
|
||||
dec.pos += p
|
||||
if dec.pos > start {
|
||||
dec.key = line[start:dec.pos]
|
||||
if multibyte && bytes.ContainsRune(dec.key, utf8.RuneError) {
|
||||
dec.syntaxError(invalidKeyError)
|
||||
return false
|
||||
}
|
||||
}
|
||||
if dec.key == nil {
|
||||
dec.unexpectedByte(c)
|
||||
return false
|
||||
}
|
||||
goto equal
|
||||
case c == '"':
|
||||
dec.pos += p
|
||||
dec.unexpectedByte(c)
|
||||
return false
|
||||
case c <= ' ':
|
||||
dec.pos += p
|
||||
if dec.pos > start {
|
||||
dec.key = line[start:dec.pos]
|
||||
if multibyte && bytes.ContainsRune(dec.key, utf8.RuneError) {
|
||||
dec.syntaxError(invalidKeyError)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case c >= utf8.RuneSelf:
|
||||
multibyte = true
|
||||
}
|
||||
}
|
||||
dec.pos = len(line)
|
||||
if dec.pos > start {
|
||||
dec.key = line[start:dec.pos]
|
||||
if multibyte && bytes.ContainsRune(dec.key, utf8.RuneError) {
|
||||
dec.syntaxError(invalidKeyError)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
equal:
|
||||
dec.pos++
|
||||
if dec.pos >= len(line) {
|
||||
return true
|
||||
}
|
||||
switch c := line[dec.pos]; {
|
||||
case c <= ' ':
|
||||
return true
|
||||
case c == '"':
|
||||
goto qvalue
|
||||
}
|
||||
|
||||
// value
|
||||
start = dec.pos
|
||||
for p, c := range line[dec.pos:] {
|
||||
switch {
|
||||
case c == '=' || c == '"':
|
||||
dec.pos += p
|
||||
dec.unexpectedByte(c)
|
||||
return false
|
||||
case c <= ' ':
|
||||
dec.pos += p
|
||||
if dec.pos > start {
|
||||
dec.value = line[start:dec.pos]
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
dec.pos = len(line)
|
||||
if dec.pos > start {
|
||||
dec.value = line[start:dec.pos]
|
||||
}
|
||||
return true
|
||||
|
||||
qvalue:
|
||||
const (
|
||||
untermQuote = "unterminated quoted value"
|
||||
invalidQuote = "invalid quoted value"
|
||||
)
|
||||
|
||||
hasEsc, esc := false, false
|
||||
start = dec.pos
|
||||
for p, c := range line[dec.pos+1:] {
|
||||
switch {
|
||||
case esc:
|
||||
esc = false
|
||||
case c == '\\':
|
||||
hasEsc, esc = true, true
|
||||
case c == '"':
|
||||
dec.pos += p + 2
|
||||
if hasEsc {
|
||||
v, ok := unquoteBytes(line[start:dec.pos])
|
||||
if !ok {
|
||||
dec.syntaxError(invalidQuote)
|
||||
return false
|
||||
}
|
||||
dec.value = v
|
||||
} else {
|
||||
start++
|
||||
end := dec.pos - 1
|
||||
if end > start {
|
||||
dec.value = line[start:end]
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
dec.pos = len(line)
|
||||
dec.syntaxError(untermQuote)
|
||||
return false
|
||||
}
|
||||
|
||||
// Key returns the most recent key found by a call to ScanKeyval. The returned
|
||||
// slice may point to internal buffers and is only valid until the next call
|
||||
// to ScanRecord. It does no allocation.
|
||||
func (dec *Decoder) Key() []byte {
|
||||
return dec.key
|
||||
}
|
||||
|
||||
// Value returns the most recent value found by a call to ScanKeyval. The
|
||||
// returned slice may point to internal buffers and is only valid until the
|
||||
// next call to ScanRecord. It does no allocation when the value has no
|
||||
// escape sequences.
|
||||
func (dec *Decoder) Value() []byte {
|
||||
return dec.value
|
||||
}
|
||||
|
||||
// Err returns the first non-EOF error that was encountered by the Scanner.
|
||||
func (dec *Decoder) Err() error {
|
||||
return dec.err
|
||||
}
|
||||
|
||||
func (dec *Decoder) syntaxError(msg string) {
|
||||
dec.err = &SyntaxError{
|
||||
Msg: msg,
|
||||
Line: dec.lineNum,
|
||||
Pos: dec.pos + 1,
|
||||
}
|
||||
}
|
||||
|
||||
func (dec *Decoder) unexpectedByte(c byte) {
|
||||
dec.err = &SyntaxError{
|
||||
Msg: fmt.Sprintf("unexpected %q", c),
|
||||
Line: dec.lineNum,
|
||||
Pos: dec.pos + 1,
|
||||
}
|
||||
}
|
||||
|
||||
// A SyntaxError represents a syntax error in the logfmt input stream.
|
||||
type SyntaxError struct {
|
||||
Msg string
|
||||
Line int
|
||||
Pos int
|
||||
}
|
||||
|
||||
func (e *SyntaxError) Error() string {
|
||||
return fmt.Sprintf("logfmt syntax error at pos %d on line %d: %s", e.Pos, e.Line, e.Msg)
|
||||
}
|
||||
6
vendor/github.com/go-logfmt/logfmt/doc.go
generated
vendored
Normal file
6
vendor/github.com/go-logfmt/logfmt/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Package logfmt implements utilities to marshal and unmarshal data in the
|
||||
// logfmt format. The logfmt format records key/value pairs in a way that
|
||||
// balances readability for humans and simplicity of computer parsing. It is
|
||||
// most commonly used as a more human friendly alternative to JSON for
|
||||
// structured logging.
|
||||
package logfmt
|
||||
322
vendor/github.com/go-logfmt/logfmt/encode.go
generated
vendored
Normal file
322
vendor/github.com/go-logfmt/logfmt/encode.go
generated
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
package logfmt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// MarshalKeyvals returns the logfmt encoding of keyvals, a variadic sequence
|
||||
// of alternating keys and values.
|
||||
func MarshalKeyvals(keyvals ...interface{}) ([]byte, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
if err := NewEncoder(buf).EncodeKeyvals(keyvals...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// An Encoder writes logfmt data to an output stream.
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
scratch bytes.Buffer
|
||||
needSep bool
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{
|
||||
w: w,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
space = []byte(" ")
|
||||
equals = []byte("=")
|
||||
newline = []byte("\n")
|
||||
null = []byte("null")
|
||||
)
|
||||
|
||||
// EncodeKeyval writes the logfmt encoding of key and value to the stream. A
|
||||
// single space is written before the second and subsequent keys in a record.
|
||||
// Nothing is written if a non-nil error is returned.
|
||||
func (enc *Encoder) EncodeKeyval(key, value interface{}) error {
|
||||
enc.scratch.Reset()
|
||||
if enc.needSep {
|
||||
if _, err := enc.scratch.Write(space); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := writeKey(&enc.scratch, key); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := enc.scratch.Write(equals); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeValue(&enc.scratch, value); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := enc.w.Write(enc.scratch.Bytes())
|
||||
enc.needSep = true
|
||||
return err
|
||||
}
|
||||
|
||||
// EncodeKeyvals writes the logfmt encoding of keyvals to the stream. Keyvals
|
||||
// is a variadic sequence of alternating keys and values. Keys of unsupported
|
||||
// type are skipped along with their corresponding value. Values of
|
||||
// unsupported type or that cause a MarshalerError are replaced by their error
|
||||
// but do not cause EncodeKeyvals to return an error. If a non-nil error is
|
||||
// returned some key/value pairs may not have be written.
|
||||
func (enc *Encoder) EncodeKeyvals(keyvals ...interface{}) error {
|
||||
if len(keyvals) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(keyvals)%2 == 1 {
|
||||
keyvals = append(keyvals, nil)
|
||||
}
|
||||
for i := 0; i < len(keyvals); i += 2 {
|
||||
k, v := keyvals[i], keyvals[i+1]
|
||||
err := enc.EncodeKeyval(k, v)
|
||||
if err == ErrUnsupportedKeyType {
|
||||
continue
|
||||
}
|
||||
if _, ok := err.(*MarshalerError); ok || err == ErrUnsupportedValueType {
|
||||
v = err
|
||||
err = enc.EncodeKeyval(k, v)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalerError represents an error encountered while marshaling a value.
|
||||
type MarshalerError struct {
|
||||
Type reflect.Type
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *MarshalerError) Error() string {
|
||||
return "error marshaling value of type " + e.Type.String() + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
// ErrNilKey is returned by Marshal functions and Encoder methods if a key is
|
||||
// a nil interface or pointer value.
|
||||
var ErrNilKey = errors.New("nil key")
|
||||
|
||||
// ErrInvalidKey is returned by Marshal functions and Encoder methods if, after
|
||||
// dropping invalid runes, a key is empty.
|
||||
var ErrInvalidKey = errors.New("invalid key")
|
||||
|
||||
// ErrUnsupportedKeyType is returned by Encoder methods if a key has an
|
||||
// unsupported type.
|
||||
var ErrUnsupportedKeyType = errors.New("unsupported key type")
|
||||
|
||||
// ErrUnsupportedValueType is returned by Encoder methods if a value has an
|
||||
// unsupported type.
|
||||
var ErrUnsupportedValueType = errors.New("unsupported value type")
|
||||
|
||||
func writeKey(w io.Writer, key interface{}) error {
|
||||
if key == nil {
|
||||
return ErrNilKey
|
||||
}
|
||||
|
||||
switch k := key.(type) {
|
||||
case string:
|
||||
return writeStringKey(w, k)
|
||||
case []byte:
|
||||
if k == nil {
|
||||
return ErrNilKey
|
||||
}
|
||||
return writeBytesKey(w, k)
|
||||
case encoding.TextMarshaler:
|
||||
kb, err := safeMarshal(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if kb == nil {
|
||||
return ErrNilKey
|
||||
}
|
||||
return writeBytesKey(w, kb)
|
||||
case fmt.Stringer:
|
||||
ks, ok := safeString(k)
|
||||
if !ok {
|
||||
return ErrNilKey
|
||||
}
|
||||
return writeStringKey(w, ks)
|
||||
default:
|
||||
rkey := reflect.ValueOf(key)
|
||||
switch rkey.Kind() {
|
||||
case reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Struct:
|
||||
return ErrUnsupportedKeyType
|
||||
case reflect.Ptr:
|
||||
if rkey.IsNil() {
|
||||
return ErrNilKey
|
||||
}
|
||||
return writeKey(w, rkey.Elem().Interface())
|
||||
}
|
||||
return writeStringKey(w, fmt.Sprint(k))
|
||||
}
|
||||
}
|
||||
|
||||
// keyRuneFilter returns r for all valid key runes, and -1 for all invalid key
|
||||
// runes. When used as the mapping function for strings.Map and bytes.Map
|
||||
// functions it causes them to remove invalid key runes from strings or byte
|
||||
// slices respectively.
|
||||
func keyRuneFilter(r rune) rune {
|
||||
if r <= ' ' || r == '=' || r == '"' || r == utf8.RuneError {
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func writeStringKey(w io.Writer, key string) error {
|
||||
k := strings.Map(keyRuneFilter, key)
|
||||
if k == "" {
|
||||
return ErrInvalidKey
|
||||
}
|
||||
_, err := io.WriteString(w, k)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeBytesKey(w io.Writer, key []byte) error {
|
||||
k := bytes.Map(keyRuneFilter, key)
|
||||
if len(k) == 0 {
|
||||
return ErrInvalidKey
|
||||
}
|
||||
_, err := w.Write(k)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeValue(w io.Writer, value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
return writeBytesValue(w, null)
|
||||
case string:
|
||||
return writeStringValue(w, v, true)
|
||||
case []byte:
|
||||
return writeBytesValue(w, v)
|
||||
case encoding.TextMarshaler:
|
||||
vb, err := safeMarshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if vb == nil {
|
||||
vb = null
|
||||
}
|
||||
return writeBytesValue(w, vb)
|
||||
case error:
|
||||
se, ok := safeError(v)
|
||||
return writeStringValue(w, se, ok)
|
||||
case fmt.Stringer:
|
||||
ss, ok := safeString(v)
|
||||
return writeStringValue(w, ss, ok)
|
||||
default:
|
||||
rvalue := reflect.ValueOf(value)
|
||||
switch rvalue.Kind() {
|
||||
case reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Struct:
|
||||
return ErrUnsupportedValueType
|
||||
case reflect.Ptr:
|
||||
if rvalue.IsNil() {
|
||||
return writeBytesValue(w, null)
|
||||
}
|
||||
return writeValue(w, rvalue.Elem().Interface())
|
||||
}
|
||||
return writeStringValue(w, fmt.Sprint(v), true)
|
||||
}
|
||||
}
|
||||
|
||||
func needsQuotedValueRune(r rune) bool {
|
||||
return r <= ' ' || r == '=' || r == '"' || r == utf8.RuneError
|
||||
}
|
||||
|
||||
func writeStringValue(w io.Writer, value string, ok bool) error {
|
||||
var err error
|
||||
if ok && value == "null" {
|
||||
_, err = io.WriteString(w, `"null"`)
|
||||
} else if strings.IndexFunc(value, needsQuotedValueRune) != -1 {
|
||||
_, err = writeQuotedString(w, value)
|
||||
} else {
|
||||
_, err = io.WriteString(w, value)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func writeBytesValue(w io.Writer, value []byte) error {
|
||||
var err error
|
||||
if bytes.IndexFunc(value, needsQuotedValueRune) != -1 {
|
||||
_, err = writeQuotedBytes(w, value)
|
||||
} else {
|
||||
_, err = w.Write(value)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// EndRecord writes a newline character to the stream and resets the encoder
|
||||
// to the beginning of a new record.
|
||||
func (enc *Encoder) EndRecord() error {
|
||||
_, err := enc.w.Write(newline)
|
||||
if err == nil {
|
||||
enc.needSep = false
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Reset resets the encoder to the beginning of a new record.
|
||||
func (enc *Encoder) Reset() {
|
||||
enc.needSep = false
|
||||
}
|
||||
|
||||
func safeError(err error) (s string, ok bool) {
|
||||
defer func() {
|
||||
if panicVal := recover(); panicVal != nil {
|
||||
if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
s, ok = "null", false
|
||||
} else {
|
||||
s, ok = fmt.Sprintf("PANIC:%v", panicVal), false
|
||||
}
|
||||
}
|
||||
}()
|
||||
s, ok = err.Error(), true
|
||||
return
|
||||
}
|
||||
|
||||
func safeString(str fmt.Stringer) (s string, ok bool) {
|
||||
defer func() {
|
||||
if panicVal := recover(); panicVal != nil {
|
||||
if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
s, ok = "null", false
|
||||
} else {
|
||||
s, ok = fmt.Sprintf("PANIC:%v", panicVal), true
|
||||
}
|
||||
}
|
||||
}()
|
||||
s, ok = str.String(), true
|
||||
return
|
||||
}
|
||||
|
||||
func safeMarshal(tm encoding.TextMarshaler) (b []byte, err error) {
|
||||
defer func() {
|
||||
if panicVal := recover(); panicVal != nil {
|
||||
if v := reflect.ValueOf(tm); v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
b, err = nil, nil
|
||||
} else {
|
||||
b, err = nil, fmt.Errorf("panic when marshalling: %s", panicVal)
|
||||
}
|
||||
}
|
||||
}()
|
||||
b, err = tm.MarshalText()
|
||||
if err != nil {
|
||||
return nil, &MarshalerError{
|
||||
Type: reflect.TypeOf(tm),
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
277
vendor/github.com/go-logfmt/logfmt/jsonstring.go
generated
vendored
Normal file
277
vendor/github.com/go-logfmt/logfmt/jsonstring.go
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
package logfmt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strconv"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Taken from Go's encoding/json and modified for use here.
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
var hex = "0123456789abcdef"
|
||||
|
||||
var bufferPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &bytes.Buffer{}
|
||||
},
|
||||
}
|
||||
|
||||
func getBuffer() *bytes.Buffer {
|
||||
return bufferPool.Get().(*bytes.Buffer)
|
||||
}
|
||||
|
||||
func poolBuffer(buf *bytes.Buffer) {
|
||||
buf.Reset()
|
||||
bufferPool.Put(buf)
|
||||
}
|
||||
|
||||
// NOTE: keep in sync with writeQuotedBytes below.
|
||||
func writeQuotedString(w io.Writer, s string) (int, error) {
|
||||
buf := getBuffer()
|
||||
buf.WriteByte('"')
|
||||
start := 0
|
||||
for i := 0; i < len(s); {
|
||||
if b := s[i]; b < utf8.RuneSelf {
|
||||
if 0x20 <= b && b != '\\' && b != '"' {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if start < i {
|
||||
buf.WriteString(s[start:i])
|
||||
}
|
||||
switch b {
|
||||
case '\\', '"':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte(b)
|
||||
case '\n':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('n')
|
||||
case '\r':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('r')
|
||||
case '\t':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('t')
|
||||
default:
|
||||
// This encodes bytes < 0x20 except for \n, \r, and \t.
|
||||
buf.WriteString(`\u00`)
|
||||
buf.WriteByte(hex[b>>4])
|
||||
buf.WriteByte(hex[b&0xF])
|
||||
}
|
||||
i++
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
c, size := utf8.DecodeRuneInString(s[i:])
|
||||
if c == utf8.RuneError {
|
||||
if start < i {
|
||||
buf.WriteString(s[start:i])
|
||||
}
|
||||
buf.WriteString(`\ufffd`)
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
i += size
|
||||
}
|
||||
if start < len(s) {
|
||||
buf.WriteString(s[start:])
|
||||
}
|
||||
buf.WriteByte('"')
|
||||
n, err := w.Write(buf.Bytes())
|
||||
poolBuffer(buf)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// NOTE: keep in sync with writeQuoteString above.
|
||||
func writeQuotedBytes(w io.Writer, s []byte) (int, error) {
|
||||
buf := getBuffer()
|
||||
buf.WriteByte('"')
|
||||
start := 0
|
||||
for i := 0; i < len(s); {
|
||||
if b := s[i]; b < utf8.RuneSelf {
|
||||
if 0x20 <= b && b != '\\' && b != '"' {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if start < i {
|
||||
buf.Write(s[start:i])
|
||||
}
|
||||
switch b {
|
||||
case '\\', '"':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte(b)
|
||||
case '\n':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('n')
|
||||
case '\r':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('r')
|
||||
case '\t':
|
||||
buf.WriteByte('\\')
|
||||
buf.WriteByte('t')
|
||||
default:
|
||||
// This encodes bytes < 0x20 except for \n, \r, and \t.
|
||||
buf.WriteString(`\u00`)
|
||||
buf.WriteByte(hex[b>>4])
|
||||
buf.WriteByte(hex[b&0xF])
|
||||
}
|
||||
i++
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
c, size := utf8.DecodeRune(s[i:])
|
||||
if c == utf8.RuneError {
|
||||
if start < i {
|
||||
buf.Write(s[start:i])
|
||||
}
|
||||
buf.WriteString(`\ufffd`)
|
||||
i += size
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
i += size
|
||||
}
|
||||
if start < len(s) {
|
||||
buf.Write(s[start:])
|
||||
}
|
||||
buf.WriteByte('"')
|
||||
n, err := w.Write(buf.Bytes())
|
||||
poolBuffer(buf)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
|
||||
// or it returns -1.
|
||||
func getu4(s []byte) rune {
|
||||
if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
|
||||
return -1
|
||||
}
|
||||
r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
return rune(r)
|
||||
}
|
||||
|
||||
func unquoteBytes(s []byte) (t []byte, ok bool) {
|
||||
if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
|
||||
return
|
||||
}
|
||||
s = s[1 : len(s)-1]
|
||||
|
||||
// Check for unusual characters. If there are none,
|
||||
// then no unquoting is needed, so return a slice of the
|
||||
// original bytes.
|
||||
r := 0
|
||||
for r < len(s) {
|
||||
c := s[r]
|
||||
if c == '\\' || c == '"' || c < ' ' {
|
||||
break
|
||||
}
|
||||
if c < utf8.RuneSelf {
|
||||
r++
|
||||
continue
|
||||
}
|
||||
rr, size := utf8.DecodeRune(s[r:])
|
||||
if rr == utf8.RuneError {
|
||||
break
|
||||
}
|
||||
r += size
|
||||
}
|
||||
if r == len(s) {
|
||||
return s, true
|
||||
}
|
||||
|
||||
b := make([]byte, len(s)+2*utf8.UTFMax)
|
||||
w := copy(b, s[0:r])
|
||||
for r < len(s) {
|
||||
// Out of room? Can only happen if s is full of
|
||||
// malformed UTF-8 and we're replacing each
|
||||
// byte with RuneError.
|
||||
if w >= len(b)-2*utf8.UTFMax {
|
||||
nb := make([]byte, (len(b)+utf8.UTFMax)*2)
|
||||
copy(nb, b[0:w])
|
||||
b = nb
|
||||
}
|
||||
switch c := s[r]; {
|
||||
case c == '\\':
|
||||
r++
|
||||
if r >= len(s) {
|
||||
return
|
||||
}
|
||||
switch s[r] {
|
||||
default:
|
||||
return
|
||||
case '"', '\\', '/', '\'':
|
||||
b[w] = s[r]
|
||||
r++
|
||||
w++
|
||||
case 'b':
|
||||
b[w] = '\b'
|
||||
r++
|
||||
w++
|
||||
case 'f':
|
||||
b[w] = '\f'
|
||||
r++
|
||||
w++
|
||||
case 'n':
|
||||
b[w] = '\n'
|
||||
r++
|
||||
w++
|
||||
case 'r':
|
||||
b[w] = '\r'
|
||||
r++
|
||||
w++
|
||||
case 't':
|
||||
b[w] = '\t'
|
||||
r++
|
||||
w++
|
||||
case 'u':
|
||||
r--
|
||||
rr := getu4(s[r:])
|
||||
if rr < 0 {
|
||||
return
|
||||
}
|
||||
r += 6
|
||||
if utf16.IsSurrogate(rr) {
|
||||
rr1 := getu4(s[r:])
|
||||
if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
|
||||
// A valid pair; consume.
|
||||
r += 6
|
||||
w += utf8.EncodeRune(b[w:], dec)
|
||||
break
|
||||
}
|
||||
// Invalid surrogate; fall back to replacement rune.
|
||||
rr = unicode.ReplacementChar
|
||||
}
|
||||
w += utf8.EncodeRune(b[w:], rr)
|
||||
}
|
||||
|
||||
// Quote, control characters are invalid.
|
||||
case c == '"', c < ' ':
|
||||
return
|
||||
|
||||
// ASCII
|
||||
case c < utf8.RuneSelf:
|
||||
b[w] = c
|
||||
r++
|
||||
w++
|
||||
|
||||
// Coerce to well-formed UTF-8.
|
||||
default:
|
||||
rr, size := utf8.DecodeRune(s[r:])
|
||||
r += size
|
||||
w += utf8.EncodeRune(b[w:], rr)
|
||||
}
|
||||
}
|
||||
return b[0:w], true
|
||||
}
|
||||
191
vendor/github.com/golang/groupcache/LICENSE
generated
vendored
Normal file
191
vendor/github.com/golang/groupcache/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
"submitted" means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same "printed page" as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
133
vendor/github.com/golang/groupcache/lru/lru.go
generated
vendored
Normal file
133
vendor/github.com/golang/groupcache/lru/lru.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright 2013 Google Inc.
|
||||
|
||||
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 lru implements an LRU cache.
|
||||
package lru
|
||||
|
||||
import "container/list"
|
||||
|
||||
// Cache is an LRU cache. It is not safe for concurrent access.
|
||||
type Cache struct {
|
||||
// MaxEntries is the maximum number of cache entries before
|
||||
// an item is evicted. Zero means no limit.
|
||||
MaxEntries int
|
||||
|
||||
// OnEvicted optionally specifies a callback function to be
|
||||
// executed when an entry is purged from the cache.
|
||||
OnEvicted func(key Key, value interface{})
|
||||
|
||||
ll *list.List
|
||||
cache map[interface{}]*list.Element
|
||||
}
|
||||
|
||||
// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
|
||||
type Key interface{}
|
||||
|
||||
type entry struct {
|
||||
key Key
|
||||
value interface{}
|
||||
}
|
||||
|
||||
// New creates a new Cache.
|
||||
// If maxEntries is zero, the cache has no limit and it's assumed
|
||||
// that eviction is done by the caller.
|
||||
func New(maxEntries int) *Cache {
|
||||
return &Cache{
|
||||
MaxEntries: maxEntries,
|
||||
ll: list.New(),
|
||||
cache: make(map[interface{}]*list.Element),
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds a value to the cache.
|
||||
func (c *Cache) Add(key Key, value interface{}) {
|
||||
if c.cache == nil {
|
||||
c.cache = make(map[interface{}]*list.Element)
|
||||
c.ll = list.New()
|
||||
}
|
||||
if ee, ok := c.cache[key]; ok {
|
||||
c.ll.MoveToFront(ee)
|
||||
ee.Value.(*entry).value = value
|
||||
return
|
||||
}
|
||||
ele := c.ll.PushFront(&entry{key, value})
|
||||
c.cache[key] = ele
|
||||
if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
|
||||
c.RemoveOldest()
|
||||
}
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
|
||||
if c.cache == nil {
|
||||
return
|
||||
}
|
||||
if ele, hit := c.cache[key]; hit {
|
||||
c.ll.MoveToFront(ele)
|
||||
return ele.Value.(*entry).value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache.
|
||||
func (c *Cache) Remove(key Key) {
|
||||
if c.cache == nil {
|
||||
return
|
||||
}
|
||||
if ele, hit := c.cache[key]; hit {
|
||||
c.removeElement(ele)
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveOldest removes the oldest item from the cache.
|
||||
func (c *Cache) RemoveOldest() {
|
||||
if c.cache == nil {
|
||||
return
|
||||
}
|
||||
ele := c.ll.Back()
|
||||
if ele != nil {
|
||||
c.removeElement(ele)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) removeElement(e *list.Element) {
|
||||
c.ll.Remove(e)
|
||||
kv := e.Value.(*entry)
|
||||
delete(c.cache, kv.key)
|
||||
if c.OnEvicted != nil {
|
||||
c.OnEvicted(kv.key, kv.value)
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *Cache) Len() int {
|
||||
if c.cache == nil {
|
||||
return 0
|
||||
}
|
||||
return c.ll.Len()
|
||||
}
|
||||
|
||||
// Clear purges all stored items from the cache.
|
||||
func (c *Cache) Clear() {
|
||||
if c.OnEvicted != nil {
|
||||
for _, e := range c.cache {
|
||||
kv := e.Value.(*entry)
|
||||
c.OnEvicted(kv.key, kv.value)
|
||||
}
|
||||
}
|
||||
c.ll = nil
|
||||
c.cache = nil
|
||||
}
|
||||
3
vendor/github.com/golang/protobuf/AUTHORS
generated
vendored
Normal file
3
vendor/github.com/golang/protobuf/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
3
vendor/github.com/golang/protobuf/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/github.com/golang/protobuf/CONTRIBUTORS
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
28
vendor/github.com/golang/protobuf/LICENSE
generated
vendored
Normal file
28
vendor/github.com/golang/protobuf/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
Copyright 2010 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
62
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
Normal file
62
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/empty/empty.proto
|
||||
|
||||
package empty
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// Symbols defined in public import of google/protobuf/empty.proto.
|
||||
|
||||
type Empty = emptypb.Empty
|
||||
|
||||
var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{
|
||||
0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
|
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{}
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() }
|
||||
func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() {
|
||||
if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes,
|
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs,
|
||||
}.Build()
|
||||
File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil
|
||||
}
|
||||
2
vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
generated
vendored
2
vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
generated
vendored
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"v2": "2.14.1"
|
||||
"v2": "2.13.0"
|
||||
}
|
||||
|
||||
19
vendor/github.com/googleapis/gax-go/v2/CHANGES.md
generated
vendored
19
vendor/github.com/googleapis/gax-go/v2/CHANGES.md
generated
vendored
@@ -1,24 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [2.14.1](https://github.com/googleapis/gax-go/compare/v2.14.0...v2.14.1) (2024-12-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update golang.org/x/net to v0.33.0 ([#391](https://github.com/googleapis/gax-go/issues/391)) ([547a5b4](https://github.com/googleapis/gax-go/commit/547a5b43aa6f376f71242da9f18e65fbdfb342f6))
|
||||
|
||||
|
||||
### Documentation
|
||||
|
||||
* fix godoc to refer to the proper envvar ([#387](https://github.com/googleapis/gax-go/issues/387)) ([dc6baf7](https://github.com/googleapis/gax-go/commit/dc6baf75c1a737233739630b5af6c9759f08abcd))
|
||||
|
||||
## [2.14.0](https://github.com/googleapis/gax-go/compare/v2.13.0...v2.14.0) (2024-11-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **internallog:** add a logging support package ([#380](https://github.com/googleapis/gax-go/issues/380)) ([c877470](https://github.com/googleapis/gax-go/commit/c87747098135631a3de5865ed03aaf2c79fd9319))
|
||||
|
||||
## [2.13.0](https://github.com/googleapis/gax-go/compare/v2.12.5...v2.13.0) (2024-07-22)
|
||||
|
||||
|
||||
|
||||
2
vendor/github.com/googleapis/gax-go/v2/internal/version.go
generated
vendored
2
vendor/github.com/googleapis/gax-go/v2/internal/version.go
generated
vendored
@@ -30,4 +30,4 @@
|
||||
package internal
|
||||
|
||||
// Version is the current tagged release of the library.
|
||||
const Version = "2.14.1"
|
||||
const Version = "2.13.0"
|
||||
|
||||
134
vendor/github.com/googleapis/gax-go/v2/internallog/internal/internal.go
generated
vendored
134
vendor/github.com/googleapis/gax-go/v2/internallog/internal/internal.go
generated
vendored
@@ -1,134 +0,0 @@
|
||||
// Copyright 2024, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Package internal provides some common logic and types to other logging
|
||||
// sub-packages.
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// LoggingLevelEnvVar is the environment variable used to enable logging
|
||||
// at a particular level.
|
||||
LoggingLevelEnvVar = "GOOGLE_SDK_GO_LOGGING_LEVEL"
|
||||
|
||||
googLvlKey = "severity"
|
||||
googMsgKey = "message"
|
||||
googSourceKey = "sourceLocation"
|
||||
googTimeKey = "timestamp"
|
||||
)
|
||||
|
||||
// NewLoggerWithWriter is exposed for testing.
|
||||
func NewLoggerWithWriter(w io.Writer) *slog.Logger {
|
||||
lvl, loggingEnabled := checkLoggingLevel()
|
||||
if !loggingEnabled {
|
||||
return slog.New(noOpHandler{})
|
||||
}
|
||||
return slog.New(newGCPSlogHandler(lvl, w))
|
||||
}
|
||||
|
||||
// checkLoggingLevel returned the configured logging level and whether or not
|
||||
// logging is enabled.
|
||||
func checkLoggingLevel() (slog.Leveler, bool) {
|
||||
sLevel := strings.ToLower(os.Getenv(LoggingLevelEnvVar))
|
||||
var level slog.Level
|
||||
switch sLevel {
|
||||
case "debug":
|
||||
level = slog.LevelDebug
|
||||
case "info":
|
||||
level = slog.LevelInfo
|
||||
case "warn":
|
||||
level = slog.LevelWarn
|
||||
case "error":
|
||||
level = slog.LevelError
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
return level, true
|
||||
}
|
||||
|
||||
// newGCPSlogHandler returns a Handler that is configured to output in a JSON
|
||||
// format with well-known keys. For more information on this format see
|
||||
// https://cloud.google.com/logging/docs/agent/logging/configuration#special-fields.
|
||||
func newGCPSlogHandler(lvl slog.Leveler, w io.Writer) slog.Handler {
|
||||
return slog.NewJSONHandler(w, &slog.HandlerOptions{
|
||||
Level: lvl,
|
||||
ReplaceAttr: replaceAttr,
|
||||
})
|
||||
}
|
||||
|
||||
// replaceAttr remaps default Go logging keys to match what is expected in
|
||||
// cloud logging.
|
||||
func replaceAttr(groups []string, a slog.Attr) slog.Attr {
|
||||
if groups == nil {
|
||||
if a.Key == slog.LevelKey {
|
||||
a.Key = googLvlKey
|
||||
return a
|
||||
} else if a.Key == slog.MessageKey {
|
||||
a.Key = googMsgKey
|
||||
return a
|
||||
} else if a.Key == slog.SourceKey {
|
||||
a.Key = googSourceKey
|
||||
return a
|
||||
} else if a.Key == slog.TimeKey {
|
||||
a.Key = googTimeKey
|
||||
if a.Value.Kind() == slog.KindTime {
|
||||
a.Value = slog.StringValue(a.Value.Time().Format(time.RFC3339))
|
||||
}
|
||||
return a
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// The handler returned if logging is not enabled.
|
||||
type noOpHandler struct{}
|
||||
|
||||
func (h noOpHandler) Enabled(_ context.Context, _ slog.Level) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (h noOpHandler) Handle(_ context.Context, _ slog.Record) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h noOpHandler) WithAttrs(_ []slog.Attr) slog.Handler {
|
||||
return h
|
||||
}
|
||||
|
||||
func (h noOpHandler) WithGroup(_ string) slog.Handler {
|
||||
return h
|
||||
}
|
||||
154
vendor/github.com/googleapis/gax-go/v2/internallog/internallog.go
generated
vendored
154
vendor/github.com/googleapis/gax-go/v2/internallog/internallog.go
generated
vendored
@@ -1,154 +0,0 @@
|
||||
// Copyright 2024, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Package internallog in intended for internal use by generated clients only.
|
||||
package internallog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/googleapis/gax-go/v2/internallog/internal"
|
||||
)
|
||||
|
||||
// New returns a new [slog.Logger] default logger, or the provided logger if
|
||||
// non-nil. The returned logger will be a no-op logger unless the environment
|
||||
// variable GOOGLE_SDK_GO_LOGGING_LEVEL is set.
|
||||
func New(l *slog.Logger) *slog.Logger {
|
||||
if l != nil {
|
||||
return l
|
||||
}
|
||||
return internal.NewLoggerWithWriter(os.Stderr)
|
||||
}
|
||||
|
||||
// HTTPRequest returns a lazily evaluated [slog.LogValuer] for a
|
||||
// [http.Request] and the associated body.
|
||||
func HTTPRequest(req *http.Request, body []byte) slog.LogValuer {
|
||||
return &request{
|
||||
req: req,
|
||||
payload: body,
|
||||
}
|
||||
}
|
||||
|
||||
type request struct {
|
||||
req *http.Request
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func (r *request) LogValue() slog.Value {
|
||||
if r == nil || r.req == nil {
|
||||
return slog.Value{}
|
||||
}
|
||||
var groupValueAttrs []slog.Attr
|
||||
groupValueAttrs = append(groupValueAttrs, slog.String("method", r.req.Method))
|
||||
groupValueAttrs = append(groupValueAttrs, slog.String("url", r.req.URL.String()))
|
||||
|
||||
var headerAttr []slog.Attr
|
||||
for k, val := range r.req.Header {
|
||||
headerAttr = append(headerAttr, slog.String(k, strings.Join(val, ",")))
|
||||
}
|
||||
if len(headerAttr) > 0 {
|
||||
groupValueAttrs = append(groupValueAttrs, slog.Any("headers", headerAttr))
|
||||
}
|
||||
|
||||
if len(r.payload) > 0 {
|
||||
if attr, ok := processPayload(r.payload); ok {
|
||||
groupValueAttrs = append(groupValueAttrs, attr)
|
||||
}
|
||||
}
|
||||
return slog.GroupValue(groupValueAttrs...)
|
||||
}
|
||||
|
||||
// HTTPResponse returns a lazily evaluated [slog.LogValuer] for a
|
||||
// [http.Response] and the associated body.
|
||||
func HTTPResponse(resp *http.Response, body []byte) slog.LogValuer {
|
||||
return &response{
|
||||
resp: resp,
|
||||
payload: body,
|
||||
}
|
||||
}
|
||||
|
||||
type response struct {
|
||||
resp *http.Response
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func (r *response) LogValue() slog.Value {
|
||||
if r == nil {
|
||||
return slog.Value{}
|
||||
}
|
||||
var groupValueAttrs []slog.Attr
|
||||
groupValueAttrs = append(groupValueAttrs, slog.String("status", fmt.Sprint(r.resp.StatusCode)))
|
||||
|
||||
var headerAttr []slog.Attr
|
||||
for k, val := range r.resp.Header {
|
||||
headerAttr = append(headerAttr, slog.String(k, strings.Join(val, ",")))
|
||||
}
|
||||
if len(headerAttr) > 0 {
|
||||
groupValueAttrs = append(groupValueAttrs, slog.Any("headers", headerAttr))
|
||||
}
|
||||
|
||||
if len(r.payload) > 0 {
|
||||
if attr, ok := processPayload(r.payload); ok {
|
||||
groupValueAttrs = append(groupValueAttrs, attr)
|
||||
}
|
||||
}
|
||||
return slog.GroupValue(groupValueAttrs...)
|
||||
}
|
||||
|
||||
func processPayload(payload []byte) (slog.Attr, bool) {
|
||||
peekChar := payload[0]
|
||||
if peekChar == '{' {
|
||||
// JSON object
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal(payload, &m); err == nil {
|
||||
return slog.Any("payload", m), true
|
||||
}
|
||||
} else if peekChar == '[' {
|
||||
// JSON array
|
||||
var m []any
|
||||
if err := json.Unmarshal(payload, &m); err == nil {
|
||||
return slog.Any("payload", m), true
|
||||
}
|
||||
} else {
|
||||
// Everything else
|
||||
buf := &bytes.Buffer{}
|
||||
if err := json.Compact(buf, payload); err != nil {
|
||||
// Write raw payload incase of error
|
||||
buf.Write(payload)
|
||||
}
|
||||
return slog.String("payload", buf.String()), true
|
||||
}
|
||||
return slog.Attr{}, false
|
||||
}
|
||||
1
vendor/github.com/hashicorp/go-hclog/.gitignore
generated
vendored
Normal file
1
vendor/github.com/hashicorp/go-hclog/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.idea*
|
||||
19
vendor/github.com/hashicorp/go-hclog/LICENSE
generated
vendored
Normal file
19
vendor/github.com/hashicorp/go-hclog/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017 HashiCorp, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
149
vendor/github.com/hashicorp/go-hclog/README.md
generated
vendored
Normal file
149
vendor/github.com/hashicorp/go-hclog/README.md
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
# go-hclog
|
||||
|
||||
[][godocs]
|
||||
|
||||
[godocs]: https://godoc.org/github.com/hashicorp/go-hclog
|
||||
|
||||
`go-hclog` is a package for Go that provides a simple key/value logging
|
||||
interface for use in development and production environments.
|
||||
|
||||
It provides logging levels that provide decreased output based upon the
|
||||
desired amount of output, unlike the standard library `log` package.
|
||||
|
||||
It provides `Printf` style logging of values via `hclog.Fmt()`.
|
||||
|
||||
It provides a human readable output mode for use in development as well as
|
||||
JSON output mode for production.
|
||||
|
||||
## Stability Note
|
||||
|
||||
This library has reached 1.0 stability. Its API can be considered solidified
|
||||
and promised through future versions.
|
||||
|
||||
## Installation and Docs
|
||||
|
||||
Install using `go get github.com/hashicorp/go-hclog`.
|
||||
|
||||
Full documentation is available at
|
||||
http://godoc.org/github.com/hashicorp/go-hclog
|
||||
|
||||
## Usage
|
||||
|
||||
### Use the global logger
|
||||
|
||||
```go
|
||||
hclog.Default().Info("hello world")
|
||||
```
|
||||
|
||||
```text
|
||||
2017-07-05T16:15:55.167-0700 [INFO ] hello world
|
||||
```
|
||||
|
||||
(Note timestamps are removed in future examples for brevity.)
|
||||
|
||||
### Create a new logger
|
||||
|
||||
```go
|
||||
appLogger := hclog.New(&hclog.LoggerOptions{
|
||||
Name: "my-app",
|
||||
Level: hclog.LevelFromString("DEBUG"),
|
||||
})
|
||||
```
|
||||
|
||||
### Emit an Info level message with 2 key/value pairs
|
||||
|
||||
```go
|
||||
input := "5.5"
|
||||
_, err := strconv.ParseInt(input, 10, 32)
|
||||
if err != nil {
|
||||
appLogger.Info("Invalid input for ParseInt", "input", input, "error", err)
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
... [INFO ] my-app: Invalid input for ParseInt: input=5.5 error="strconv.ParseInt: parsing "5.5": invalid syntax"
|
||||
```
|
||||
|
||||
### Create a new Logger for a major subsystem
|
||||
|
||||
```go
|
||||
subsystemLogger := appLogger.Named("transport")
|
||||
subsystemLogger.Info("we are transporting something")
|
||||
```
|
||||
|
||||
```text
|
||||
... [INFO ] my-app.transport: we are transporting something
|
||||
```
|
||||
|
||||
Notice that logs emitted by `subsystemLogger` contain `my-app.transport`,
|
||||
reflecting both the application and subsystem names.
|
||||
|
||||
### Create a new Logger with fixed key/value pairs
|
||||
|
||||
Using `With()` will include a specific key-value pair in all messages emitted
|
||||
by that logger.
|
||||
|
||||
```go
|
||||
requestID := "5fb446b6-6eba-821d-df1b-cd7501b6a363"
|
||||
requestLogger := subsystemLogger.With("request", requestID)
|
||||
requestLogger.Info("we are transporting a request")
|
||||
```
|
||||
|
||||
```text
|
||||
... [INFO ] my-app.transport: we are transporting a request: request=5fb446b6-6eba-821d-df1b-cd7501b6a363
|
||||
```
|
||||
|
||||
This allows sub Loggers to be context specific without having to thread that
|
||||
into all the callers.
|
||||
|
||||
### Using `hclog.Fmt()`
|
||||
|
||||
```go
|
||||
totalBandwidth := 200
|
||||
appLogger.Info("total bandwidth exceeded", "bandwidth", hclog.Fmt("%d GB/s", totalBandwidth))
|
||||
```
|
||||
|
||||
```text
|
||||
... [INFO ] my-app: total bandwidth exceeded: bandwidth="200 GB/s"
|
||||
```
|
||||
|
||||
### Use this with code that uses the standard library logger
|
||||
|
||||
If you want to use the standard library's `log.Logger` interface you can wrap
|
||||
`hclog.Logger` by calling the `StandardLogger()` method. This allows you to use
|
||||
it with the familiar `Println()`, `Printf()`, etc. For example:
|
||||
|
||||
```go
|
||||
stdLogger := appLogger.StandardLogger(&hclog.StandardLoggerOptions{
|
||||
InferLevels: true,
|
||||
})
|
||||
// Printf() is provided by stdlib log.Logger interface, not hclog.Logger
|
||||
stdLogger.Printf("[DEBUG] %+v", stdLogger)
|
||||
```
|
||||
|
||||
```text
|
||||
... [DEBUG] my-app: &{mu:{state:0 sema:0} prefix: flag:0 out:0xc42000a0a0 buf:[]}
|
||||
```
|
||||
|
||||
Alternatively, you may configure the system-wide logger:
|
||||
|
||||
```go
|
||||
// log the standard logger from 'import "log"'
|
||||
log.SetOutput(appLogger.StandardWriter(&hclog.StandardLoggerOptions{InferLevels: true}))
|
||||
log.SetPrefix("")
|
||||
log.SetFlags(0)
|
||||
|
||||
log.Printf("[DEBUG] %d", 42)
|
||||
```
|
||||
|
||||
```text
|
||||
... [DEBUG] my-app: 42
|
||||
```
|
||||
|
||||
Notice that if `appLogger` is initialized with the `INFO` log level, _and_ you
|
||||
specify `InferLevels: true`, you will not see any output here. You must change
|
||||
`appLogger` to `DEBUG` to see output. See the docs for more information.
|
||||
|
||||
If the log lines start with a timestamp you can use the
|
||||
`InferLevelsWithTimestamp` option to try and ignore them. Please note that in order
|
||||
for `InferLevelsWithTimestamp` to be relevant, `InferLevels` must be set to `true`.
|
||||
44
vendor/github.com/hashicorp/go-hclog/colorize_unix.go
generated
vendored
Normal file
44
vendor/github.com/hashicorp/go-hclog/colorize_unix.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
// hasFD is used to check if the writer has an Fd value to check
|
||||
// if it's a terminal.
|
||||
type hasFD interface {
|
||||
Fd() uintptr
|
||||
}
|
||||
|
||||
// setColorization will mutate the values of this logger
|
||||
// to appropriately configure colorization options. It provides
|
||||
// a wrapper to the output stream on Windows systems.
|
||||
func (l *intLogger) setColorization(opts *LoggerOptions) {
|
||||
if opts.Color != AutoColor {
|
||||
return
|
||||
}
|
||||
|
||||
if sc, ok := l.writer.w.(SupportsColor); ok {
|
||||
if !sc.SupportsColor() {
|
||||
l.headerColor = ColorOff
|
||||
l.writer.color = ColorOff
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fi, ok := l.writer.w.(hasFD)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if !isatty.IsTerminal(fi.Fd()) {
|
||||
l.headerColor = ColorOff
|
||||
l.writer.color = ColorOff
|
||||
}
|
||||
}
|
||||
41
vendor/github.com/hashicorp/go-hclog/colorize_windows.go
generated
vendored
Normal file
41
vendor/github.com/hashicorp/go-hclog/colorize_windows.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
colorable "github.com/mattn/go-colorable"
|
||||
)
|
||||
|
||||
// setColorization will mutate the values of this logger
|
||||
// to appropriately configure colorization options. It provides
|
||||
// a wrapper to the output stream on Windows systems.
|
||||
func (l *intLogger) setColorization(opts *LoggerOptions) {
|
||||
if opts.Color == ColorOff {
|
||||
return
|
||||
}
|
||||
|
||||
fi, ok := l.writer.w.(*os.File)
|
||||
if !ok {
|
||||
l.writer.color = ColorOff
|
||||
l.headerColor = ColorOff
|
||||
return
|
||||
}
|
||||
|
||||
cfi := colorable.NewColorable(fi)
|
||||
|
||||
// NewColorable detects if color is possible and if it's not, then it
|
||||
// returns the original value. So we can test if we got the original
|
||||
// value back to know if color is possible.
|
||||
if cfi == fi {
|
||||
l.writer.color = ColorOff
|
||||
l.headerColor = ColorOff
|
||||
} else {
|
||||
l.writer.w = cfi
|
||||
}
|
||||
}
|
||||
41
vendor/github.com/hashicorp/go-hclog/context.go
generated
vendored
Normal file
41
vendor/github.com/hashicorp/go-hclog/context.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// WithContext inserts a logger into the context and is retrievable
|
||||
// with FromContext. The optional args can be set with the same syntax as
|
||||
// Logger.With to set fields on the inserted logger. This will not modify
|
||||
// the logger argument in-place.
|
||||
func WithContext(ctx context.Context, logger Logger, args ...interface{}) context.Context {
|
||||
// While we could call logger.With even with zero args, we have this
|
||||
// check to avoid unnecessary allocations around creating a copy of a
|
||||
// logger.
|
||||
if len(args) > 0 {
|
||||
logger = logger.With(args...)
|
||||
}
|
||||
|
||||
return context.WithValue(ctx, contextKey, logger)
|
||||
}
|
||||
|
||||
// FromContext returns a logger from the context. This will return L()
|
||||
// (the default logger) if no logger is found in the context. Therefore,
|
||||
// this will never return a nil value.
|
||||
func FromContext(ctx context.Context) Logger {
|
||||
logger, _ := ctx.Value(contextKey).(Logger)
|
||||
if logger == nil {
|
||||
return L()
|
||||
}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
// Unexported new type so that our context key never collides with another.
|
||||
type contextKeyType struct{}
|
||||
|
||||
// contextKey is the key used for the context to store the logger.
|
||||
var contextKey = contextKeyType{}
|
||||
74
vendor/github.com/hashicorp/go-hclog/exclude.go
generated
vendored
Normal file
74
vendor/github.com/hashicorp/go-hclog/exclude.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ExcludeByMessage provides a simple way to build a list of log messages that
|
||||
// can be queried and matched. This is meant to be used with the Exclude
|
||||
// option on Options to suppress log messages. This does not hold any mutexs
|
||||
// within itself, so normal usage would be to Add entries at setup and none after
|
||||
// Exclude is going to be called. Exclude is called with a mutex held within
|
||||
// the Logger, so that doesn't need to use a mutex. Example usage:
|
||||
//
|
||||
// f := new(ExcludeByMessage)
|
||||
// f.Add("Noisy log message text")
|
||||
// appLogger.Exclude = f.Exclude
|
||||
type ExcludeByMessage struct {
|
||||
messages map[string]struct{}
|
||||
}
|
||||
|
||||
// Add a message to be filtered. Do not call this after Exclude is to be called
|
||||
// due to concurrency issues.
|
||||
func (f *ExcludeByMessage) Add(msg string) {
|
||||
if f.messages == nil {
|
||||
f.messages = make(map[string]struct{})
|
||||
}
|
||||
|
||||
f.messages[msg] = struct{}{}
|
||||
}
|
||||
|
||||
// Return true if the given message should be included
|
||||
func (f *ExcludeByMessage) Exclude(level Level, msg string, args ...interface{}) bool {
|
||||
_, ok := f.messages[msg]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ExcludeByPrefix is a simple type to match a message string that has a common prefix.
|
||||
type ExcludeByPrefix string
|
||||
|
||||
// Matches an message that starts with the prefix.
|
||||
func (p ExcludeByPrefix) Exclude(level Level, msg string, args ...interface{}) bool {
|
||||
return strings.HasPrefix(msg, string(p))
|
||||
}
|
||||
|
||||
// ExcludeByRegexp takes a regexp and uses it to match a log message string. If it matches
|
||||
// the log entry is excluded.
|
||||
type ExcludeByRegexp struct {
|
||||
Regexp *regexp.Regexp
|
||||
}
|
||||
|
||||
// Exclude the log message if the message string matches the regexp
|
||||
func (e ExcludeByRegexp) Exclude(level Level, msg string, args ...interface{}) bool {
|
||||
return e.Regexp.MatchString(msg)
|
||||
}
|
||||
|
||||
// ExcludeFuncs is a slice of functions that will called to see if a log entry
|
||||
// should be filtered or not. It stops calling functions once at least one returns
|
||||
// true.
|
||||
type ExcludeFuncs []func(level Level, msg string, args ...interface{}) bool
|
||||
|
||||
// Calls each function until one of them returns true
|
||||
func (ff ExcludeFuncs) Exclude(level Level, msg string, args ...interface{}) bool {
|
||||
for _, f := range ff {
|
||||
if f(level, msg, args...) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
67
vendor/github.com/hashicorp/go-hclog/global.go
generated
vendored
Normal file
67
vendor/github.com/hashicorp/go-hclog/global.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
protect sync.Once
|
||||
def Logger
|
||||
|
||||
// DefaultOptions is used to create the Default logger. These are read
|
||||
// only when the Default logger is created, so set them as soon as the
|
||||
// process starts.
|
||||
DefaultOptions = &LoggerOptions{
|
||||
Level: DefaultLevel,
|
||||
Output: DefaultOutput,
|
||||
TimeFn: time.Now,
|
||||
}
|
||||
)
|
||||
|
||||
// Default returns a globally held logger. This can be a good starting
|
||||
// place, and then you can use .With() and .Named() to create sub-loggers
|
||||
// to be used in more specific contexts.
|
||||
// The value of the Default logger can be set via SetDefault() or by
|
||||
// changing the options in DefaultOptions.
|
||||
//
|
||||
// This method is goroutine safe, returning a global from memory, but
|
||||
// care should be used if SetDefault() is called it random times
|
||||
// in the program as that may result in race conditions and an unexpected
|
||||
// Logger being returned.
|
||||
func Default() Logger {
|
||||
protect.Do(func() {
|
||||
// If SetDefault was used before Default() was called, we need to
|
||||
// detect that here.
|
||||
if def == nil {
|
||||
def = New(DefaultOptions)
|
||||
}
|
||||
})
|
||||
|
||||
return def
|
||||
}
|
||||
|
||||
// L is a short alias for Default().
|
||||
func L() Logger {
|
||||
return Default()
|
||||
}
|
||||
|
||||
// SetDefault changes the logger to be returned by Default()and L()
|
||||
// to the one given. This allows packages to use the default logger
|
||||
// and have higher level packages change it to match the execution
|
||||
// environment. It returns any old default if there is one.
|
||||
//
|
||||
// NOTE: This is expected to be called early in the program to setup
|
||||
// a default logger. As such, it does not attempt to make itself
|
||||
// not racy with regard to the value of the default logger. Ergo
|
||||
// if it is called in goroutines, you may experience race conditions
|
||||
// with other goroutines retrieving the default logger. Basically,
|
||||
// don't do that.
|
||||
func SetDefault(log Logger) Logger {
|
||||
old := def
|
||||
def = log
|
||||
return old
|
||||
}
|
||||
207
vendor/github.com/hashicorp/go-hclog/interceptlogger.go
generated
vendored
Normal file
207
vendor/github.com/hashicorp/go-hclog/interceptlogger.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var _ Logger = &interceptLogger{}
|
||||
|
||||
type interceptLogger struct {
|
||||
Logger
|
||||
|
||||
mu *sync.Mutex
|
||||
sinkCount *int32
|
||||
Sinks map[SinkAdapter]struct{}
|
||||
}
|
||||
|
||||
func NewInterceptLogger(opts *LoggerOptions) InterceptLogger {
|
||||
l := newLogger(opts)
|
||||
if l.callerOffset > 0 {
|
||||
// extra frames for interceptLogger.{Warn,Info,Log,etc...}, and interceptLogger.log
|
||||
l.callerOffset += 2
|
||||
}
|
||||
intercept := &interceptLogger{
|
||||
Logger: l,
|
||||
mu: new(sync.Mutex),
|
||||
sinkCount: new(int32),
|
||||
Sinks: make(map[SinkAdapter]struct{}),
|
||||
}
|
||||
|
||||
atomic.StoreInt32(intercept.sinkCount, 0)
|
||||
|
||||
return intercept
|
||||
}
|
||||
|
||||
func (i *interceptLogger) Log(level Level, msg string, args ...interface{}) {
|
||||
i.log(level, msg, args...)
|
||||
}
|
||||
|
||||
// log is used to make the caller stack frame lookup consistent. If Warn,Info,etc
|
||||
// all called Log then direct calls to Log would have a different stack frame
|
||||
// depth. By having all the methods call the same helper we ensure the stack
|
||||
// frame depth is the same.
|
||||
func (i *interceptLogger) log(level Level, msg string, args ...interface{}) {
|
||||
i.Logger.Log(level, msg, args...)
|
||||
if atomic.LoadInt32(i.sinkCount) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
for s := range i.Sinks {
|
||||
s.Accept(i.Name(), level, msg, i.retrieveImplied(args...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// Emit the message and args at TRACE level to log and sinks
|
||||
func (i *interceptLogger) Trace(msg string, args ...interface{}) {
|
||||
i.log(Trace, msg, args...)
|
||||
}
|
||||
|
||||
// Emit the message and args at DEBUG level to log and sinks
|
||||
func (i *interceptLogger) Debug(msg string, args ...interface{}) {
|
||||
i.log(Debug, msg, args...)
|
||||
}
|
||||
|
||||
// Emit the message and args at INFO level to log and sinks
|
||||
func (i *interceptLogger) Info(msg string, args ...interface{}) {
|
||||
i.log(Info, msg, args...)
|
||||
}
|
||||
|
||||
// Emit the message and args at WARN level to log and sinks
|
||||
func (i *interceptLogger) Warn(msg string, args ...interface{}) {
|
||||
i.log(Warn, msg, args...)
|
||||
}
|
||||
|
||||
// Emit the message and args at ERROR level to log and sinks
|
||||
func (i *interceptLogger) Error(msg string, args ...interface{}) {
|
||||
i.log(Error, msg, args...)
|
||||
}
|
||||
|
||||
func (i *interceptLogger) retrieveImplied(args ...interface{}) []interface{} {
|
||||
top := i.Logger.ImpliedArgs()
|
||||
|
||||
cp := make([]interface{}, len(top)+len(args))
|
||||
copy(cp, top)
|
||||
copy(cp[len(top):], args)
|
||||
|
||||
return cp
|
||||
}
|
||||
|
||||
// Create a new sub-Logger that a name descending from the current name.
|
||||
// This is used to create a subsystem specific Logger.
|
||||
// Registered sinks will subscribe to these messages as well.
|
||||
func (i *interceptLogger) Named(name string) Logger {
|
||||
return i.NamedIntercept(name)
|
||||
}
|
||||
|
||||
// Create a new sub-Logger with an explicit name. This ignores the current
|
||||
// name. This is used to create a standalone logger that doesn't fall
|
||||
// within the normal hierarchy. Registered sinks will subscribe
|
||||
// to these messages as well.
|
||||
func (i *interceptLogger) ResetNamed(name string) Logger {
|
||||
return i.ResetNamedIntercept(name)
|
||||
}
|
||||
|
||||
// Create a new sub-Logger that a name decending from the current name.
|
||||
// This is used to create a subsystem specific Logger.
|
||||
// Registered sinks will subscribe to these messages as well.
|
||||
func (i *interceptLogger) NamedIntercept(name string) InterceptLogger {
|
||||
var sub interceptLogger
|
||||
|
||||
sub = *i
|
||||
sub.Logger = i.Logger.Named(name)
|
||||
return &sub
|
||||
}
|
||||
|
||||
// Create a new sub-Logger with an explicit name. This ignores the current
|
||||
// name. This is used to create a standalone logger that doesn't fall
|
||||
// within the normal hierarchy. Registered sinks will subscribe
|
||||
// to these messages as well.
|
||||
func (i *interceptLogger) ResetNamedIntercept(name string) InterceptLogger {
|
||||
var sub interceptLogger
|
||||
|
||||
sub = *i
|
||||
sub.Logger = i.Logger.ResetNamed(name)
|
||||
return &sub
|
||||
}
|
||||
|
||||
// Return a sub-Logger for which every emitted log message will contain
|
||||
// the given key/value pairs. This is used to create a context specific
|
||||
// Logger.
|
||||
func (i *interceptLogger) With(args ...interface{}) Logger {
|
||||
var sub interceptLogger
|
||||
|
||||
sub = *i
|
||||
|
||||
sub.Logger = i.Logger.With(args...)
|
||||
|
||||
return &sub
|
||||
}
|
||||
|
||||
// RegisterSink attaches a SinkAdapter to interceptLoggers sinks.
|
||||
func (i *interceptLogger) RegisterSink(sink SinkAdapter) {
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
|
||||
i.Sinks[sink] = struct{}{}
|
||||
|
||||
atomic.AddInt32(i.sinkCount, 1)
|
||||
}
|
||||
|
||||
// DeregisterSink removes a SinkAdapter from interceptLoggers sinks.
|
||||
func (i *interceptLogger) DeregisterSink(sink SinkAdapter) {
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
|
||||
delete(i.Sinks, sink)
|
||||
|
||||
atomic.AddInt32(i.sinkCount, -1)
|
||||
}
|
||||
|
||||
func (i *interceptLogger) StandardLoggerIntercept(opts *StandardLoggerOptions) *log.Logger {
|
||||
return i.StandardLogger(opts)
|
||||
}
|
||||
|
||||
func (i *interceptLogger) StandardLogger(opts *StandardLoggerOptions) *log.Logger {
|
||||
if opts == nil {
|
||||
opts = &StandardLoggerOptions{}
|
||||
}
|
||||
|
||||
return log.New(i.StandardWriter(opts), "", 0)
|
||||
}
|
||||
|
||||
func (i *interceptLogger) StandardWriterIntercept(opts *StandardLoggerOptions) io.Writer {
|
||||
return i.StandardWriter(opts)
|
||||
}
|
||||
|
||||
func (i *interceptLogger) StandardWriter(opts *StandardLoggerOptions) io.Writer {
|
||||
return &stdlogAdapter{
|
||||
log: i,
|
||||
inferLevels: opts.InferLevels,
|
||||
inferLevelsWithTimestamp: opts.InferLevelsWithTimestamp,
|
||||
forceLevel: opts.ForceLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *interceptLogger) ResetOutput(opts *LoggerOptions) error {
|
||||
if or, ok := i.Logger.(OutputResettable); ok {
|
||||
return or.ResetOutput(opts)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (i *interceptLogger) ResetOutputWithFlush(opts *LoggerOptions, flushable Flushable) error {
|
||||
if or, ok := i.Logger.(OutputResettable); ok {
|
||||
return or.ResetOutputWithFlush(opts, flushable)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
1007
vendor/github.com/hashicorp/go-hclog/intlogger.go
generated
vendored
Normal file
1007
vendor/github.com/hashicorp/go-hclog/intlogger.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
415
vendor/github.com/hashicorp/go-hclog/logger.go
generated
vendored
Normal file
415
vendor/github.com/hashicorp/go-hclog/logger.go
generated
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultOutput is used as the default log output.
|
||||
DefaultOutput io.Writer = os.Stderr
|
||||
|
||||
// DefaultLevel is used as the default log level.
|
||||
DefaultLevel = Info
|
||||
)
|
||||
|
||||
// Level represents a log level.
|
||||
type Level int32
|
||||
|
||||
const (
|
||||
// NoLevel is a special level used to indicate that no level has been
|
||||
// set and allow for a default to be used.
|
||||
NoLevel Level = 0
|
||||
|
||||
// Trace is the most verbose level. Intended to be used for the tracing
|
||||
// of actions in code, such as function enters/exits, etc.
|
||||
Trace Level = 1
|
||||
|
||||
// Debug information for programmer low-level analysis.
|
||||
Debug Level = 2
|
||||
|
||||
// Info information about steady state operations.
|
||||
Info Level = 3
|
||||
|
||||
// Warn information about rare but handled events.
|
||||
Warn Level = 4
|
||||
|
||||
// Error information about unrecoverable events.
|
||||
Error Level = 5
|
||||
|
||||
// Off disables all logging output.
|
||||
Off Level = 6
|
||||
)
|
||||
|
||||
// Format is a simple convenience type for when formatting is required. When
|
||||
// processing a value of this type, the logger automatically treats the first
|
||||
// argument as a Printf formatting string and passes the rest as the values
|
||||
// to be formatted. For example: L.Info(Fmt{"%d beans/day", beans}).
|
||||
type Format []interface{}
|
||||
|
||||
// Fmt returns a Format type. This is a convenience function for creating a Format
|
||||
// type.
|
||||
func Fmt(str string, args ...interface{}) Format {
|
||||
return append(Format{str}, args...)
|
||||
}
|
||||
|
||||
// A simple shortcut to format numbers in hex when displayed with the normal
|
||||
// text output. For example: L.Info("header value", Hex(17))
|
||||
type Hex int
|
||||
|
||||
// A simple shortcut to format numbers in octal when displayed with the normal
|
||||
// text output. For example: L.Info("perms", Octal(17))
|
||||
type Octal int
|
||||
|
||||
// A simple shortcut to format numbers in binary when displayed with the normal
|
||||
// text output. For example: L.Info("bits", Binary(17))
|
||||
type Binary int
|
||||
|
||||
// A simple shortcut to format strings with Go quoting. Control and
|
||||
// non-printable characters will be escaped with their backslash equivalents in
|
||||
// output. Intended for untrusted or multiline strings which should be logged
|
||||
// as concisely as possible.
|
||||
type Quote string
|
||||
|
||||
// ColorOption expresses how the output should be colored, if at all.
|
||||
type ColorOption uint8
|
||||
|
||||
const (
|
||||
// ColorOff is the default coloration, and does not
|
||||
// inject color codes into the io.Writer.
|
||||
ColorOff ColorOption = iota
|
||||
// AutoColor checks if the io.Writer is a tty,
|
||||
// and if so enables coloring.
|
||||
AutoColor
|
||||
// ForceColor will enable coloring, regardless of whether
|
||||
// the io.Writer is a tty or not.
|
||||
ForceColor
|
||||
)
|
||||
|
||||
// SupportsColor is an optional interface that can be implemented by the output
|
||||
// value. If implemented and SupportsColor() returns true, then AutoColor will
|
||||
// enable colorization.
|
||||
type SupportsColor interface {
|
||||
SupportsColor() bool
|
||||
}
|
||||
|
||||
// LevelFromString returns a Level type for the named log level, or "NoLevel" if
|
||||
// the level string is invalid. This facilitates setting the log level via
|
||||
// config or environment variable by name in a predictable way.
|
||||
func LevelFromString(levelStr string) Level {
|
||||
// We don't care about case. Accept both "INFO" and "info".
|
||||
levelStr = strings.ToLower(strings.TrimSpace(levelStr))
|
||||
switch levelStr {
|
||||
case "trace":
|
||||
return Trace
|
||||
case "debug":
|
||||
return Debug
|
||||
case "info":
|
||||
return Info
|
||||
case "warn":
|
||||
return Warn
|
||||
case "error":
|
||||
return Error
|
||||
case "off":
|
||||
return Off
|
||||
default:
|
||||
return NoLevel
|
||||
}
|
||||
}
|
||||
|
||||
func (l Level) String() string {
|
||||
switch l {
|
||||
case Trace:
|
||||
return "trace"
|
||||
case Debug:
|
||||
return "debug"
|
||||
case Info:
|
||||
return "info"
|
||||
case Warn:
|
||||
return "warn"
|
||||
case Error:
|
||||
return "error"
|
||||
case NoLevel:
|
||||
return "none"
|
||||
case Off:
|
||||
return "off"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// Logger describes the interface that must be implemented by all loggers.
|
||||
type Logger interface {
|
||||
// Args are alternating key, val pairs
|
||||
// keys must be strings
|
||||
// vals can be any type, but display is implementation specific
|
||||
// Emit a message and key/value pairs at a provided log level
|
||||
Log(level Level, msg string, args ...interface{})
|
||||
|
||||
// Emit a message and key/value pairs at the TRACE level
|
||||
Trace(msg string, args ...interface{})
|
||||
|
||||
// Emit a message and key/value pairs at the DEBUG level
|
||||
Debug(msg string, args ...interface{})
|
||||
|
||||
// Emit a message and key/value pairs at the INFO level
|
||||
Info(msg string, args ...interface{})
|
||||
|
||||
// Emit a message and key/value pairs at the WARN level
|
||||
Warn(msg string, args ...interface{})
|
||||
|
||||
// Emit a message and key/value pairs at the ERROR level
|
||||
Error(msg string, args ...interface{})
|
||||
|
||||
// Indicate if TRACE logs would be emitted. This and the other Is* guards
|
||||
// are used to elide expensive logging code based on the current level.
|
||||
IsTrace() bool
|
||||
|
||||
// Indicate if DEBUG logs would be emitted. This and the other Is* guards
|
||||
IsDebug() bool
|
||||
|
||||
// Indicate if INFO logs would be emitted. This and the other Is* guards
|
||||
IsInfo() bool
|
||||
|
||||
// Indicate if WARN logs would be emitted. This and the other Is* guards
|
||||
IsWarn() bool
|
||||
|
||||
// Indicate if ERROR logs would be emitted. This and the other Is* guards
|
||||
IsError() bool
|
||||
|
||||
// ImpliedArgs returns With key/value pairs
|
||||
ImpliedArgs() []interface{}
|
||||
|
||||
// Creates a sublogger that will always have the given key/value pairs
|
||||
With(args ...interface{}) Logger
|
||||
|
||||
// Returns the Name of the logger
|
||||
Name() string
|
||||
|
||||
// Create a logger that will prepend the name string on the front of all messages.
|
||||
// If the logger already has a name, the new value will be appended to the current
|
||||
// name. That way, a major subsystem can use this to decorate all it's own logs
|
||||
// without losing context.
|
||||
Named(name string) Logger
|
||||
|
||||
// Create a logger that will prepend the name string on the front of all messages.
|
||||
// This sets the name of the logger to the value directly, unlike Named which honor
|
||||
// the current name as well.
|
||||
ResetNamed(name string) Logger
|
||||
|
||||
// Updates the level. This should affect all related loggers as well,
|
||||
// unless they were created with IndependentLevels. If an
|
||||
// implementation cannot update the level on the fly, it should no-op.
|
||||
SetLevel(level Level)
|
||||
|
||||
// Returns the current level
|
||||
GetLevel() Level
|
||||
|
||||
// Return a value that conforms to the stdlib log.Logger interface
|
||||
StandardLogger(opts *StandardLoggerOptions) *log.Logger
|
||||
|
||||
// Return a value that conforms to io.Writer, which can be passed into log.SetOutput()
|
||||
StandardWriter(opts *StandardLoggerOptions) io.Writer
|
||||
}
|
||||
|
||||
// StandardLoggerOptions can be used to configure a new standard logger.
|
||||
type StandardLoggerOptions struct {
|
||||
// Indicate that some minimal parsing should be done on strings to try
|
||||
// and detect their level and re-emit them.
|
||||
// This supports the strings like [ERROR], [ERR] [TRACE], [WARN], [INFO],
|
||||
// [DEBUG] and strip it off before reapplying it.
|
||||
InferLevels bool
|
||||
|
||||
// Indicate that some minimal parsing should be done on strings to try
|
||||
// and detect their level and re-emit them while ignoring possible
|
||||
// timestamp values in the beginning of the string.
|
||||
// This supports the strings like [ERROR], [ERR] [TRACE], [WARN], [INFO],
|
||||
// [DEBUG] and strip it off before reapplying it.
|
||||
// The timestamp detection may result in false positives and incomplete
|
||||
// string outputs.
|
||||
// InferLevelsWithTimestamp is only relevant if InferLevels is true.
|
||||
InferLevelsWithTimestamp bool
|
||||
|
||||
// ForceLevel is used to force all output from the standard logger to be at
|
||||
// the specified level. Similar to InferLevels, this will strip any level
|
||||
// prefix contained in the logged string before applying the forced level.
|
||||
// If set, this override InferLevels.
|
||||
ForceLevel Level
|
||||
}
|
||||
|
||||
type TimeFunction = func() time.Time
|
||||
|
||||
// LoggerOptions can be used to configure a new logger.
|
||||
type LoggerOptions struct {
|
||||
// Name of the subsystem to prefix logs with
|
||||
Name string
|
||||
|
||||
// The threshold for the logger. Anything less severe is suppressed
|
||||
Level Level
|
||||
|
||||
// Where to write the logs to. Defaults to os.Stderr if nil
|
||||
Output io.Writer
|
||||
|
||||
// An optional Locker in case Output is shared. This can be a sync.Mutex or
|
||||
// a NoopLocker if the caller wants control over output, e.g. for batching
|
||||
// log lines.
|
||||
Mutex Locker
|
||||
|
||||
// Control if the output should be in JSON.
|
||||
JSONFormat bool
|
||||
|
||||
// Control the escape switch of json.Encoder
|
||||
JSONEscapeDisabled bool
|
||||
|
||||
// Include file and line information in each log line
|
||||
IncludeLocation bool
|
||||
|
||||
// AdditionalLocationOffset is the number of additional stack levels to skip
|
||||
// when finding the file and line information for the log line
|
||||
AdditionalLocationOffset int
|
||||
|
||||
// The time format to use instead of the default
|
||||
TimeFormat string
|
||||
|
||||
// A function which is called to get the time object that is formatted using `TimeFormat`
|
||||
TimeFn TimeFunction
|
||||
|
||||
// Control whether or not to display the time at all. This is required
|
||||
// because setting TimeFormat to empty assumes the default format.
|
||||
DisableTime bool
|
||||
|
||||
// Color the output. On Windows, colored logs are only available for io.Writers that
|
||||
// are concretely instances of *os.File.
|
||||
Color ColorOption
|
||||
|
||||
// Only color the header, not the body. This can help with readability of long messages.
|
||||
ColorHeaderOnly bool
|
||||
|
||||
// Color the header and message body fields. This can help with readability
|
||||
// of long messages with multiple fields.
|
||||
ColorHeaderAndFields bool
|
||||
|
||||
// A function which is called with the log information and if it returns true the value
|
||||
// should not be logged.
|
||||
// This is useful when interacting with a system that you wish to suppress the log
|
||||
// message for (because it's too noisy, etc)
|
||||
Exclude func(level Level, msg string, args ...interface{}) bool
|
||||
|
||||
// IndependentLevels causes subloggers to be created with an independent
|
||||
// copy of this logger's level. This means that using SetLevel on this
|
||||
// logger will not affect any subloggers, and SetLevel on any subloggers
|
||||
// will not affect the parent or sibling loggers.
|
||||
IndependentLevels bool
|
||||
|
||||
// When set, changing the level of a logger effects only it's direct sub-loggers
|
||||
// rather than all sub-loggers. For example:
|
||||
// a := logger.Named("a")
|
||||
// a.SetLevel(Error)
|
||||
// b := a.Named("b")
|
||||
// c := a.Named("c")
|
||||
// b.GetLevel() => Error
|
||||
// c.GetLevel() => Error
|
||||
// b.SetLevel(Info)
|
||||
// a.GetLevel() => Error
|
||||
// b.GetLevel() => Info
|
||||
// c.GetLevel() => Error
|
||||
// a.SetLevel(Warn)
|
||||
// a.GetLevel() => Warn
|
||||
// b.GetLevel() => Warn
|
||||
// c.GetLevel() => Warn
|
||||
SyncParentLevel bool
|
||||
|
||||
// SubloggerHook registers a function that is called when a sublogger via
|
||||
// Named, With, or ResetNamed is created. If defined, the function is passed
|
||||
// the newly created Logger and the returned Logger is returned from the
|
||||
// original function. This option allows customization via interception and
|
||||
// wrapping of Logger instances.
|
||||
SubloggerHook func(sub Logger) Logger
|
||||
}
|
||||
|
||||
// InterceptLogger describes the interface for using a logger
|
||||
// that can register different output sinks.
|
||||
// This is useful for sending lower level log messages
|
||||
// to a different output while keeping the root logger
|
||||
// at a higher one.
|
||||
type InterceptLogger interface {
|
||||
// Logger is the root logger for an InterceptLogger
|
||||
Logger
|
||||
|
||||
// RegisterSink adds a SinkAdapter to the InterceptLogger
|
||||
RegisterSink(sink SinkAdapter)
|
||||
|
||||
// DeregisterSink removes a SinkAdapter from the InterceptLogger
|
||||
DeregisterSink(sink SinkAdapter)
|
||||
|
||||
// Create a interceptlogger that will prepend the name string on the front of all messages.
|
||||
// If the logger already has a name, the new value will be appended to the current
|
||||
// name. That way, a major subsystem can use this to decorate all it's own logs
|
||||
// without losing context.
|
||||
NamedIntercept(name string) InterceptLogger
|
||||
|
||||
// Create a interceptlogger that will prepend the name string on the front of all messages.
|
||||
// This sets the name of the logger to the value directly, unlike Named which honor
|
||||
// the current name as well.
|
||||
ResetNamedIntercept(name string) InterceptLogger
|
||||
|
||||
// Deprecated: use StandardLogger
|
||||
StandardLoggerIntercept(opts *StandardLoggerOptions) *log.Logger
|
||||
|
||||
// Deprecated: use StandardWriter
|
||||
StandardWriterIntercept(opts *StandardLoggerOptions) io.Writer
|
||||
}
|
||||
|
||||
// SinkAdapter describes the interface that must be implemented
|
||||
// in order to Register a new sink to an InterceptLogger
|
||||
type SinkAdapter interface {
|
||||
Accept(name string, level Level, msg string, args ...interface{})
|
||||
}
|
||||
|
||||
// Flushable represents a method for flushing an output buffer. It can be used
|
||||
// if Resetting the log to use a new output, in order to flush the writes to
|
||||
// the existing output beforehand.
|
||||
type Flushable interface {
|
||||
Flush() error
|
||||
}
|
||||
|
||||
// OutputResettable provides ways to swap the output in use at runtime
|
||||
type OutputResettable interface {
|
||||
// ResetOutput swaps the current output writer with the one given in the
|
||||
// opts. Color options given in opts will be used for the new output.
|
||||
ResetOutput(opts *LoggerOptions) error
|
||||
|
||||
// ResetOutputWithFlush swaps the current output writer with the one given
|
||||
// in the opts, first calling Flush on the given Flushable. Color options
|
||||
// given in opts will be used for the new output.
|
||||
ResetOutputWithFlush(opts *LoggerOptions, flushable Flushable) error
|
||||
}
|
||||
|
||||
// Locker is used for locking output. If not set when creating a logger, a
|
||||
// sync.Mutex will be used internally.
|
||||
type Locker interface {
|
||||
// Lock is called when the output is going to be changed or written to
|
||||
Lock()
|
||||
|
||||
// Unlock is called when the operation that called Lock() completes
|
||||
Unlock()
|
||||
}
|
||||
|
||||
// NoopLocker implements locker but does nothing. This is useful if the client
|
||||
// wants tight control over locking, in order to provide grouping of log
|
||||
// entries or other functionality.
|
||||
type NoopLocker struct{}
|
||||
|
||||
// Lock does nothing
|
||||
func (n NoopLocker) Lock() {}
|
||||
|
||||
// Unlock does nothing
|
||||
func (n NoopLocker) Unlock() {}
|
||||
|
||||
var _ Locker = (*NoopLocker)(nil)
|
||||
63
vendor/github.com/hashicorp/go-hclog/nulllogger.go
generated
vendored
Normal file
63
vendor/github.com/hashicorp/go-hclog/nulllogger.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hclog
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
)
|
||||
|
||||
// NewNullLogger instantiates a Logger for which all calls
|
||||
// will succeed without doing anything.
|
||||
// Useful for testing purposes.
|
||||
func NewNullLogger() Logger {
|
||||
return &nullLogger{}
|
||||
}
|
||||
|
||||
type nullLogger struct{}
|
||||
|
||||
func (l *nullLogger) Log(level Level, msg string, args ...interface{}) {}
|
||||
|
||||
func (l *nullLogger) Trace(msg string, args ...interface{}) {}
|
||||
|
||||
func (l *nullLogger) Debug(msg string, args ...interface{}) {}
|
||||
|
||||
func (l *nullLogger) Info(msg string, args ...interface{}) {}
|
||||
|
||||
func (l *nullLogger) Warn(msg string, args ...interface{}) {}
|
||||
|
||||
func (l *nullLogger) Error(msg string, args ...interface{}) {}
|
||||
|
||||
func (l *nullLogger) IsTrace() bool { return false }
|
||||
|
||||
func (l *nullLogger) IsDebug() bool { return false }
|
||||
|
||||
func (l *nullLogger) IsInfo() bool { return false }
|
||||
|
||||
func (l *nullLogger) IsWarn() bool { return false }
|
||||
|
||||
func (l *nullLogger) IsError() bool { return false }
|
||||
|
||||
func (l *nullLogger) ImpliedArgs() []interface{} { return []interface{}{} }
|
||||
|
||||
func (l *nullLogger) With(args ...interface{}) Logger { return l }
|
||||
|
||||
func (l *nullLogger) Name() string { return "" }
|
||||
|
||||
func (l *nullLogger) Named(name string) Logger { return l }
|
||||
|
||||
func (l *nullLogger) ResetNamed(name string) Logger { return l }
|
||||
|
||||
func (l *nullLogger) SetLevel(level Level) {}
|
||||
|
||||
func (l *nullLogger) GetLevel() Level { return NoLevel }
|
||||
|
||||
func (l *nullLogger) StandardLogger(opts *StandardLoggerOptions) *log.Logger {
|
||||
return log.New(l.StandardWriter(opts), "", log.LstdFlags)
|
||||
}
|
||||
|
||||
func (l *nullLogger) StandardWriter(opts *StandardLoggerOptions) io.Writer {
|
||||
return ioutil.Discard
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user