| // Copyright 2021 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 |
| // |
| // https://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 logging |
| |
| import ( |
| "context" |
| "io" |
| "os" |
| "time" |
| ) |
| |
| // LoggerOption is a configuration option for a Logger. |
| type LoggerOption interface { |
| set(*Logger) |
| } |
| |
| // CommonLabels are labels that apply to all log entries written from a Logger, |
| // so that you don't have to repeat them in each log entry's Labels field. If |
| // any of the log entries contains a (key, value) with the same key that is in |
| // CommonLabels, then the entry's (key, value) overrides the one in |
| // CommonLabels. |
| func CommonLabels(m map[string]string) LoggerOption { return commonLabels(m) } |
| |
| type commonLabels map[string]string |
| |
| func (c commonLabels) set(l *Logger) { l.commonLabels = c } |
| |
| // ConcurrentWriteLimit determines how many goroutines will send log entries to the |
| // underlying service. The default is 1. Set ConcurrentWriteLimit to a higher value to |
| // increase throughput. |
| func ConcurrentWriteLimit(n int) LoggerOption { return concurrentWriteLimit(n) } |
| |
| type concurrentWriteLimit int |
| |
| func (c concurrentWriteLimit) set(l *Logger) { l.bundler.HandlerLimit = int(c) } |
| |
| // DelayThreshold is the maximum amount of time that an entry should remain |
| // buffered in memory before a call to the logging service is triggered. Larger |
| // values of DelayThreshold will generally result in fewer calls to the logging |
| // service, while increasing the risk that log entries will be lost if the |
| // process crashes. |
| // The default is DefaultDelayThreshold. |
| func DelayThreshold(d time.Duration) LoggerOption { return delayThreshold(d) } |
| |
| type delayThreshold time.Duration |
| |
| func (d delayThreshold) set(l *Logger) { l.bundler.DelayThreshold = time.Duration(d) } |
| |
| // EntryCountThreshold is the maximum number of entries that will be buffered |
| // in memory before a call to the logging service is triggered. Larger values |
| // will generally result in fewer calls to the logging service, while |
| // increasing both memory consumption and the risk that log entries will be |
| // lost if the process crashes. |
| // The default is DefaultEntryCountThreshold. |
| func EntryCountThreshold(n int) LoggerOption { return entryCountThreshold(n) } |
| |
| type entryCountThreshold int |
| |
| func (e entryCountThreshold) set(l *Logger) { l.bundler.BundleCountThreshold = int(e) } |
| |
| // EntryByteThreshold is the maximum number of bytes of entries that will be |
| // buffered in memory before a call to the logging service is triggered. See |
| // EntryCountThreshold for a discussion of the tradeoffs involved in setting |
| // this option. |
| // The default is DefaultEntryByteThreshold. |
| func EntryByteThreshold(n int) LoggerOption { return entryByteThreshold(n) } |
| |
| type entryByteThreshold int |
| |
| func (e entryByteThreshold) set(l *Logger) { l.bundler.BundleByteThreshold = int(e) } |
| |
| // EntryByteLimit is the maximum number of bytes of entries that will be sent |
| // in a single call to the logging service. ErrOversizedEntry is returned if an |
| // entry exceeds EntryByteLimit. This option limits the size of a single RPC |
| // payload, to account for network or service issues with large RPCs. If |
| // EntryByteLimit is smaller than EntryByteThreshold, the latter has no effect. |
| // The default is zero, meaning there is no limit. |
| func EntryByteLimit(n int) LoggerOption { return entryByteLimit(n) } |
| |
| type entryByteLimit int |
| |
| func (e entryByteLimit) set(l *Logger) { l.bundler.BundleByteLimit = int(e) } |
| |
| // BufferedByteLimit is the maximum number of bytes that the Logger will keep |
| // in memory before returning ErrOverflow. This option limits the total memory |
| // consumption of the Logger (but note that each Logger has its own, separate |
| // limit). It is possible to reach BufferedByteLimit even if it is larger than |
| // EntryByteThreshold or EntryByteLimit, because calls triggered by the latter |
| // two options may be enqueued (and hence occupying memory) while new log |
| // entries are being added. |
| // The default is DefaultBufferedByteLimit. |
| func BufferedByteLimit(n int) LoggerOption { return bufferedByteLimit(n) } |
| |
| type bufferedByteLimit int |
| |
| func (b bufferedByteLimit) set(l *Logger) { l.bundler.BufferedByteLimit = int(b) } |
| |
| // ContextFunc is a function that will be called to obtain a context.Context for the |
| // WriteLogEntries RPC executed in the background for calls to Logger.Log. The |
| // default is a function that always returns context.Background. The second return |
| // value of the function is a function to call after the RPC completes. |
| // |
| // The function is not used for calls to Logger.LogSync, since the caller can pass |
| // in the context directly. |
| // |
| // This option is EXPERIMENTAL. It may be changed or removed. |
| func ContextFunc(f func() (ctx context.Context, afterCall func())) LoggerOption { |
| return contextFunc(f) |
| } |
| |
| type contextFunc func() (ctx context.Context, afterCall func()) |
| |
| func (c contextFunc) set(l *Logger) { l.ctxFunc = c } |
| |
| // SourceLocationPopulation is the flag controlling population of the source location info |
| // in the ingested entries. This options allows to configure automatic population of the |
| // SourceLocation field for all ingested entries, entries with DEBUG severity or disable it. |
| // Note that enabling this option can decrease execution time of Logger.Log and Logger.LogSync |
| // by the factor of 2 or larger. |
| // The default disables source location population. |
| // |
| // This option is not used when an entry is created using ToLogEntry. |
| func SourceLocationPopulation(f int) LoggerOption { |
| return sourceLocationOption(f) |
| } |
| |
| const ( |
| // DoNotPopulateSourceLocation is default for clients when WithSourceLocation is not provided |
| DoNotPopulateSourceLocation = 0 |
| // PopulateSourceLocationForDebugEntries is set when WithSourceLocation(PopulateDebugEntries) is provided |
| PopulateSourceLocationForDebugEntries = 1 |
| // AlwaysPopulateSourceLocation is set when WithSourceLocation(PopulateAllEntries) is provided |
| AlwaysPopulateSourceLocation = 2 |
| ) |
| |
| type sourceLocationOption int |
| |
| func (o sourceLocationOption) set(l *Logger) { |
| if o == DoNotPopulateSourceLocation || o == PopulateSourceLocationForDebugEntries || o == AlwaysPopulateSourceLocation { |
| l.populateSourceLocation = int(o) |
| } |
| } |
| |
| // PartialSuccess sets the partialSuccess flag to true when ingesting a bundle of log entries. |
| // See https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write#body.request_body.FIELDS.partial_success |
| // If not provided the partialSuccess flag is set to false. |
| func PartialSuccess() LoggerOption { |
| return &partialSuccessOption{} |
| } |
| |
| type partialSuccessOption struct{} |
| |
| func (o *partialSuccessOption) set(l *Logger) { |
| l.partialSuccess = true |
| } |
| |
| // RedirectAsJSON instructs Logger to redirect output of calls to Log and LogSync to provided io.Writer instead of ingesting |
| // to Cloud Logging. Logger formats log entries following logging agent's Json format. |
| // See https://cloud.google.com/logging/docs/structured-logging#special-payload-fields for more info about the format. |
| // Use this option to delegate log ingestion to an out-of-process logging agent. |
| // If no writer is provided, the redirect is set to stdout. |
| func RedirectAsJSON(w io.Writer) LoggerOption { |
| if w == nil { |
| w = os.Stdout |
| } |
| return &redirectOutputOption{ |
| writer: w, |
| } |
| } |
| |
| type redirectOutputOption struct { |
| writer io.Writer |
| } |
| |
| func (o *redirectOutputOption) set(l *Logger) { |
| l.redirectOutputWriter = o.writer |
| } |