loggeroption.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2021 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package logging
  15. import (
  16. "context"
  17. "io"
  18. "os"
  19. "time"
  20. )
  21. // LoggerOption is a configuration option for a Logger.
  22. type LoggerOption interface {
  23. set(*Logger)
  24. }
  25. // CommonLabels are labels that apply to all log entries written from a Logger,
  26. // so that you don't have to repeat them in each log entry's Labels field. If
  27. // any of the log entries contains a (key, value) with the same key that is in
  28. // CommonLabels, then the entry's (key, value) overrides the one in
  29. // CommonLabels.
  30. func CommonLabels(m map[string]string) LoggerOption { return commonLabels(m) }
  31. type commonLabels map[string]string
  32. func (c commonLabels) set(l *Logger) { l.commonLabels = c }
  33. // ConcurrentWriteLimit determines how many goroutines will send log entries to the
  34. // underlying service. The default is 1. Set ConcurrentWriteLimit to a higher value to
  35. // increase throughput.
  36. func ConcurrentWriteLimit(n int) LoggerOption { return concurrentWriteLimit(n) }
  37. type concurrentWriteLimit int
  38. func (c concurrentWriteLimit) set(l *Logger) { l.bundler.HandlerLimit = int(c) }
  39. // DelayThreshold is the maximum amount of time that an entry should remain
  40. // buffered in memory before a call to the logging service is triggered. Larger
  41. // values of DelayThreshold will generally result in fewer calls to the logging
  42. // service, while increasing the risk that log entries will be lost if the
  43. // process crashes.
  44. // The default is DefaultDelayThreshold.
  45. func DelayThreshold(d time.Duration) LoggerOption { return delayThreshold(d) }
  46. type delayThreshold time.Duration
  47. func (d delayThreshold) set(l *Logger) { l.bundler.DelayThreshold = time.Duration(d) }
  48. // EntryCountThreshold is the maximum number of entries that will be buffered
  49. // in memory before a call to the logging service is triggered. Larger values
  50. // will generally result in fewer calls to the logging service, while
  51. // increasing both memory consumption and the risk that log entries will be
  52. // lost if the process crashes.
  53. // The default is DefaultEntryCountThreshold.
  54. func EntryCountThreshold(n int) LoggerOption { return entryCountThreshold(n) }
  55. type entryCountThreshold int
  56. func (e entryCountThreshold) set(l *Logger) { l.bundler.BundleCountThreshold = int(e) }
  57. // EntryByteThreshold is the maximum number of bytes of entries that will be
  58. // buffered in memory before a call to the logging service is triggered. See
  59. // EntryCountThreshold for a discussion of the tradeoffs involved in setting
  60. // this option.
  61. // The default is DefaultEntryByteThreshold.
  62. func EntryByteThreshold(n int) LoggerOption { return entryByteThreshold(n) }
  63. type entryByteThreshold int
  64. func (e entryByteThreshold) set(l *Logger) { l.bundler.BundleByteThreshold = int(e) }
  65. // EntryByteLimit is the maximum number of bytes of entries that will be sent
  66. // in a single call to the logging service. ErrOversizedEntry is returned if an
  67. // entry exceeds EntryByteLimit. This option limits the size of a single RPC
  68. // payload, to account for network or service issues with large RPCs. If
  69. // EntryByteLimit is smaller than EntryByteThreshold, the latter has no effect.
  70. // The default is zero, meaning there is no limit.
  71. func EntryByteLimit(n int) LoggerOption { return entryByteLimit(n) }
  72. type entryByteLimit int
  73. func (e entryByteLimit) set(l *Logger) { l.bundler.BundleByteLimit = int(e) }
  74. // BufferedByteLimit is the maximum number of bytes that the Logger will keep
  75. // in memory before returning ErrOverflow. This option limits the total memory
  76. // consumption of the Logger (but note that each Logger has its own, separate
  77. // limit). It is possible to reach BufferedByteLimit even if it is larger than
  78. // EntryByteThreshold or EntryByteLimit, because calls triggered by the latter
  79. // two options may be enqueued (and hence occupying memory) while new log
  80. // entries are being added.
  81. // The default is DefaultBufferedByteLimit.
  82. func BufferedByteLimit(n int) LoggerOption { return bufferedByteLimit(n) }
  83. type bufferedByteLimit int
  84. func (b bufferedByteLimit) set(l *Logger) { l.bundler.BufferedByteLimit = int(b) }
  85. // ContextFunc is a function that will be called to obtain a context.Context for the
  86. // WriteLogEntries RPC executed in the background for calls to Logger.Log. The
  87. // default is a function that always returns context.Background. The second return
  88. // value of the function is a function to call after the RPC completes.
  89. //
  90. // The function is not used for calls to Logger.LogSync, since the caller can pass
  91. // in the context directly.
  92. //
  93. // This option is EXPERIMENTAL. It may be changed or removed.
  94. func ContextFunc(f func() (ctx context.Context, afterCall func())) LoggerOption {
  95. return contextFunc(f)
  96. }
  97. type contextFunc func() (ctx context.Context, afterCall func())
  98. func (c contextFunc) set(l *Logger) { l.ctxFunc = c }
  99. // SourceLocationPopulation is the flag controlling population of the source location info
  100. // in the ingested entries. This options allows to configure automatic population of the
  101. // SourceLocation field for all ingested entries, entries with DEBUG severity or disable it.
  102. // Note that enabling this option can decrease execution time of Logger.Log and Logger.LogSync
  103. // by the factor of 2 or larger.
  104. // The default disables source location population.
  105. //
  106. // This option is not used when an entry is created using ToLogEntry.
  107. func SourceLocationPopulation(f int) LoggerOption {
  108. return sourceLocationOption(f)
  109. }
  110. const (
  111. // DoNotPopulateSourceLocation is default for clients when WithSourceLocation is not provided
  112. DoNotPopulateSourceLocation = 0
  113. // PopulateSourceLocationForDebugEntries is set when WithSourceLocation(PopulateDebugEntries) is provided
  114. PopulateSourceLocationForDebugEntries = 1
  115. // AlwaysPopulateSourceLocation is set when WithSourceLocation(PopulateAllEntries) is provided
  116. AlwaysPopulateSourceLocation = 2
  117. )
  118. type sourceLocationOption int
  119. func (o sourceLocationOption) set(l *Logger) {
  120. if o == DoNotPopulateSourceLocation || o == PopulateSourceLocationForDebugEntries || o == AlwaysPopulateSourceLocation {
  121. l.populateSourceLocation = int(o)
  122. }
  123. }
  124. // PartialSuccess sets the partialSuccess flag to true when ingesting a bundle of log entries.
  125. // See https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write#body.request_body.FIELDS.partial_success
  126. // If not provided the partialSuccess flag is set to false.
  127. func PartialSuccess() LoggerOption {
  128. return &partialSuccessOption{}
  129. }
  130. type partialSuccessOption struct{}
  131. func (o *partialSuccessOption) set(l *Logger) {
  132. l.partialSuccess = true
  133. }
  134. // RedirectAsJSON instructs Logger to redirect output of calls to Log and LogSync to provided io.Writer instead of ingesting
  135. // to Cloud Logging. Logger formats log entries following logging agent's Json format.
  136. // See https://cloud.google.com/logging/docs/structured-logging#special-payload-fields for more info about the format.
  137. // Use this option to delegate log ingestion to an out-of-process logging agent.
  138. // If no writer is provided, the redirect is set to stdout.
  139. func RedirectAsJSON(w io.Writer) LoggerOption {
  140. if w == nil {
  141. w = os.Stdout
  142. }
  143. return &redirectOutputOption{
  144. writer: w,
  145. }
  146. }
  147. type redirectOutputOption struct {
  148. writer io.Writer
  149. }
  150. func (o *redirectOutputOption) set(l *Logger) {
  151. l.redirectOutputWriter = o.writer
  152. }