Understanding how to use the Google Stackdriver Logging API

Melody Zhao
Vendasta
Published in
3 min readJul 31, 2019

I didn’t have any experience using the Google Stackdriver Logging API [1], other than going through logs in the Logs Viewer tracking down bugs. Recently, the team I am part of worked on displaying error logs in one of Vendasta’s [2] products. To query for logs, I needed to use the Stackdriver Logging API and its Go client library. This blog covers some of the interesting things I found while using the API.

The Go library endpoint we used from the Stackdriver Logging API is ListLogEntries[3]. It takes a collection of config names like cluster, namespace, and resource IDs. It also takes a page size and a page token. This is how the page size and token are defined in the proto:

This seemed pretty easy. I’d pass them in and API would perform paging. This is what I came up with:

I deployed it and did some testing in Postman [4]. I gave it a small page size and it returned me all the logs, whatever the page size. Why wasn’t pagination working? Do you see the problem in my code above?

I was so confident it was Google API’s issue that I opened an issue in the Github repo of Google’s client library. Later I got this reply:

So here’s the tricky part:

  1. The actual log fetching doesn’t happen at ListLogEntries call. ListLogEntries simply defines an iterator, as well as the internal functions such as fetch(), which does the gRPC call to Stackdriver API, and Next(), which goes and points at the next item or call fetch(). Then it returns the iterator;
  2. The log fetching happens when iterator.Next() is called;
  3. When Next() finds out that there are no items left in the current buffer, it'll call Stackdriver API again to get more logs;
  4. If there are no more logs, iterator.Done will be returned, which breaks the for-loop;
  5. The pageSize we passed in doesn’t control how many logs we’ll get back, It controls the maximum number of items that the go library fetches from Stackdriver API each time.

So what my code was doing is:

This is a problem I encountered that I found very interesting. It is not only ListLogEntries that works this way; all list methods in the Stackdriver Logging Go library seem to behave the same way. Google has a recommended pattern of using Go iterators [5].

Another tool I found very useful is the API Explorer [6]. It lists all of Google’s APIs and provides an interface where developers can directly interact with them.

--

--