From 7b4377ad9d8a7205416df8d6217ef2b010f89481 Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Wed, 22 Jan 2025 16:07:17 +0100 Subject: vendor: delete --- .../go/logging/logadmin/logadmin.go | 423 --------------------- .../go/logging/logadmin/metrics.go | 154 -------- .../go/logging/logadmin/resources.go | 75 ---- .../cloud.google.com/go/logging/logadmin/sinks.go | 256 ------------- 4 files changed, 908 deletions(-) delete mode 100644 vendor/cloud.google.com/go/logging/logadmin/logadmin.go delete mode 100644 vendor/cloud.google.com/go/logging/logadmin/metrics.go delete mode 100644 vendor/cloud.google.com/go/logging/logadmin/resources.go delete mode 100644 vendor/cloud.google.com/go/logging/logadmin/sinks.go (limited to 'vendor/cloud.google.com/go/logging/logadmin') diff --git a/vendor/cloud.google.com/go/logging/logadmin/logadmin.go b/vendor/cloud.google.com/go/logging/logadmin/logadmin.go deleted file mode 100644 index 04d8459f2..000000000 --- a/vendor/cloud.google.com/go/logging/logadmin/logadmin.go +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright 2016 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. - -// These features are missing now, but will likely be added: -// - There is no way to specify CallOptions. - -// Package logadmin contains a Cloud Logging client that can be used -// for reading logs and working with sinks, metrics and monitored resources. -// For a client that can write logs, see package cloud.google.com/go/logging. -// -// The client uses Logging API v2. -// See https://cloud.google.com/logging/docs/api/v2/ for an introduction to the API. -// -// Note: This package is in beta. Some backwards-incompatible changes may occur. -package logadmin // import "cloud.google.com/go/logging/logadmin" - -import ( - "context" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "cloud.google.com/go/logging" - vkit "cloud.google.com/go/logging/apiv2" - logpb "cloud.google.com/go/logging/apiv2/loggingpb" - "cloud.google.com/go/logging/internal" - gax "github.com/googleapis/gax-go/v2" - "google.golang.org/api/iterator" - "google.golang.org/api/option" - _ "google.golang.org/genproto/googleapis/appengine/logging/v1" // Import the following so EntryIterator can unmarshal log protos. - _ "google.golang.org/genproto/googleapis/cloud/audit" - logtypepb "google.golang.org/genproto/googleapis/logging/type" - "google.golang.org/grpc/codes" -) - -// Client is a Logging client. A Client is associated with a single Cloud project. -type Client struct { - lClient *vkit.Client // logging client - sClient *vkit.ConfigClient // sink client - mClient *vkit.MetricsClient // metric client - parent string - closed bool -} - -// NewClient returns a new logging client associated with the provided project ID. -// -// By default NewClient uses AdminScope. To use a different scope, call -// NewClient using a WithScopes option (see https://godoc.org/google.golang.org/api/option#WithScopes). -func NewClient(ctx context.Context, parent string, opts ...option.ClientOption) (*Client, error) { - if !strings.ContainsRune(parent, '/') { - parent = "projects/" + parent - } - opts = append([]option.ClientOption{ - option.WithScopes(logging.AdminScope), - }, opts...) - lc, err := vkit.NewClient(ctx, opts...) - if err != nil { - return nil, err - } - // TODO(jba): pass along any client options that should be provided to all clients. - sc, err := vkit.NewConfigClient(ctx, option.WithGRPCConn(lc.Connection())) - if err != nil { - return nil, err - } - mc, err := vkit.NewMetricsClient(ctx, option.WithGRPCConn(lc.Connection())) - if err != nil { - return nil, err - } - // Retry some non-idempotent methods on INTERNAL, because it happens sometimes - // and in all observed cases the operation did not complete. - retryerOnInternal := func() gax.Retryer { - return gax.OnCodes([]codes.Code{ - codes.Internal, - }, gax.Backoff{ - Initial: 100 * time.Millisecond, - Max: 1000 * time.Millisecond, - Multiplier: 1.2, - }) - } - mc.CallOptions.CreateLogMetric = []gax.CallOption{gax.WithRetry(retryerOnInternal)} - mc.CallOptions.UpdateLogMetric = []gax.CallOption{gax.WithRetry(retryerOnInternal)} - - lc.SetGoogleClientInfo("gccl", internal.Version) - sc.SetGoogleClientInfo("gccl", internal.Version) - mc.SetGoogleClientInfo("gccl", internal.Version) - client := &Client{ - lClient: lc, - sClient: sc, - mClient: mc, - parent: parent, - } - return client, nil -} - -// Close closes the client. -func (c *Client) Close() error { - if c.closed { - return nil - } - // Return only the first error. Since all clients share an underlying connection, - // Closes after the first always report a "connection is closing" error. - err := c.lClient.Close() - _ = c.sClient.Close() - _ = c.mClient.Close() - c.closed = true - return err -} - -// DeleteLog deletes a log and all its log entries. The log will reappear if it receives new entries. -// logID identifies the log within the project. An example log ID is "syslog". Requires AdminScope. -func (c *Client) DeleteLog(ctx context.Context, logID string) error { - return c.lClient.DeleteLog(ctx, &logpb.DeleteLogRequest{ - LogName: internal.LogPath(c.parent, logID), - }) -} - -func toHTTPRequest(p *logtypepb.HttpRequest) (*logging.HTTPRequest, error) { - if p == nil { - return nil, nil - } - u, err := url.Parse(p.RequestUrl) - if err != nil { - return nil, err - } - var dur time.Duration - if p.Latency != nil { - if err := p.GetLatency().CheckValid(); err != nil { - return nil, err - } - dur = p.GetLatency().AsDuration() - } - hr := &http.Request{ - Method: p.RequestMethod, - URL: u, - Header: map[string][]string{}, - } - if p.UserAgent != "" { - hr.Header.Set("User-Agent", p.UserAgent) - } - if p.Referer != "" { - hr.Header.Set("Referer", p.Referer) - } - return &logging.HTTPRequest{ - Request: hr, - RequestSize: p.RequestSize, - Status: int(p.Status), - ResponseSize: p.ResponseSize, - Latency: dur, - LocalIP: p.ServerIp, - RemoteIP: p.RemoteIp, - CacheHit: p.CacheHit, - CacheValidatedWithOriginServer: p.CacheValidatedWithOriginServer, - CacheFillBytes: p.CacheFillBytes, - CacheLookup: p.CacheLookup, - }, nil -} - -// An EntriesOption is an option for listing log entries. -type EntriesOption interface { - set(*logpb.ListLogEntriesRequest) -} - -// ProjectIDs sets the project IDs or project numbers from which to retrieve -// log entries. Examples of a project ID: "my-project-1A", "1234567890". -func ProjectIDs(pids []string) EntriesOption { return projectIDs(pids) } - -type projectIDs []string - -func (p projectIDs) set(r *logpb.ListLogEntriesRequest) { - r.ResourceNames = make([]string, len(p)) - for i, v := range p { - r.ResourceNames[i] = fmt.Sprintf("projects/%s", v) - } -} - -// ResourceNames sets the resource names from which to retrieve -// log entries. Examples: "projects/my-project-1A", "organizations/my-org". -func ResourceNames(rns []string) EntriesOption { return resourceNames(rns) } - -type resourceNames []string - -func (rn resourceNames) set(r *logpb.ListLogEntriesRequest) { - r.ResourceNames = append([]string(nil), rn...) -} - -// Filter sets an advanced logs filter for listing log entries (see -// https://cloud.google.com/logging/docs/view/advanced_filters). The filter is -// compared against all log entries in the projects specified by ProjectIDs. -// Only entries that match the filter are retrieved. An empty filter (the -// default) matches all log entries. -// -// In the filter string, log names must be written in their full form, as -// "projects/PROJECT-ID/logs/LOG-ID". Forward slashes in LOG-ID must be -// replaced by %2F before calling Filter. -// -// Timestamps in the filter string must be written in RFC 3339 format. By default, -// timestamp filters for the past 24 hours. -func Filter(f string) EntriesOption { return filter(f) } - -type filter string - -func (f filter) set(r *logpb.ListLogEntriesRequest) { r.Filter = string(f) } - -// NewestFirst causes log entries to be listed from most recent (newest) to -// least recent (oldest). By default, they are listed from oldest to newest. -func NewestFirst() EntriesOption { return newestFirst{} } - -type newestFirst struct{} - -func (newestFirst) set(r *logpb.ListLogEntriesRequest) { r.OrderBy = "timestamp desc" } - -// PageSize provide a way to override number of results to return from each request. -func PageSize(p int32) EntriesOption { return pageSize(p) } - -type pageSize int32 - -func (p pageSize) set(r *logpb.ListLogEntriesRequest) { r.PageSize = int32(p) } - -// Entries returns an EntryIterator for iterating over log entries. By default, -// the log entries will be restricted to those from the project passed to -// NewClient. This may be overridden by passing a ProjectIDs option. Requires ReadScope or AdminScope. -func (c *Client) Entries(ctx context.Context, opts ...EntriesOption) *EntryIterator { - it := &EntryIterator{ - it: c.lClient.ListLogEntries(ctx, listLogEntriesRequest(c.parent, opts)), - } - it.pageInfo, it.nextFunc = iterator.NewPageInfo( - it.fetch, - func() int { return len(it.items) }, - func() interface{} { b := it.items; it.items = nil; return b }) - return it -} - -func listLogEntriesRequest(parent string, opts []EntriesOption) *logpb.ListLogEntriesRequest { - req := &logpb.ListLogEntriesRequest{ - ResourceNames: []string{parent}, - } - for _, opt := range opts { - opt.set(req) - } - req.Filter = defaultTimestampFilter(req.Filter) - return req -} - -// defaultTimestampFilter returns a timestamp filter that looks back 24 hours in the past. -// This default setting is consistent with documentation. Note: user filters containing 'timestamp' -// substring disables this default timestamp filter, e.g. `textPayload: "timestamp"` -func defaultTimestampFilter(filter string) string { - dayAgo := time.Now().Add(-24 * time.Hour).UTC() - switch { - case len(filter) == 0: - return fmt.Sprintf(`timestamp >= "%s"`, dayAgo.Format(time.RFC3339)) - case !strings.Contains(strings.ToLower(filter), "timestamp"): - return fmt.Sprintf(`%s AND timestamp >= "%s"`, filter, dayAgo.Format(time.RFC3339)) - default: - return filter - } -} - -// An EntryIterator iterates over log entries. -type EntryIterator struct { - it *vkit.LogEntryIterator - pageInfo *iterator.PageInfo - nextFunc func() error - items []*logging.Entry -} - -// PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details. -func (it *EntryIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } - -// Next returns the next result. Its second return value is iterator.Done -// (https://godoc.org/google.golang.org/api/iterator) if there are no more -// results. Once Next returns Done, all subsequent calls will return Done. -func (it *EntryIterator) Next() (*logging.Entry, error) { - if err := it.nextFunc(); err != nil { - return nil, err - } - item := it.items[0] - it.items = it.items[1:] - return item, nil -} - -func (it *EntryIterator) fetch(pageSize int, pageToken string) (string, error) { - return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { - item, err := it.it.Next() - if err != nil { - return err - } - e, err := fromLogEntry(item) - if err != nil { - return err - } - it.items = append(it.items, e) - return nil - }) -} - -var slashUnescaper = strings.NewReplacer("%2F", "/", "%2f", "/") - -func fromLogEntry(le *logpb.LogEntry) (*logging.Entry, error) { - if err := le.GetTimestamp().CheckValid(); err != nil { - return nil, err - } - time := le.GetTimestamp().AsTime() - var payload interface{} - switch x := le.Payload.(type) { - case *logpb.LogEntry_TextPayload: - payload = x.TextPayload - - case *logpb.LogEntry_ProtoPayload: - msg, err := x.ProtoPayload.UnmarshalNew() - if err != nil { - return nil, fmt.Errorf("logging: unmarshalling proto payload: %w", err) - } - payload = msg - - case *logpb.LogEntry_JsonPayload: - // Leave this as a Struct. - // TODO(jba): convert to map[string]interface{}? - payload = x.JsonPayload - - case nil: - payload = nil - - default: - return nil, fmt.Errorf("logging: unknown payload type: %T", le.Payload) - } - hr, err := toHTTPRequest(le.HttpRequest) - if err != nil { - return nil, err - } - return &logging.Entry{ - Timestamp: time, - Severity: logging.Severity(le.Severity), - Payload: payload, - Labels: le.Labels, - InsertID: le.InsertId, - HTTPRequest: hr, - Operation: le.Operation, - LogName: slashUnescaper.Replace(le.LogName), - Resource: le.Resource, - Trace: le.Trace, - SourceLocation: le.SourceLocation, - }, nil -} - -// Logs lists the logs owned by the parent resource of the client. -func (c *Client) Logs(ctx context.Context) *LogIterator { - it := &LogIterator{ - parentResource: c.parent, - it: c.lClient.ListLogs(ctx, &logpb.ListLogsRequest{Parent: c.parent}), - } - it.pageInfo, it.nextFunc = iterator.NewPageInfo( - it.fetch, - func() int { return len(it.items) }, - func() interface{} { b := it.items; it.items = nil; return b }) - return it -} - -// A LogIterator iterates over logs. -type LogIterator struct { - parentResource string - it *vkit.StringIterator - pageInfo *iterator.PageInfo - nextFunc func() error - items []string -} - -// PageInfo supports pagination. See https://godoc.org/google.golang.org/api/iterator package for details. -func (it *LogIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } - -// Next returns the next result. Its second return value is iterator.Done -// (https://godoc.org/google.golang.org/api/iterator) if there are no more -// results. Once Next returns Done, all subsequent calls will return Done. -func (it *LogIterator) Next() (string, error) { - if err := it.nextFunc(); err != nil { - return "", err - } - item := it.items[0] - it.items = it.items[1:] - return item, nil -} - -func (it *LogIterator) fetch(pageSize int, pageToken string) (string, error) { - return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { - logPath, err := it.it.Next() - if err != nil { - return err - } - logID := internal.LogIDFromPath(it.parentResource, logPath) - it.items = append(it.items, logID) - return nil - }) -} - -// Common fetch code for iterators that are backed by vkit iterators. -func iterFetch(pageSize int, pageToken string, pi *iterator.PageInfo, next func() error) (string, error) { - pi.MaxSize = pageSize - pi.Token = pageToken - // Get one item, which will fill the buffer. - if err := next(); err != nil { - return "", err - } - // Collect the rest of the buffer. - for pi.Remaining() > 0 { - if err := next(); err != nil { - return "", err - } - } - return pi.Token, nil -} diff --git a/vendor/cloud.google.com/go/logging/logadmin/metrics.go b/vendor/cloud.google.com/go/logging/logadmin/metrics.go deleted file mode 100644 index 3db10d748..000000000 --- a/vendor/cloud.google.com/go/logging/logadmin/metrics.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2016 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 logadmin - -import ( - "context" - "fmt" - - vkit "cloud.google.com/go/logging/apiv2" - logpb "cloud.google.com/go/logging/apiv2/loggingpb" - "google.golang.org/api/iterator" -) - -// Metric describes a logs-based metric. The value of the metric is the -// number of log entries that match a logs filter. -// -// Metrics are a feature of Cloud Monitoring. -// See https://cloud.google.com/monitoring/api/v3/metrics for more about them. -type Metric struct { - // ID is a client-assigned metric identifier. Example: - // "severe_errors". Metric identifiers are limited to 1000 - // characters and can include only the following characters: A-Z, - // a-z, 0-9, and the special characters _-.,+!*',()%/\. The - // forward-slash character (/) denotes a hierarchy of name pieces, - // and it cannot be the first character of the name. - ID string - - // Description describes this metric. It is used in documentation. - Description string - - // Filter is an advanced logs filter (see - // https://cloud.google.com/logging/docs/view/advanced_filters). - // Example: "logName:syslog AND severity>=ERROR". - Filter string -} - -// CreateMetric creates a logs-based metric. -func (c *Client) CreateMetric(ctx context.Context, m *Metric) error { - _, err := c.mClient.CreateLogMetric(ctx, &logpb.CreateLogMetricRequest{ - Parent: c.parent, - Metric: toLogMetric(m), - }) - return err -} - -// DeleteMetric deletes a log-based metric. -// The provided metric ID is the metric identifier. For example, "severe_errors". -func (c *Client) DeleteMetric(ctx context.Context, metricID string) error { - return c.mClient.DeleteLogMetric(ctx, &logpb.DeleteLogMetricRequest{ - MetricName: c.metricPath(metricID), - }) -} - -// Metric gets a logs-based metric. -// The provided metric ID is the metric identifier. For example, "severe_errors". -// Requires ReadScope or AdminScope. -func (c *Client) Metric(ctx context.Context, metricID string) (*Metric, error) { - lm, err := c.mClient.GetLogMetric(ctx, &logpb.GetLogMetricRequest{ - MetricName: c.metricPath(metricID), - }) - if err != nil { - return nil, err - } - return fromLogMetric(lm), nil -} - -// UpdateMetric creates a logs-based metric if it does not exist, or updates an -// existing one. -func (c *Client) UpdateMetric(ctx context.Context, m *Metric) error { - _, err := c.mClient.UpdateLogMetric(ctx, &logpb.UpdateLogMetricRequest{ - MetricName: c.metricPath(m.ID), - Metric: toLogMetric(m), - }) - return err -} - -func (c *Client) metricPath(metricID string) string { - return fmt.Sprintf("%s/metrics/%s", c.parent, metricID) -} - -// Metrics returns a MetricIterator for iterating over all Metrics in the Client's project. -// Requires ReadScope or AdminScope. -func (c *Client) Metrics(ctx context.Context) *MetricIterator { - it := &MetricIterator{ - it: c.mClient.ListLogMetrics(ctx, &logpb.ListLogMetricsRequest{Parent: c.parent}), - } - it.pageInfo, it.nextFunc = iterator.NewPageInfo( - it.fetch, - func() int { return len(it.items) }, - func() interface{} { b := it.items; it.items = nil; return b }) - return it -} - -// A MetricIterator iterates over Metrics. -type MetricIterator struct { - it *vkit.LogMetricIterator - pageInfo *iterator.PageInfo - nextFunc func() error - items []*Metric -} - -// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. -func (it *MetricIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } - -// Next returns the next result. Its second return value is Done if there are -// no more results. Once Next returns Done, all subsequent calls will return -// Done. -func (it *MetricIterator) Next() (*Metric, error) { - if err := it.nextFunc(); err != nil { - return nil, err - } - item := it.items[0] - it.items = it.items[1:] - return item, nil -} - -func (it *MetricIterator) fetch(pageSize int, pageToken string) (string, error) { - return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { - item, err := it.it.Next() - if err != nil { - return err - } - it.items = append(it.items, fromLogMetric(item)) - return nil - }) -} - -func toLogMetric(m *Metric) *logpb.LogMetric { - return &logpb.LogMetric{ - Name: m.ID, - Description: m.Description, - Filter: m.Filter, - } -} - -func fromLogMetric(lm *logpb.LogMetric) *Metric { - return &Metric{ - ID: lm.Name, - Description: lm.Description, - Filter: lm.Filter, - } -} diff --git a/vendor/cloud.google.com/go/logging/logadmin/resources.go b/vendor/cloud.google.com/go/logging/logadmin/resources.go deleted file mode 100644 index 7f153d21d..000000000 --- a/vendor/cloud.google.com/go/logging/logadmin/resources.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2016 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 logadmin - -import ( - "context" - - vkit "cloud.google.com/go/logging/apiv2" - logpb "cloud.google.com/go/logging/apiv2/loggingpb" - "google.golang.org/api/iterator" - mrpb "google.golang.org/genproto/googleapis/api/monitoredres" -) - -// ResourceDescriptors returns a ResourceDescriptorIterator -// for iterating over MonitoredResourceDescriptors. Requires ReadScope or AdminScope. -// See https://cloud.google.com/logging/docs/api/v2/#monitored-resources for an explanation of -// monitored resources. -// See https://cloud.google.com/logging/docs/api/v2/resource-list for a list of monitored resources. -func (c *Client) ResourceDescriptors(ctx context.Context) *ResourceDescriptorIterator { - it := &ResourceDescriptorIterator{ - it: c.lClient.ListMonitoredResourceDescriptors(ctx, - &logpb.ListMonitoredResourceDescriptorsRequest{}), - } - it.pageInfo, it.nextFunc = iterator.NewPageInfo( - it.fetch, - func() int { return len(it.items) }, - func() interface{} { b := it.items; it.items = nil; return b }) - return it -} - -// ResourceDescriptorIterator is an iterator over MonitoredResourceDescriptors. -type ResourceDescriptorIterator struct { - it *vkit.MonitoredResourceDescriptorIterator - pageInfo *iterator.PageInfo - nextFunc func() error - items []*mrpb.MonitoredResourceDescriptor -} - -// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. -func (it *ResourceDescriptorIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } - -// Next returns the next result. Its second return value is Done if there are -// no more results. Once Next returns Done, all subsequent calls will return -// Done. -func (it *ResourceDescriptorIterator) Next() (*mrpb.MonitoredResourceDescriptor, error) { - if err := it.nextFunc(); err != nil { - return nil, err - } - item := it.items[0] - it.items = it.items[1:] - return item, nil -} - -func (it *ResourceDescriptorIterator) fetch(pageSize int, pageToken string) (string, error) { - return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { - item, err := it.it.Next() - if err != nil { - return err - } - it.items = append(it.items, item) - return nil - }) -} diff --git a/vendor/cloud.google.com/go/logging/logadmin/sinks.go b/vendor/cloud.google.com/go/logging/logadmin/sinks.go deleted file mode 100644 index d71316a9d..000000000 --- a/vendor/cloud.google.com/go/logging/logadmin/sinks.go +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2016 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 logadmin - -import ( - "context" - "errors" - "fmt" - - vkit "cloud.google.com/go/logging/apiv2" - logpb "cloud.google.com/go/logging/apiv2/loggingpb" - "google.golang.org/api/iterator" - maskpb "google.golang.org/protobuf/types/known/fieldmaskpb" -) - -// Sink describes a sink used to export log entries outside Cloud -// Logging. Incoming log entries matching a filter are exported to a -// destination (a Cloud Storage bucket, BigQuery dataset or Cloud Pub/Sub -// topic). -// -// For more information, see https://cloud.google.com/logging/docs/export/using_exported_logs. -// (The Sinks in this package are what the documentation refers to as "project sinks".) -type Sink struct { - // ID is a client-assigned sink identifier. Example: - // "my-severe-errors-to-pubsub". - // Sink identifiers are limited to 1000 characters - // and can include only the following characters: A-Z, a-z, - // 0-9, and the special characters "_-.". - ID string - - // Destination is the export destination. See - // https://cloud.google.com/logging/docs/api/tasks/exporting-logs. - // Examples: "storage.googleapis.com/a-bucket", - // "bigquery.googleapis.com/projects/a-project-id/datasets/a-dataset". - Destination string - - // Filter optionally specifies an advanced logs filter (see - // https://cloud.google.com/logging/docs/view/advanced_filters) that - // defines the log entries to be exported. Example: "logName:syslog AND - // severity>=ERROR". If omitted, all entries are returned. - Filter string - - // WriterIdentity must be a service account name. When exporting logs, Logging - // adopts this identity for authorization. The export destination's owner must - // give this service account permission to write to the export destination. - WriterIdentity string - - // IncludeChildren, when set to true, allows the sink to export log entries from - // the organization or folder, plus (recursively) from any contained folders, billing - // accounts, or projects. IncludeChildren is false by default. You can use the sink's - // filter to choose log entries from specific projects, specific resource types, or - // specific named logs. - // - // Caution: If you enable this feature, your aggregated export sink might export - // a very large number of log entries. To avoid exporting too many log entries, - // design your aggregated export sink filter carefully, as described on - // https://cloud.google.com/logging/docs/export/aggregated_exports. - IncludeChildren bool -} - -// CreateSink creates a Sink. It returns an error if the Sink already exists. -// Requires AdminScope. -func (c *Client) CreateSink(ctx context.Context, sink *Sink) (*Sink, error) { - return c.CreateSinkOpt(ctx, sink, SinkOptions{}) -} - -// CreateSinkOpt creates a Sink using the provided options. It returns an -// error if the Sink already exists. Requires AdminScope. -func (c *Client) CreateSinkOpt(ctx context.Context, sink *Sink, opts SinkOptions) (*Sink, error) { - ls, err := c.sClient.CreateSink(ctx, &logpb.CreateSinkRequest{ - Parent: c.parent, - Sink: toLogSink(sink), - UniqueWriterIdentity: opts.UniqueWriterIdentity, - }) - if err != nil { - return nil, err - } - return fromLogSink(ls), nil -} - -// SinkOptions define options to be used when creating or updating a sink. -type SinkOptions struct { - // Determines the kind of IAM identity returned as WriterIdentity in the new - // sink. If this value is omitted or set to false, and if the sink's parent is a - // project, then the value returned as WriterIdentity is the same group or - // service account used by Cloud Logging before the addition of writer - // identities to the API. The sink's destination must be in the same project as - // the sink itself. - // - // If this field is set to true, or if the sink is owned by a non-project - // resource such as an organization, then the value of WriterIdentity will - // be a unique service account used only for exports from the new sink. - UniqueWriterIdentity bool - - // These fields apply only to UpdateSinkOpt calls. The corresponding sink field - // is updated if and only if the Update field is true. - UpdateDestination bool - UpdateFilter bool - UpdateIncludeChildren bool -} - -// DeleteSink deletes a sink. The provided sinkID is the sink's identifier, such as -// "my-severe-errors-to-pubsub". -// Requires AdminScope. -func (c *Client) DeleteSink(ctx context.Context, sinkID string) error { - return c.sClient.DeleteSink(ctx, &logpb.DeleteSinkRequest{ - SinkName: c.sinkPath(sinkID), - }) -} - -// Sink gets a sink. The provided sinkID is the sink's identifier, such as -// "my-severe-errors-to-pubsub". -// Requires ReadScope or AdminScope. -func (c *Client) Sink(ctx context.Context, sinkID string) (*Sink, error) { - ls, err := c.sClient.GetSink(ctx, &logpb.GetSinkRequest{ - SinkName: c.sinkPath(sinkID), - }) - if err != nil { - return nil, err - } - return fromLogSink(ls), nil -} - -// UpdateSink updates an existing Sink. Requires AdminScope. -// -// WARNING: UpdateSink will always update the Destination, Filter and IncludeChildren -// fields of the sink, even if they have their zero values. Use UpdateSinkOpt -// for more control over which fields to update. -func (c *Client) UpdateSink(ctx context.Context, sink *Sink) (*Sink, error) { - return c.UpdateSinkOpt(ctx, sink, SinkOptions{ - UpdateDestination: true, - UpdateFilter: true, - UpdateIncludeChildren: true, - }) -} - -// UpdateSinkOpt updates an existing Sink, using the provided options. Requires AdminScope. -// -// To change a sink's writer identity to a service account unique to the sink, set -// opts.UniqueWriterIdentity to true. It is not possible to change a sink's writer identity -// from a unique service account to a non-unique writer identity. -func (c *Client) UpdateSinkOpt(ctx context.Context, sink *Sink, opts SinkOptions) (*Sink, error) { - mask := &maskpb.FieldMask{} - if opts.UpdateDestination { - mask.Paths = append(mask.Paths, "destination") - } - if opts.UpdateFilter { - mask.Paths = append(mask.Paths, "filter") - } - if opts.UpdateIncludeChildren { - mask.Paths = append(mask.Paths, "include_children") - } - if opts.UniqueWriterIdentity && len(mask.Paths) == 0 { - // Hack: specify a deprecated, unchangeable field so that we have a non-empty - // field mask. (An empty field mask would cause the destination, filter and include_children - // fields to be changed.) - mask.Paths = append(mask.Paths, "output_version_format") - } - if len(mask.Paths) == 0 { - return nil, errors.New("logadmin: UpdateSinkOpt: nothing to update") - } - ls, err := c.sClient.UpdateSink(ctx, &logpb.UpdateSinkRequest{ - SinkName: c.sinkPath(sink.ID), - Sink: toLogSink(sink), - UniqueWriterIdentity: opts.UniqueWriterIdentity, - UpdateMask: mask, - }) - if err != nil { - return nil, err - } - return fromLogSink(ls), err -} - -func (c *Client) sinkPath(sinkID string) string { - return fmt.Sprintf("%s/sinks/%s", c.parent, sinkID) -} - -// Sinks returns a SinkIterator for iterating over all Sinks in the Client's project. -// Requires ReadScope or AdminScope. -func (c *Client) Sinks(ctx context.Context) *SinkIterator { - it := &SinkIterator{ - it: c.sClient.ListSinks(ctx, &logpb.ListSinksRequest{Parent: c.parent}), - } - it.pageInfo, it.nextFunc = iterator.NewPageInfo( - it.fetch, - func() int { return len(it.items) }, - func() interface{} { b := it.items; it.items = nil; return b }) - return it -} - -// A SinkIterator iterates over Sinks. -type SinkIterator struct { - it *vkit.LogSinkIterator - pageInfo *iterator.PageInfo - nextFunc func() error - items []*Sink -} - -// PageInfo supports pagination. See the google.golang.org/api/iterator package for details. -func (it *SinkIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } - -// Next returns the next result. Its second return value is Done if there are -// no more results. Once Next returns Done, all subsequent calls will return -// Done. -func (it *SinkIterator) Next() (*Sink, error) { - if err := it.nextFunc(); err != nil { - return nil, err - } - item := it.items[0] - it.items = it.items[1:] - return item, nil -} - -func (it *SinkIterator) fetch(pageSize int, pageToken string) (string, error) { - return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error { - item, err := it.it.Next() - if err != nil { - return err - } - it.items = append(it.items, fromLogSink(item)) - return nil - }) -} - -func toLogSink(s *Sink) *logpb.LogSink { - return &logpb.LogSink{ - Name: s.ID, - Destination: s.Destination, - Filter: s.Filter, - IncludeChildren: s.IncludeChildren, - OutputVersionFormat: logpb.LogSink_V2, - // omit WriterIdentity because it is output-only. - } -} - -func fromLogSink(ls *logpb.LogSink) *Sink { - return &Sink{ - ID: ls.Name, - Destination: ls.Destination, - Filter: ls.Filter, - WriterIdentity: ls.WriterIdentity, - IncludeChildren: ls.IncludeChildren, - } -} -- cgit mrf-deployment