@@ -244,7 +244,7 @@ type LoggerOption interface {
244244
245245// CommonResource sets the monitored resource associated with all log entries
246246// written from a Logger. If not provided, the resource is automatically
247- // detected based on the running environment (on GCE and GAE Standard only).
247+ // detected based on the running environment (on GCE, GCR, GCF and GAE Standard only).
248248// This value can be overridden per-entry by setting an Entry's Resource field.
249249func CommonResource (r * mrpb.MonitoredResource ) LoggerOption { return commonResource {r } }
250250
@@ -298,13 +298,81 @@ func detectGAEResource() *mrpb.MonitoredResource {
298298 }
299299}
300300
301+ func isCloudRun () bool {
302+ _ , config := os .LookupEnv ("K_CONFIGURATION" )
303+ _ , service := os .LookupEnv ("K_SERVICE" )
304+ _ , revision := os .LookupEnv ("K_REVISION" )
305+ return config && service && revision
306+ }
307+
308+ func detectCloudRunResource () * mrpb.MonitoredResource {
309+ projectID , err := metadata .ProjectID ()
310+ if err != nil {
311+ return nil
312+ }
313+ zone , err := metadata .Zone ()
314+ if err != nil {
315+ return nil
316+ }
317+ return & mrpb.MonitoredResource {
318+ Type : "cloud_run_revision" ,
319+ Labels : map [string ]string {
320+ "project_id" : projectID ,
321+ "location" : regionFromZone (zone ),
322+ "service_name" : os .Getenv ("K_SERVICE" ),
323+ "revision_name" : os .Getenv ("K_REVISION" ),
324+ "configuration_name" : os .Getenv ("K_CONFIGURATION" ),
325+ },
326+ }
327+ }
328+
329+ func isCloudFunction () bool {
330+ // Reserved envvars in older function runtimes, e.g. Node.js 8, Python 3.7 and Go 1.11.
331+ _ , name := os .LookupEnv ("FUNCTION_NAME" )
332+ _ , region := os .LookupEnv ("FUNCTION_REGION" )
333+ _ , entry := os .LookupEnv ("ENTRY_POINT" )
334+
335+ // Reserved envvars in newer function runtimes.
336+ _ , target := os .LookupEnv ("FUNCTION_TARGET" )
337+ _ , signature := os .LookupEnv ("FUNCTION_SIGNATURE_TYPE" )
338+ _ , service := os .LookupEnv ("K_SERVICE" )
339+ return (name && region && entry ) || (target && signature && service )
340+ }
341+
342+ func detectCloudFunction () * mrpb.MonitoredResource {
343+ projectID , err := metadata .ProjectID ()
344+ if err != nil {
345+ return nil
346+ }
347+ zone , err := metadata .Zone ()
348+ if err != nil {
349+ return nil
350+ }
351+ // Newer functions runtimes store name in K_SERVICE.
352+ functionName , exists := os .LookupEnv ("K_SERVICE" )
353+ if ! exists {
354+ functionName , _ = os .LookupEnv ("FUNCTION_NAME" )
355+ }
356+ return & mrpb.MonitoredResource {
357+ Type : "cloud_function" ,
358+ Labels : map [string ]string {
359+ "project_id" : projectID ,
360+ "region" : regionFromZone (zone ),
361+ "function_name" : functionName ,
362+ },
363+ }
364+ }
365+
301366func detectResource () * mrpb.MonitoredResource {
302367 detectedResource .once .Do (func () {
303368 switch {
304- // GAE needs to come first, as metadata.OnGCE() is actually true on GAE
305- // Second Gen runtimes.
369+ // AppEngine, Functions, CloudRun need to come first, as metadata.OnGCE() returns true on these runtimes.
306370 case os .Getenv ("GAE_ENV" ) == "standard" :
307371 detectedResource .pb = detectGAEResource ()
372+ case isCloudFunction ():
373+ detectedResource .pb = detectCloudFunction ()
374+ case isCloudRun ():
375+ detectedResource .pb = detectCloudRunResource ()
308376 case metadata .OnGCE ():
309377 detectedResource .pb = detectGCEResource ()
310378 }
@@ -334,6 +402,10 @@ func monitoredResource(parent string) *mrpb.MonitoredResource {
334402 }
335403}
336404
405+ func regionFromZone (zone string ) string {
406+ return zone [:strings .LastIndex (zone , "-" )]
407+ }
408+
337409func globalResource (projectID string ) * mrpb.MonitoredResource {
338410 return & mrpb.MonitoredResource {
339411 Type : "global" ,
0 commit comments