// Logger returns a Logger that will write entries with the given log ID, such as // "syslog". A log ID must be less than 512 characters long and can only // include the following characters: upper and lower case alphanumeric // characters: [A-Za-z0-9]; and punctuation characters: forward-slash, // underscore, hyphen, and period. func (c *Client) Logger(logID string, opts ...LoggerOption) *Logger { l := &Logger{ client: c, logName: internal.LogPath(c.parent(), logID), commonResource: &mrpb.MonitoredResource{Type: "global"}, } // TODO(jba): determine the right context for the bundle handler. ctx := context.TODO() l.bundler = bundler.NewBundler(&logpb.LogEntry{}, func(entries interface{}) { l.writeLogEntries(ctx, entries.([]*logpb.LogEntry)) }) l.bundler.DelayThreshold = DefaultDelayThreshold l.bundler.BundleCountThreshold = DefaultEntryCountThreshold l.bundler.BundleByteThreshold = DefaultEntryByteThreshold l.bundler.BufferedByteLimit = DefaultBufferedByteLimit for _, opt := range opts { opt.set(l) } l.stdLoggers = map[Severity]*log.Logger{} for s := range severityName { l.stdLoggers[s] = log.New(severityWriter{l, s}, "", 0) } c.loggers.Add(1) go func() { defer c.loggers.Done() <-c.donec l.bundler.Close() }() return l }
// deleteLog is used to clean up a log after a test that writes to it. func deleteLog(ctx context.Context, logID string) { aclient.DeleteLog(ctx, logID) // DeleteLog can take some time to happen, so we wait for the log to // disappear. There is no direct way to determine if a log exists, so we // just wait until there are no log entries associated with the ID. filter := fmt.Sprintf(`logName = "%s"`, internal.LogPath("projects/"+testProjectID, logID)) waitFor(func() bool { return countLogEntries(ctx, filter) == 0 }) }
// Ping reports whether the client's connection to the logging service and the // authentication configuration are valid. To accomplish this, Ping writes a // log entry "ping" to a log named "ping". func (c *Client) Ping(ctx context.Context) error { ent := &logpb.LogEntry{ Payload: &logpb.LogEntry_TextPayload{"ping"}, Timestamp: unixZeroTimestamp, // Identical timestamps and insert IDs are both InsertId: "ping", // necessary for the service to dedup these entries. } _, err := c.client.WriteLogEntries(ctx, &logpb.WriteLogEntriesRequest{ LogName: internal.LogPath(c.parent(), "ping"), Resource: &mrpb.MonitoredResource{Type: "global"}, Entries: []*logpb.LogEntry{ent}, }) return err }
func TestDeleteLog(t *testing.T) { initLogs(ctx) // Generate new testLogID // Write some log entries. ctx := context.Background() payloads := []string{"p1", "p2"} lg := client.Logger(testLogID) for _, p := range payloads { // Use the insert ID to guarantee iteration order. lg.Log(logging.Entry{Payload: p, InsertID: p}) } lg.Flush() var got []*logging.Entry ok := waitFor(func() bool { var err error got, err = allTestLogEntries(ctx) if err != nil { t.Log("fetching log entries: ", err) return false } return len(got) == 2 }) if !ok { t.Fatalf("timed out; got: %d, want: %d\n", len(got), 2) } // Sleep. // Write timestamp uses client-provided timestamp, delete uses server // timestamp. We sleep to reduce the possibility that the logs are never // "deleted" because of clock skew. // This is the recommended approach by Stackdriver team. time.Sleep(3 * time.Second) // Delete the log err := aclient.DeleteLog(ctx, testLogID) if err != nil { log.Fatalf("error deleting log: %v", err) } // DeleteLog can take some time to happen, so we wait for the log to // disappear. There is no direct way to determine if a log exists, so we // just wait until there are no log entries associated with the ID. filter := fmt.Sprintf(`logName = "%s"`, internal.LogPath("projects/"+testProjectID, testLogID)) ok = waitFor(func() bool { return countLogEntries(ctx, filter) == 0 }) if !ok { t.Fatalf("timed out waiting for log entries to be deleted") } }
// 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), }) }