// 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 }
// newMessageIterator starts a new MessageIterator. Stop must be called on the MessageIterator // when it is no longer needed. // subName is the full name of the subscription to pull messages from. // ctx is the context to use for acking messages and extending message deadlines. func newMessageIterator(ctx context.Context, s service, subName string, po *pullOptions) *MessageIterator { // TODO: make kaTicker frequency more configurable. // (ackDeadline - 5s) is a reasonable default for now, because the minimum ack period is 10s. This gives us 5s grace. keepAlivePeriod := po.ackDeadline - 5*time.Second kaTicker := time.NewTicker(keepAlivePeriod) // Stopped in it.Stop // TODO: make ackTicker more configurable. Something less than // kaTicker is a reasonable default (there's no point extending // messages when they could be acked instead). ackTicker := time.NewTicker(keepAlivePeriod / 2) // Stopped in it.Stop ka := &keepAlive{ s: s, Ctx: ctx, Sub: subName, ExtensionTick: kaTicker.C, Deadline: po.ackDeadline, MaxExtension: po.maxExtension, } ack := &acker{ s: s, Ctx: ctx, Sub: subName, AckTick: ackTicker.C, Notify: ka.Remove, } nacker := bundler.NewBundler("", func(ackIDs interface{}) { // NACK by setting the ack deadline to zero, to make the message // immediately available for redelivery. // // If the RPC fails, nothing we can do about it. In the worst case, the // deadline for these messages will expire and they will still get // redelivered. _ = s.modifyAckDeadline(ctx, subName, 0, ackIDs.([]string)) }) nacker.DelayThreshold = keepAlivePeriod / 10 // nack promptly nacker.BundleCountThreshold = 10 pull := newPuller(s, subName, ctx, po.maxPrefetch, ka.Add, ka.Remove) ka.Start() ack.Start() return &MessageIterator{ kaTicker: kaTicker, ackTicker: ackTicker, ka: ka, acker: ack, nacker: nacker, puller: pull, closed: make(chan struct{}), } }
// NewClient creates a new Google Stackdriver Trace client. func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*Client, error) { o := []option.ClientOption{ option.WithScopes(cloudPlatformScope), option.WithUserAgent(userAgent), } o = append(o, opts...) hc, basePath, err := transport.NewHTTPClient(ctx, o...) if err != nil { return nil, fmt.Errorf("creating HTTP client for Google Stackdriver Trace API: %v", err) } apiService, err := api.New(hc) if err != nil { return nil, fmt.Errorf("creating Google Stackdriver Trace API client: %v", err) } if basePath != "" { // An option set a basepath, so override api.New's default. apiService.BasePath = basePath } c := &Client{ service: apiService, projectID: projectID, } bundler := bundler.NewBundler((*api.Trace)(nil), func(bundle interface{}) { traces := bundle.([]*api.Trace) err := c.upload(traces) if err != nil { log.Printf("failed to upload %d traces to the Cloud Trace server.", len(traces)) } }) bundler.DelayThreshold = 2 * time.Second bundler.BundleCountThreshold = 100 // We're not measuring bytes here, we're counting traces and spans as one "byte" each. bundler.BundleByteThreshold = 1000 bundler.BundleByteLimit = 1000 bundler.BufferedByteLimit = 10000 c.bundler = bundler return c, nil }