Skip to content

Commit a2538e1

Browse files
authored
fix(logging): correctly detect GKE resource (#4092)
* fix(logging): gke resource autodetection * fix: detect gke resource correctly * chore: remove podname and namespace labels not supported * feat: detect podname from HOSTNAME envvar * feat: add resource.namespace_name * feat: add container name to resource.labels
1 parent 1246717 commit a2538e1

2 files changed

Lines changed: 268 additions & 202 deletions

File tree

logging/logging.go

Lines changed: 0 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,13 @@ import (
3232
"fmt"
3333
"log"
3434
"net/http"
35-
"os"
3635
"regexp"
3736
"strconv"
3837
"strings"
3938
"sync"
4039
"time"
4140
"unicode/utf8"
4241

43-
"cloud.google.com/go/compute/metadata"
4442
"cloud.google.com/go/internal/version"
4543
vkit "cloud.google.com/go/logging/apiv2"
4644
"cloud.google.com/go/logging/internal"
@@ -242,206 +240,6 @@ type LoggerOption interface {
242240
set(*Logger)
243241
}
244242

245-
// CommonResource sets the monitored resource associated with all log entries
246-
// written from a Logger. If not provided, the resource is automatically
247-
// detected based on the running environment (on GCE, GCR, GCF and GAE Standard only).
248-
// This value can be overridden per-entry by setting an Entry's Resource field.
249-
func CommonResource(r *mrpb.MonitoredResource) LoggerOption { return commonResource{r} }
250-
251-
type commonResource struct{ *mrpb.MonitoredResource }
252-
253-
func (r commonResource) set(l *Logger) { l.commonResource = r.MonitoredResource }
254-
255-
var detectedResource struct {
256-
pb *mrpb.MonitoredResource
257-
once sync.Once
258-
}
259-
260-
func detectGCEResource() *mrpb.MonitoredResource {
261-
projectID, err := metadata.ProjectID()
262-
if err != nil {
263-
return nil
264-
}
265-
id, err := metadata.InstanceID()
266-
if err != nil {
267-
return nil
268-
}
269-
zone, err := metadata.Zone()
270-
if err != nil {
271-
return nil
272-
}
273-
name, err := metadata.InstanceName()
274-
if err != nil {
275-
return nil
276-
}
277-
return &mrpb.MonitoredResource{
278-
Type: "gce_instance",
279-
Labels: map[string]string{
280-
"project_id": projectID,
281-
"instance_id": id,
282-
"instance_name": name,
283-
"zone": zone,
284-
},
285-
}
286-
}
287-
288-
func isCloudRun() bool {
289-
_, config := os.LookupEnv("K_CONFIGURATION")
290-
_, service := os.LookupEnv("K_SERVICE")
291-
_, revision := os.LookupEnv("K_REVISION")
292-
return config && service && revision
293-
}
294-
295-
func detectCloudRunResource() *mrpb.MonitoredResource {
296-
projectID, err := metadata.ProjectID()
297-
if err != nil {
298-
return nil
299-
}
300-
zone, err := metadata.Zone()
301-
if err != nil {
302-
return nil
303-
}
304-
return &mrpb.MonitoredResource{
305-
Type: "cloud_run_revision",
306-
Labels: map[string]string{
307-
"project_id": projectID,
308-
"location": regionFromZone(zone),
309-
"service_name": os.Getenv("K_SERVICE"),
310-
"revision_name": os.Getenv("K_REVISION"),
311-
"configuration_name": os.Getenv("K_CONFIGURATION"),
312-
},
313-
}
314-
}
315-
316-
func isCloudFunction() bool {
317-
// Reserved envvars in older function runtimes, e.g. Node.js 8, Python 3.7 and Go 1.11.
318-
_, name := os.LookupEnv("FUNCTION_NAME")
319-
_, region := os.LookupEnv("FUNCTION_REGION")
320-
_, entry := os.LookupEnv("ENTRY_POINT")
321-
322-
// Reserved envvars in newer function runtimes.
323-
_, target := os.LookupEnv("FUNCTION_TARGET")
324-
_, signature := os.LookupEnv("FUNCTION_SIGNATURE_TYPE")
325-
_, service := os.LookupEnv("K_SERVICE")
326-
return (name && region && entry) || (target && signature && service)
327-
}
328-
329-
func detectCloudFunction() *mrpb.MonitoredResource {
330-
projectID, err := metadata.ProjectID()
331-
if err != nil {
332-
return nil
333-
}
334-
zone, err := metadata.Zone()
335-
if err != nil {
336-
return nil
337-
}
338-
// Newer functions runtimes store name in K_SERVICE.
339-
functionName, exists := os.LookupEnv("K_SERVICE")
340-
if !exists {
341-
functionName, _ = os.LookupEnv("FUNCTION_NAME")
342-
}
343-
return &mrpb.MonitoredResource{
344-
Type: "cloud_function",
345-
Labels: map[string]string{
346-
"project_id": projectID,
347-
"region": regionFromZone(zone),
348-
"function_name": functionName,
349-
},
350-
}
351-
}
352-
353-
// isAppEngine returns true for both standard and flex
354-
func isAppEngine() bool {
355-
_, service := os.LookupEnv("GAE_SERVICE")
356-
_, version := os.LookupEnv("GAE_VERSION")
357-
_, instance := os.LookupEnv("GAE_INSTANCE")
358-
359-
return service && version && instance
360-
}
361-
362-
func detectAppEngineResource() *mrpb.MonitoredResource {
363-
projectID, err := metadata.ProjectID()
364-
if err != nil {
365-
return nil
366-
}
367-
if projectID == "" {
368-
projectID = os.Getenv("GOOGLE_CLOUD_PROJECT")
369-
}
370-
zone, err := metadata.Zone()
371-
if err != nil {
372-
return nil
373-
}
374-
375-
return &mrpb.MonitoredResource{
376-
Type: "gae_app",
377-
Labels: map[string]string{
378-
"project_id": projectID,
379-
"module_id": os.Getenv("GAE_SERVICE"),
380-
"version_id": os.Getenv("GAE_VERSION"),
381-
"instance_id": os.Getenv("GAE_INSTANCE"),
382-
"runtime": os.Getenv("GAE_RUNTIME"),
383-
"zone": zone,
384-
},
385-
}
386-
}
387-
388-
func detectResource() *mrpb.MonitoredResource {
389-
detectedResource.once.Do(func() {
390-
switch {
391-
// AppEngine, Functions, CloudRun are detected first, as metadata.OnGCE()
392-
// erroneously returns true on these runtimes.
393-
case isAppEngine():
394-
detectedResource.pb = detectAppEngineResource()
395-
case isCloudFunction():
396-
detectedResource.pb = detectCloudFunction()
397-
case isCloudRun():
398-
detectedResource.pb = detectCloudRunResource()
399-
case metadata.OnGCE():
400-
detectedResource.pb = detectGCEResource()
401-
}
402-
})
403-
return detectedResource.pb
404-
}
405-
406-
var resourceInfo = map[string]struct{ rtype, label string }{
407-
"organizations": {"organization", "organization_id"},
408-
"folders": {"folder", "folder_id"},
409-
"projects": {"project", "project_id"},
410-
"billingAccounts": {"billing_account", "account_id"},
411-
}
412-
413-
func monitoredResource(parent string) *mrpb.MonitoredResource {
414-
parts := strings.SplitN(parent, "/", 2)
415-
if len(parts) != 2 {
416-
return globalResource(parent)
417-
}
418-
info, ok := resourceInfo[parts[0]]
419-
if !ok {
420-
return globalResource(parts[1])
421-
}
422-
return &mrpb.MonitoredResource{
423-
Type: info.rtype,
424-
Labels: map[string]string{info.label: parts[1]},
425-
}
426-
}
427-
428-
func regionFromZone(zone string) string {
429-
cutoff := strings.LastIndex(zone, "-")
430-
if cutoff > 0 {
431-
return zone[:cutoff]
432-
}
433-
return zone
434-
}
435-
436-
func globalResource(projectID string) *mrpb.MonitoredResource {
437-
return &mrpb.MonitoredResource{
438-
Type: "global",
439-
Labels: map[string]string{
440-
"project_id": projectID,
441-
},
442-
}
443-
}
444-
445243
// CommonLabels are labels that apply to all log entries written from a Logger,
446244
// so that you don't have to repeat them in each log entry's Labels field. If
447245
// any of the log entries contains a (key, value) with the same key that is in

0 commit comments

Comments
 (0)