tessl install tessl/golang-cloud-google-com--go--logging@1.13.0Cloud Logging client library for Go that enables writing log entries to Google Cloud Logging service with buffered asynchronous and synchronous logging capabilities.
This document describes the logadmin package for reading logs, managing sinks for exporting logs, creating and managing logs-based metrics, and working with monitored resources.
import "cloud.google.com/go/logging/logadmin"The logadmin package provides a Cloud Logging client for administrative operations. It is used for reading logs and working with sinks, metrics, and monitored resources. For writing logs, use the main cloud.google.com/go/logging package.
Note: This package is in beta. Some backwards-incompatible changes may occur.
func NewClient(ctx context.Context, parent string, opts ...option.ClientOption) (*Client, error)Creates a new logging client associated with the provided parent resource. By default, NewClient uses AdminScope. To use a different scope, call NewClient using a WithScopes option.
Parameters:
ctx - Context for the operationparent - Parent resource (project ID, or "projects/PROJECT_ID")opts - Optional client configuration optionsReturns:
*Client - The created logadmin clienterror - Error if client creation failsExample:
import (
"context"
"cloud.google.com/go/logging/logadmin"
)
ctx := context.Background()
// Create client with project ID
client, err := logadmin.NewClient(ctx, "my-project")
if err != nil {
// Handle error
}
defer client.Close()func (c *Client) Close() errorCloses the client and releases resources.
func (c *Client) Entries(ctx context.Context, opts ...EntriesOption) *EntryIteratorReturns 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 or ResourceNames option. Requires ReadScope or AdminScope.
Parameters:
ctx - Context for the operationopts - Optional filtering and pagination optionsReturns:
*EntryIterator - Iterator for reading log entriesExample:
import (
"cloud.google.com/go/logging/logadmin"
"google.golang.org/api/iterator"
)
ctx := context.Background()
client, _ := logadmin.NewClient(ctx, "my-project")
defer client.Close()
// Read all log entries
iter := client.Entries(ctx)
for {
entry, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
// Handle error
}
// Process entry
fmt.Printf("Log: %v\n", entry.Payload)
}func Filter(f string) EntriesOptionSets an advanced logs filter. The filter is compared against all log entries in the specified projects. Only entries that match the filter are retrieved.
Example:
// Filter by severity
iter := client.Entries(ctx, logadmin.Filter("severity >= ERROR"))
// Filter by log name and timestamp
iter := client.Entries(ctx, logadmin.Filter(
`logName="projects/my-project/logs/syslog" AND timestamp >= "2024-01-01T00:00:00Z"`,
))
// Filter by resource type
iter := client.Entries(ctx, logadmin.Filter(`resource.type="gce_instance"`))func NewestFirst() EntriesOptionLists log entries from most recent to least recent. By default, entries are listed from oldest to newest.
Example:
iter := client.Entries(ctx, logadmin.NewestFirst())func ProjectIDs(pids []string) EntriesOptionSets the project IDs or project numbers from which to retrieve log entries.
Example:
iter := client.Entries(ctx, logadmin.ProjectIDs([]string{"project-1", "project-2"}))func ResourceNames(rns []string) EntriesOptionSets resource names from which to retrieve log entries. Examples: "projects/my-project-1A", "organizations/my-org".
Example:
iter := client.Entries(ctx, logadmin.ResourceNames([]string{
"projects/my-project",
"organizations/my-org",
}))func PageSize(p int32) EntriesOptionOverrides the number of results to return from each request.
Example:
iter := client.Entries(ctx, logadmin.PageSize(100))type EntryIterator struct {
// unexported fields
}
func (it *EntryIterator) Next() (*logging.Entry, error)
func (it *EntryIterator) PageInfo() *iterator.PageInfoIterates over log entries. Call Next() to retrieve entries one by one, or use PageInfo() for pagination control.
func (c *Client) Logs(ctx context.Context) *LogIteratorLists the logs owned by the parent resource of the client.
Example:
iter := client.Logs(ctx)
for {
logName, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
// Handle error
}
fmt.Printf("Log: %s\n", logName)
}type LogIterator struct {
// unexported fields
}
func (it *LogIterator) Next() (string, error)
func (it *LogIterator) PageInfo() *iterator.PageInfofunc (c *Client) DeleteLog(ctx context.Context, logID string) errorDeletes a log and all its log entries. The log will reappear if it receives new entries. Requires AdminScope.
Example:
err := client.DeleteLog(ctx, "old-log")
if err != nil {
// Handle error
}Sinks export log entries to external destinations like Cloud Storage, BigQuery, or Pub/Sub.
type Sink struct {
ID string
Destination string
Filter string
WriterIdentity string
IncludeChildren bool
}Fields:
ID string - Client-assigned sink identifier (max 1000 chars: A-Z, a-z, 0-9, _, -, .)Destination string - Export destination (e.g., "storage.googleapis.com/a-bucket", "bigquery.googleapis.com/projects/a-project-id/datasets/a-dataset")Filter string - Optional advanced logs filter defining log entries to exportWriterIdentity string - Service account name for authorizationIncludeChildren bool - Whether to export from organization/folder plus contained folders, billing accounts, or projects (default false)func (c *Client) CreateSink(ctx context.Context, sink *Sink) (*Sink, error)
func (c *Client) CreateSinkOpt(ctx context.Context, sink *Sink, opts SinkOptions) (*Sink, error)Creates a Sink. Returns an error if the Sink already exists. Requires AdminScope.
Example:
sink := &logadmin.Sink{
ID: "my-sink",
Destination: "storage.googleapis.com/my-bucket",
Filter: "severity >= ERROR",
}
createdSink, err := client.CreateSink(ctx, sink)
if err != nil {
// Handle error
}
// Grant writer identity permission to write to destination
fmt.Printf("Grant %s permission to write to bucket\n", createdSink.WriterIdentity)func (c *Client) Sink(ctx context.Context, sinkID string) (*Sink, error)
func (c *Client) Sinks(ctx context.Context) *SinkIteratorGets a single sink or iterates over all sinks. Requires ReadScope or AdminScope.
Example:
// Get single sink
sink, err := client.Sink(ctx, "my-sink")
if err != nil {
// Handle error
}
fmt.Printf("Sink destination: %s\n", sink.Destination)
// List all sinks
iter := client.Sinks(ctx)
for {
sink, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
// Handle error
}
fmt.Printf("Sink: %s -> %s\n", sink.ID, sink.Destination)
}func (c *Client) UpdateSink(ctx context.Context, sink *Sink) (*Sink, error)
func (c *Client) UpdateSinkOpt(ctx context.Context, sink *Sink, opts SinkOptions) (*Sink, error)Updates an existing Sink. WARNING: UpdateSink always updates Destination, Filter, and IncludeChildren even if they have zero values. Use UpdateSinkOpt for selective updates. Requires AdminScope.
Example:
// Get existing sink
sink, _ := client.Sink(ctx, "my-sink")
// Update filter
sink.Filter = "severity >= WARNING"
updatedSink, err := client.UpdateSink(ctx, sink)
if err != nil {
// Handle error
}
// Selective update using UpdateSinkOpt
opts := logadmin.SinkOptions{
UpdateFilter: true,
}
updatedSink, err = client.UpdateSinkOpt(ctx, sink, opts)func (c *Client) DeleteSink(ctx context.Context, sinkID string) errorDeletes a sink. Requires AdminScope.
Example:
err := client.DeleteSink(ctx, "my-sink")
if err != nil {
// Handle error
}type SinkOptions struct {
UniqueWriterIdentity bool
UpdateDestination bool
UpdateFilter bool
UpdateIncludeChildren bool
}Options for creating or updating sinks.
type SinkIterator struct {
// unexported fields
}
func (it *SinkIterator) Next() (*Sink, error)
func (it *SinkIterator) PageInfo() *iterator.PageInfoLogs-based metrics are counters of log entries that match a filter.
type Metric struct {
ID string
Description string
Filter string
}Fields:
ID string - Client-assigned metric identifier (max 1000 chars: A-Z, a-z, 0-9, _, -, ., +, !, *, ', (, ), %, /, )Description string - Describes the metric (used in documentation)Filter string - Advanced logs filter (e.g., "logName:syslog AND severity>=ERROR")func (c *Client) CreateMetric(ctx context.Context, m *Metric) errorCreates a logs-based metric.
Example:
metric := &logadmin.Metric{
ID: "severe-errors",
Description: "Count of severe errors",
Filter: "severity >= ERROR",
}
err := client.CreateMetric(ctx, metric)
if err != nil {
// Handle error
}func (c *Client) Metric(ctx context.Context, metricID string) (*Metric, error)
func (c *Client) Metrics(ctx context.Context) *MetricIteratorGets a single metric or iterates over all metrics. Requires ReadScope or AdminScope.
Example:
// Get single metric
metric, err := client.Metric(ctx, "severe-errors")
if err != nil {
// Handle error
}
fmt.Printf("Metric filter: %s\n", metric.Filter)
// List all metrics
iter := client.Metrics(ctx)
for {
metric, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
// Handle error
}
fmt.Printf("Metric: %s - %s\n", metric.ID, metric.Description)
}func (c *Client) UpdateMetric(ctx context.Context, m *Metric) errorCreates a logs-based metric if it does not exist, or updates an existing one.
Example:
metric, _ := client.Metric(ctx, "severe-errors")
metric.Filter = "severity >= CRITICAL"
err := client.UpdateMetric(ctx, metric)
if err != nil {
// Handle error
}func (c *Client) DeleteMetric(ctx context.Context, metricID string) errorDeletes a log-based metric.
Example:
err := client.DeleteMetric(ctx, "severe-errors")
if err != nil {
// Handle error
}type MetricIterator struct {
// unexported fields
}
func (it *MetricIterator) Next() (*Metric, error)
func (it *MetricIterator) PageInfo() *iterator.PageInfofunc (c *Client) ResourceDescriptors(ctx context.Context) *ResourceDescriptorIteratorReturns a ResourceDescriptorIterator for iterating over MonitoredResourceDescriptors. Requires ReadScope or AdminScope.
Example:
iter := client.ResourceDescriptors(ctx)
for {
descriptor, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
// Handle error
}
fmt.Printf("Resource type: %s\n", descriptor.Type)
}type ResourceDescriptorIterator struct {
// unexported fields
}
func (it *ResourceDescriptorIterator) Next() (*mrpb.MonitoredResourceDescriptor, error)
func (it *ResourceDescriptorIterator) PageInfo() *iterator.PageInfopackage main
import (
"context"
"fmt"
"log"
"cloud.google.com/go/logging/logadmin"
"google.golang.org/api/iterator"
)
func main() {
ctx := context.Background()
// Create logadmin client
client, err := logadmin.NewClient(ctx, "my-project")
if err != nil {
log.Fatalf("failed to create client: %v", err)
}
defer client.Close()
// Create a sink to export error logs to Cloud Storage
sink := &logadmin.Sink{
ID: "error-logs-to-storage",
Destination: "storage.googleapis.com/my-logs-bucket",
Filter: "severity >= ERROR",
}
createdSink, err := client.CreateSink(ctx, sink)
if err != nil {
log.Printf("failed to create sink: %v", err)
} else {
fmt.Printf("Created sink with writer identity: %s\n", createdSink.WriterIdentity)
}
// Create a metric for counting critical errors
metric := &logadmin.Metric{
ID: "critical-error-count",
Description: "Count of critical errors",
Filter: "severity >= CRITICAL",
}
err = client.CreateMetric(ctx, metric)
if err != nil {
log.Printf("failed to create metric: %v", err)
} else {
fmt.Println("Created metric: critical-error-count")
}
// Read recent error logs
iter := client.Entries(ctx,
logadmin.Filter("severity >= ERROR"),
logadmin.NewestFirst(),
logadmin.PageSize(10),
)
fmt.Println("\nRecent error logs:")
count := 0
for {
entry, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Printf("failed to read entry: %v", err)
break
}
count++
fmt.Printf("%d. [%s] %v\n", count, entry.Severity, entry.Payload)
if count >= 10 {
break
}
}
// List all sinks
fmt.Println("\nAll sinks:")
sinkIter := client.Sinks(ctx)
for {
s, err := sinkIter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Printf("failed to list sinks: %v", err)
break
}
fmt.Printf(" - %s -> %s\n", s.ID, s.Destination)
}
// List all metrics
fmt.Println("\nAll metrics:")
metricIter := client.Metrics(ctx)
for {
m, err := metricIter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Printf("failed to list metrics: %v", err)
break
}
fmt.Printf(" - %s: %s\n", m.ID, m.Description)
}
}sink := &logadmin.Sink{
ID: "logs-to-bigquery",
Destination: "bigquery.googleapis.com/projects/my-project/datasets/logs_dataset",
Filter: `resource.type="gae_app"`,
}
createdSink, err := client.CreateSink(ctx, sink)
// Grant createdSink.WriterIdentity permission to write to BigQuery datasetsink := &logadmin.Sink{
ID: "logs-to-pubsub",
Destination: "pubsub.googleapis.com/projects/my-project/topics/logs-topic",
Filter: "severity >= WARNING",
}
createdSink, err := client.CreateSink(ctx, sink)
// Grant createdSink.WriterIdentity permission to publish to Pub/Sub topiciter := client.Entries(ctx, logadmin.Filter(
`timestamp >= "2024-01-01T00:00:00Z" AND timestamp < "2024-01-02T00:00:00Z"`,
))metric := &logadmin.Metric{
ID: "app-errors",
Description: "Count of application errors",
Filter: `logName="projects/my-project/logs/application" AND severity >= ERROR`,
}
err := client.CreateMetric(ctx, metric)