Search code examples
google-cloud-platformstackdrivergoogle-cloud-logging

How to nest LogEntries in GCP Stackdriver logging UI?


Using the GCP Logging Client or API terminology, how does one nest log entries as shown in this image?

nested logs


Solution

  • This use-case is explained in the AppEngline Logs docs.

    Make sure to also set the traceId fields to non-null values on the request and app logs which you are sending. Here's sample code in Scala:

    import com.google.cloud.MonitoredResource
    import com.google.cloud.logging.Payload._
    import com.google.cloud.logging._
    import collection.JavaConverters._
    import org.threeten.bp.Duration
    
    val logging = LoggingOptions.getDefaultInstance().getService()
    val traceId = "keasdfwxcbrbntpoiuwehrtiojsadf";
    
    var firstEntry = {
      LogEntry.newBuilder(StringPayload.of("string-payload-one"))
        .setSeverity(Severity.ERROR)
        .setLogName("app")
        .setTimestamp(1519955138399L)
        .setResource(MonitoredResource.newBuilder("global").build())
        .setLabels(Map("environment" -> "testing").asJava)
        .setTrace(traceId)
        .build()
    }
    
    var midEntry = {
      LogEntry.newBuilder(StringPayload.of("string-payload-two"))
        .setSeverity(Severity.INFO)
        .setLogName("request")
        .setResource(MonitoredResource.newBuilder("global").build())
        .setHttpRequest(HttpRequest.newBuilder().setStatus(200).setRequestUrl("/about-us").setLatency(Duration.ofMillis(1234)).build())
        .setTimestamp(1519955137906L)
        .setLabels(Map("environment" -> "testing").asJava)
        .setTrace(traceId)
        .build()
    }
    
    var lastEntry = {
      LogEntry.newBuilder(StringPayload.of("string-payload-three"))
        .setSeverity(Severity.ERROR)
        .setLogName("app")
        .setResource(MonitoredResource.newBuilder("global").build())
        .setTimestamp(1519955138523L)
        .setLabels(Map("environment" -> "testing").asJava)
        .setTrace(traceId)
        .build()
    }
    
    logging.write(List(firstEntry, midEntry, lastEntry).asJava)
    

    At the end, the log entries should show up both in their individual logs and "cross-logged" as children of their requests, like this:

    enter image description here