google-cloud-logging 0.20.1 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,6 +25,16 @@ module Google
25
25
  PATH_ENV_VARS = %w(LOGGING_KEYFILE GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
26
26
  JSON_ENV_VARS = %w(LOGGING_KEYFILE_JSON GOOGLE_CLOUD_KEYFILE_JSON
27
27
  GCLOUD_KEYFILE_JSON)
28
+
29
+ ##
30
+ # @private Create credentials with given scope and/or keyfile
31
+ def self.credentials_with_scope keyfile, scope = nil
32
+ if keyfile.nil?
33
+ default(scope: scope)
34
+ else
35
+ new(keyfile, scope: scope)
36
+ end
37
+ end
28
38
  end
29
39
  end
30
40
  end
@@ -39,16 +39,15 @@ module Google
39
39
  # applications. For example, the log `compute.googleapis.com/activity_log`
40
40
  # is produced by Google Compute Engine. Logs are simply referenced by name
41
41
  # in google-cloud. There is no `Log` type in google-cloud or `Log`
42
- # resource in the Cloud Logging API.
42
+ # resource in the Stackdriver Logging API.
43
43
  #
44
44
  # @see https://cloud.google.com/logging/docs/view/logs_index List of Log
45
45
  # Types
46
46
  #
47
47
  # @example
48
- # require "google/cloud"
48
+ # require "google/cloud/logging"
49
49
  #
50
- # gcloud = Google::Cloud.new
51
- # logging = gcloud.logging
50
+ # logging = Google::Cloud::Logging.new
52
51
  #
53
52
  # entry = logging.entry payload: "Job started.", log_name: "my_app_log"
54
53
  # entry.resource.type = "gae_app"
@@ -112,10 +111,9 @@ module Google
112
111
  # Sets the severity level to `:DEFAULT`.
113
112
  #
114
113
  # @example
115
- # require "google/cloud"
114
+ # require "google/cloud/logging"
116
115
  #
117
- # gcloud = Google::Cloud.new
118
- # logging = gcloud.logging
116
+ # logging = Google::Cloud::Logging.new
119
117
  #
120
118
  # entry = logging.entry
121
119
  # entry.severity = :DEBUG
@@ -137,10 +135,9 @@ module Google
137
135
  # Sets the severity level to `:DEBUG`.
138
136
  #
139
137
  # @example
140
- # require "google/cloud"
138
+ # require "google/cloud/logging"
141
139
  #
142
- # gcloud = Google::Cloud.new
143
- # logging = gcloud.logging
140
+ # logging = Google::Cloud::Logging.new
144
141
  #
145
142
  # entry = logging.entry
146
143
  # entry.severity #=> :DEFAULT
@@ -162,10 +159,9 @@ module Google
162
159
  # Sets the severity level to `:INFO`.
163
160
  #
164
161
  # @example
165
- # require "google/cloud"
162
+ # require "google/cloud/logging"
166
163
  #
167
- # gcloud = Google::Cloud.new
168
- # logging = gcloud.logging
164
+ # logging = Google::Cloud::Logging.new
169
165
  #
170
166
  # entry = logging.entry
171
167
  # entry.severity #=> :DEFAULT
@@ -187,10 +183,9 @@ module Google
187
183
  # Sets the severity level to `:NOTICE`.
188
184
  #
189
185
  # @example
190
- # require "google/cloud"
186
+ # require "google/cloud/logging"
191
187
  #
192
- # gcloud = Google::Cloud.new
193
- # logging = gcloud.logging
188
+ # logging = Google::Cloud::Logging.new
194
189
  #
195
190
  # entry = logging.entry
196
191
  # entry.severity #=> :DEFAULT
@@ -212,10 +207,9 @@ module Google
212
207
  # Sets the severity level to `:WARNING`.
213
208
  #
214
209
  # @example
215
- # require "google/cloud"
210
+ # require "google/cloud/logging"
216
211
  #
217
- # gcloud = Google::Cloud.new
218
- # logging = gcloud.logging
212
+ # logging = Google::Cloud::Logging.new
219
213
  #
220
214
  # entry = logging.entry
221
215
  # entry.severity #=> :DEFAULT
@@ -237,10 +231,9 @@ module Google
237
231
  # Sets the severity level to `:ERROR`.
238
232
  #
239
233
  # @example
240
- # require "google/cloud"
234
+ # require "google/cloud/logging"
241
235
  #
242
- # gcloud = Google::Cloud.new
243
- # logging = gcloud.logging
236
+ # logging = Google::Cloud::Logging.new
244
237
  #
245
238
  # entry = logging.entry
246
239
  # entry.severity #=> :DEFAULT
@@ -262,10 +255,9 @@ module Google
262
255
  # Sets the severity level to `:CRITICAL`.
263
256
  #
264
257
  # @example
265
- # require "google/cloud"
258
+ # require "google/cloud/logging"
266
259
  #
267
- # gcloud = Google::Cloud.new
268
- # logging = gcloud.logging
260
+ # logging = Google::Cloud::Logging.new
269
261
  #
270
262
  # entry = logging.entry
271
263
  # entry.severity #=> :DEFAULT
@@ -287,10 +279,9 @@ module Google
287
279
  # Sets the severity level to `:ALERT`.
288
280
  #
289
281
  # @example
290
- # require "google/cloud"
282
+ # require "google/cloud/logging"
291
283
  #
292
- # gcloud = Google::Cloud.new
293
- # logging = gcloud.logging
284
+ # logging = Google::Cloud::Logging.new
294
285
  #
295
286
  # entry = logging.entry
296
287
  # entry.severity #=> :DEFAULT
@@ -312,10 +303,9 @@ module Google
312
303
  # Sets the severity level to `:EMERGENCY`.
313
304
  #
314
305
  # @example
315
- # require "google/cloud"
306
+ # require "google/cloud/logging"
316
307
  #
317
- # gcloud = Google::Cloud.new
318
- # logging = gcloud.logging
308
+ # logging = Google::Cloud::Logging.new
319
309
  #
320
310
  # entry = logging.entry
321
311
  # entry.severity #=> :DEFAULT
@@ -461,7 +451,7 @@ module Google
461
451
  # @private Get a Time object from a Google::Protobuf::Timestamp object.
462
452
  def self.extract_timestamp grpc
463
453
  return nil if grpc.timestamp.nil?
464
- Time.at grpc.timestamp.seconds, grpc.timestamp.nanos/1000.0
454
+ Time.at grpc.timestamp.seconds, Rational(grpc.timestamp.nanos, 1000)
465
455
  end
466
456
  end
467
457
  end
@@ -39,10 +39,9 @@ module Google
39
39
  # @return [Boolean]
40
40
  #
41
41
  # @example
42
- # require "google/cloud"
42
+ # require "google/cloud/logging"
43
43
  #
44
- # gcloud = Google::Cloud.new
45
- # logging = gcloud.logging
44
+ # logging = Google::Cloud::Logging.new
46
45
  #
47
46
  # entries = logging.entries
48
47
  # if entries.next?
@@ -59,10 +58,9 @@ module Google
59
58
  # @return [Sink::List]
60
59
  #
61
60
  # @example
62
- # require "google/cloud"
61
+ # require "google/cloud/logging"
63
62
  #
64
- # gcloud = Google::Cloud.new
65
- # logging = gcloud.logging
63
+ # logging = Google::Cloud::Logging.new
66
64
  #
67
65
  # entries = dataset.entries
68
66
  # if entries.next?
@@ -97,10 +95,9 @@ module Google
97
95
  # @return [Enumerator]
98
96
  #
99
97
  # @example Iterating each log entry by passing a block:
100
- # require "google/cloud"
98
+ # require "google/cloud/logging"
101
99
  #
102
- # gcloud = Google::Cloud.new
103
- # logging = gcloud.logging
100
+ # logging = Google::Cloud::Logging.new
104
101
  # entries = logging.entries order: "timestamp desc"
105
102
  #
106
103
  # entries.all do |entry|
@@ -108,10 +105,9 @@ module Google
108
105
  # end
109
106
  #
110
107
  # @example Using the enumerator by not passing a block:
111
- # require "google/cloud"
108
+ # require "google/cloud/logging"
112
109
  #
113
- # gcloud = Google::Cloud.new
114
- # logging = gcloud.logging
110
+ # logging = Google::Cloud::Logging.new
115
111
  # entries = logging.entries order: "timestamp desc"
116
112
  #
117
113
  # all_payloads = entries.all.map do |entry|
@@ -119,10 +115,9 @@ module Google
119
115
  # end
120
116
  #
121
117
  # @example Limit the number of API calls made:
122
- # require "google/cloud"
118
+ # require "google/cloud/logging"
123
119
  #
124
- # gcloud = Google::Cloud.new
125
- # logging = gcloud.logging
120
+ # logging = Google::Cloud::Logging.new
126
121
  # entries = logging.entries order: "timestamp desc"
127
122
  #
128
123
  # entries.all(request_limit: 10) do |entry|
@@ -13,6 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
+ require "orderedhash"
17
+
16
18
  module Google
17
19
  module Cloud
18
20
  module Logging
@@ -22,10 +24,9 @@ module Google
22
24
  # A (mostly) API-compatible logger for ruby's Logger.
23
25
  #
24
26
  # @example
25
- # require "google/cloud"
27
+ # require "google/cloud/logging"
26
28
  #
27
- # gcloud = Google::Cloud.new
28
- # logging = gcloud.logging
29
+ # logging = Google::Cloud::Logging.new
29
30
  #
30
31
  # resource = logging.resource "gae_app",
31
32
  # module_id: "1",
@@ -36,29 +37,71 @@ module Google
36
37
  #
37
38
  class Logger
38
39
  ##
39
- # @private The logging object.
40
- attr_accessor :logging
40
+ # The Google Cloud writer object that calls to {#write_entries} are made
41
+ # on. Either an AsyncWriter or Project object.
42
+ attr_reader :writer
41
43
 
42
44
  ##
43
- # @private The Google Cloud log_name to write the log entry with.
45
+ # The Google Cloud log_name to write the log entry with.
44
46
  attr_reader :log_name
45
47
 
46
48
  ##
47
- # @private The Google Cloud resource to write the log entry with.
49
+ # The Google Cloud resource to write the log entry with.
48
50
  attr_reader :resource
49
51
 
50
52
  ##
51
- # @private The Google Cloud labels to write the log entry with.
53
+ # The Google Cloud labels to write the log entry with.
52
54
  attr_reader :labels
53
55
 
54
56
  ##
55
- # @private Creates a new Logger instance.
56
- def initialize logging, log_name, resource, labels = nil
57
- @logging = logging
57
+ # A OrderedHash of Thread IDs to Stackdriver request trace ID. The
58
+ # Stackdriver trace ID is a shared request identifier across all
59
+ # Stackdriver services.
60
+ attr_reader :trace_ids
61
+
62
+ ##
63
+ # Create a new Logger instance.
64
+ #
65
+ # @param [#write_entries] writer The object that will transmit log
66
+ # entries. Generally, to create a logger that blocks on transmitting
67
+ # log entries, pass the Project; otherwise, to create a logger that
68
+ # transmits log entries in the background, pass an AsyncWriter. You
69
+ # may also pass any other object that responds to #write_entries.
70
+ # @param [String] log_name A log resource name to be associated with the
71
+ # written log entries.
72
+ # @param [Google::Cloud::Logging::Resource] resource The monitored
73
+ # resource to be associated with written log entries.
74
+ # @param [Hash] labels A set of user-defined data to be associated with
75
+ # written log entries.
76
+ #
77
+ # @return [Google::Cloud::Logging::Logger] a Logger object that can be
78
+ # used in place of a ruby standard library logger object.
79
+ #
80
+ # @example
81
+ # require "google/cloud/logging"
82
+ #
83
+ # logging = Google::Cloud::Logging.new
84
+ #
85
+ # writer = logging.async_writer max_queue_size: 1000
86
+ #
87
+ # resource = logging.resource "gae_app", labels: {
88
+ # "module_id" => "1",
89
+ # "version_id" => "20150925t173233" }
90
+ # }
91
+ #
92
+ # logger = Google::Cloud::Logging::Logger.new writer,
93
+ # "my_app_log",
94
+ # resource,
95
+ # env: :production
96
+ # logger.info "Job started."
97
+ #
98
+ def initialize writer, log_name, resource, labels = nil
99
+ @writer = writer
58
100
  @log_name = log_name
59
101
  @resource = resource
60
102
  @labels = labels
61
103
  @level = 0 # DEBUG is the default behavior
104
+ @trace_ids = OrderedHash.new
62
105
  end
63
106
 
64
107
  ##
@@ -243,10 +286,9 @@ module Google
243
286
  # name of the severity level
244
287
  #
245
288
  # @example
246
- # require "google/cloud"
289
+ # require "google/cloud/logging"
247
290
  #
248
- # gcloud = Google::Cloud.new
249
- # logging = gcloud.logging
291
+ # logging = Google::Cloud::Logging.new
250
292
  #
251
293
  # resource = logging.resource "gae_app",
252
294
  # module_id: "1",
@@ -264,19 +306,46 @@ module Google
264
306
  end
265
307
  alias_method :sev_threshold=, :level=
266
308
 
309
+ ##
310
+ # Track a given trace_id by associating it with the current
311
+ # Thread
312
+ #
313
+ # @param [String] trace_id The HTTP_X_CLOUD_TRACE_CONTEXT HTTP request
314
+ # header that's shared and tracked by all Stackdriver services
315
+ def add_trace_id trace_id
316
+ trace_ids[current_thread_id] = trace_id
317
+
318
+ # Start removing old entries if hash gets too large.
319
+ # This should never happen, because middleware should automatically
320
+ # remove entries when a request is finished
321
+ trace_ids.shift if trace_ids.size > 10_000
322
+ end
323
+
324
+ ##
325
+ # Untrack the trace_id that's associated with current Thread
326
+ #
327
+ # @return The trace_id that's being deleted
328
+ def delete_trace_id
329
+ trace_ids.delete current_thread_id
330
+ end
331
+
267
332
  protected
268
333
 
269
334
  ##
270
335
  # @private Write a log entry to the Stackdriver Logging service.
271
336
  def write_entry severity, message
272
- entry = logging.entry.tap do |e|
337
+ entry = Entry.new.tap do |e|
273
338
  e.severity = gcloud_severity(severity)
274
339
  e.payload = message
275
340
  end
276
341
 
277
- logging.write_entries entry, log_name: log_name,
278
- resource: resource,
279
- labels: labels
342
+ # merge input labels and trace_id
343
+ trace_id = trace_ids[current_thread_id]
344
+ merged_labels = trace_id.nil? ? {} : { traceId: trace_id }
345
+ merged_labels = labels.merge(merged_labels) unless labels.nil?
346
+
347
+ writer.write_entries entry, log_name: log_name, resource: resource,
348
+ labels: merged_labels
280
349
  end
281
350
 
282
351
  ##
@@ -303,6 +372,12 @@ module Google
303
372
  rescue
304
373
  :DEFAULT
305
374
  end
375
+
376
+ ##
377
+ # @private Get current thread id
378
+ def current_thread_id
379
+ Thread.current.object_id
380
+ end
306
381
  end
307
382
  end
308
383
  end
@@ -32,10 +32,9 @@ module Google
32
32
  # @see https://cloud.google.com/monitoring/docs Google Cloud Monitoring
33
33
  #
34
34
  # @example
35
- # require "google/cloud"
35
+ # require "google/cloud/logging"
36
36
  #
37
- # gcloud = Google::Cloud.new
38
- # logging = gcloud.logging
37
+ # logging = Google::Cloud::Logging.new
39
38
  # metric = logging.create_metric "errors", "severity>=ERROR"
40
39
  #
41
40
  class Metric
@@ -95,10 +94,9 @@ module Google
95
94
  # Updates the logs-based metric.
96
95
  #
97
96
  # @example
98
- # require "google/cloud"
97
+ # require "google/cloud/logging"
99
98
  #
100
- # gcloud = Google::Cloud.new
101
- # logging = gcloud.logging
99
+ # logging = Google::Cloud::Logging.new
102
100
  # metric = logging.metric "severe_errors"
103
101
  # metric.filter = "logName:syslog AND severity>=ERROR"
104
102
  # metric.save
@@ -114,10 +112,9 @@ module Google
114
112
  # service.
115
113
  #
116
114
  # @example
117
- # require "google/cloud"
115
+ # require "google/cloud/logging"
118
116
  #
119
- # gcloud = Google::Cloud.new
120
- # logging = gcloud.logging
117
+ # logging = Google::Cloud::Logging.new
121
118
  # metric = logging.metric "severe_errors"
122
119
  # metric.filter = "Unwanted value"
123
120
  # metric.reload!
@@ -136,10 +133,9 @@ module Google
136
133
  # @return [Boolean] Returns `true` if the metric was deleted.
137
134
  #
138
135
  # @example
139
- # require "google/cloud"
136
+ # require "google/cloud/logging"
140
137
  #
141
- # gcloud = Google::Cloud.new
142
- # logging = gcloud.logging
138
+ # logging = Google::Cloud::Logging.new
143
139
  # metric = logging.metric "severe_errors"
144
140
  # metric.delete
145
141
  #
@@ -40,10 +40,9 @@ module Google
40
40
  # @return [Boolean]
41
41
  #
42
42
  # @example
43
- # require "google/cloud"
43
+ # require "google/cloud/logging"
44
44
  #
45
- # gcloud = Google::Cloud.new
46
- # logging = gcloud.logging
45
+ # logging = Google::Cloud::Logging.new
47
46
  #
48
47
  # metrics = logging.metrics
49
48
  # if metrics.next?
@@ -60,10 +59,9 @@ module Google
60
59
  # @return [Sink::List]
61
60
  #
62
61
  # @example
63
- # require "google/cloud"
62
+ # require "google/cloud/logging"
64
63
  #
65
- # gcloud = Google::Cloud.new
66
- # logging = gcloud.logging
64
+ # logging = Google::Cloud::Logging.new
67
65
  #
68
66
  # metrics = dataset.metrics
69
67
  # if metrics.next?
@@ -96,10 +94,9 @@ module Google
96
94
  # @return [Enumerator]
97
95
  #
98
96
  # @example Iterating each metric by passing a block:
99
- # require "google/cloud"
97
+ # require "google/cloud/logging"
100
98
  #
101
- # gcloud = Google::Cloud.new
102
- # logging = gcloud.logging
99
+ # logging = Google::Cloud::Logging.new
103
100
  # metrics = logging.metrics
104
101
  #
105
102
  # metrics.all do |metric|
@@ -107,10 +104,9 @@ module Google
107
104
  # end
108
105
  #
109
106
  # @example Using the enumerator by not passing a block:
110
- # require "google/cloud"
107
+ # require "google/cloud/logging"
111
108
  #
112
- # gcloud = Google::Cloud.new
113
- # logging = gcloud.logging
109
+ # logging = Google::Cloud::Logging.new
114
110
  # metrics = logging.metrics
115
111
  #
116
112
  # all_names = metrics.all.map do |metric|
@@ -118,10 +114,9 @@ module Google
118
114
  # end
119
115
  #
120
116
  # @example Limit the number of API calls made:
121
- # require "google/cloud"
117
+ # require "google/cloud/logging"
122
118
  #
123
- # gcloud = Google::Cloud.new
124
- # logging = gcloud.logging
119
+ # logging = Google::Cloud::Logging.new
125
120
  # metrics = logging.metrics
126
121
  #
127
122
  # metrics.all(request_limit: 10) do |metric|