Reading and Writing Application Logs
Overview
Request logs vs application logs
Writing application logs
Reading logs via API
Log URL formats in App Engine and developer consoles
Reading logs in the console
Understanding request log fields
Quotas and limits
Overview
When a request is sent to your app, a request log is automatically written by App Engine. During the handling of the request, your app can also write application logs. In this page, we'll show you how to write application logs from your application, how to read both application and request logs programmatically using the Logs API, how to view logging in the Google Cloud Platform Console, and how to understand the request log data that App Engine writes during the request.
Request logs vs application logs
There are two categories of log data: request logs and application logs. A request log is automatically written by App Engine for each request handled by your app, and contains information such as the app ID, HTTP version, and so forth. For a complete list of available properties for request logs, see RequestLogs. See also the request log table for descriptions of the request log fields.
Each request log contains a list of application logs (AppLogLine) associated with that request, returned in the RequestLogs.getAppLogLines() method. Each app log contains the time the log was written, the log message, and the log level.
Note: A request log can only hold 1000 app logs. If you add more than 1000, the older logs will not be retained.
Writing application logs
Important: Individual log entries from an application have an 8KB limit. Nothing beyond this limit will be written to the app log.
The App Engine Java SDK allows a developer to log the following levels of severity:
SEVERE
WARNING
INFO
CONFIG
FINE
FINER
FINEST
In order to add logging to your Java app, you'll first need to add the appropriate system properties to your project's appengine-web.xml file, and you may also need to modify the logging.properties file to set the desired log level. Both of these files are created for you when you create a new App Engine Java project using Maven. You can find these files at the following locations:

Edit the appengine-web.xml file to add the following inside the <appengine-web-app> tags:
Notice that the default log level in logging.properties is WARNING, which suppresses INFO messages from the output. To change the log level for all classes in your app, edit the logging.properties file to change the level. For example you could change .level = WARNING to .level = INFO.
In your application code, write log messages as desired using the java.util.logging.Logger API. The example below writes an Info log message:
When your app runs, App Engine records the messages and makes them available. You can read them programmatically using the Logs API as shown next, or you can browse them in the Logs Viewer. You can also download the log files using the AppCfg tool.
Reading logs via API
Note: The Logs API only generates output for deployed apps.
The general process of getting logs using the Logs API is as follows:
Use
LogQueryto specify which logs to return.Use
LogServiceFactory.getLogService()to create the LogServiceInvoke
LogServiceFactory.getLogService().fetch()to return an iterator for the request logs.In each iteration, for each
RequestLogs, process the request properties as desired.Optionally, use
RequestLogs.getAppLogLines()to get the list of app logs (AppLogLine) associated with this request.If you retrieved the app logs list, for each
AppLogLine, process the property data as desired.
Sample code
The following sample displays 5 request logs at at time, along with their application logs. It lets you cycle through each set of 5 logs using a Next link.
In the sample, notice that the GET handler expects to be re-invoked by the user clicking on the Next link, and so it extracts the offset param, if present. That offset is used in the subsequent re-invocation of LogServiceFactory.getLogService().fetch() to "page through" each group of 5 request logs. There is nothing special about the number 5; it can be anything you want.
Log URL format in the Google Cloud Platform Console
See the following sample URL for an example of the log URL format in the Cloud Platform Console:
https://console.cloud.google.com/logs?filters=request_id:000000db00ff00ff827e493472570001737e73686966746361727331000168656164000100
Note: The URL no longer includes the filter_type.
Reading logs in the console
Note: the logs described here are shown as visible in the Log Viewer.
To view logs using the Log Viewer:
In the Cloud Platform Console, go to the logs for your project.
Use the desired filter to retrieve the logs you want to see. You can filter by various combinations of time, log level, module, and log filter label or regular expression.
Notice that labels are regular expressions for filtering the logs by logging fields. Valid labels include the following:
day
month
year
hour
minute
second
tzone
remotehost
identd_user
user
status
bytes
referrer
useragent
method
path
querystring
protocol
request_id
For example,
path:/foo.* useragent:.*Chrome.*gets logs for all requests to a path starting with/foothat were issued from a Chrome browser.
A typical App Engine log contains data in the Apache combined log format, along with some special App Engine fields, as shown in the following sample log:
Understanding request log fields
The following table lists the fields in order of occurrence along with a description:
Field Order | Field Name | Always Present? | Description |
|---|---|---|---|
1 | Client address | Yes | Client IP address. Example: |
2 | RFC1413 identity | No | RFC1413 identity of the client. This is nearly always the character |
3 | User | No | Present only if the app uses the Users API and the user is logged in. This value is the "nickname" portion of the Google Account, for example, if the Google Account is |
4 | Timestamp | Yes | Request timestamp. Example: |
5 | Request querystring | Yes | First line of the request, containing method, path, and HTTP version. Example: |
6 | HTTP Status Code | Yes | Returned HTTP status code. Example: |
7 | Response size | Yes | Response size in bytes. Example: |
8 | Referrer path | No | If there is no referrer, the log contains no path, but only |
9 | User-agent | Yes | Identifies the browser and operating system to the web server. Example: |
10 | Hostname | Yes | The hostname used by the client to connect to the App Engine application. Example : ( |
11 | Wallclock time | Yes | Total clock time in milliseconds spent by App Engine on the request. This time duration does not include time spent between the client and the server running the instance of your application. Example: |
12 | CPU milliseconds | Yes | CPU milliseconds required to fulfill the request. This is the number of milliseconds spent by the CPU actually executing your application code, expressed in terms of a baseline 1.2 GHz Intel x86 CPU. If the CPU actually used is faster than the baseline, the CPU milliseconds can be larger than the actual clock time defined above. Example: |
13 | Exit code | No | Only present if the instance shut down after getting the request. In the format |
14 | Estimated cost | Yes | DEPRECATED. Estimated cost of 1000 requests just like this one, in USD. Example: |
15 | Queue name | No | The name of the task queue used. Only present if request used a task queue. Example: |
16 | Task name | No | The name of the task executed in the task queue for this request. Only present if the request resulted in the queuing of a task. Example: |
17 | Pending queue | No | Only present if a request spent some time in a pending queue. If there are many of these in your logs and/or the values are high, it might be an indication that you need more instances to serve your traffic. Example: |
18 | Loading request | No | Only present if the request is a loading request. This means an instance had to be started up. Ideally, your instances should be up and healthy for as long as possible, serving large numbers of requests before being recycled and needing to be started again. Which means you shouldn't see too many of these in your logs. Example: |
19 | Instance | Yes | Unique identifier for the instance that handles the request. Example: |
20 | Version | Yes | The current App Engine release version used in production App Engine: 1.9.34 |
Quotas and limits
Your application is affected by the following logs-related quotas:
Logs data retrieved via the Logs API.
Log storage, also called logs retention.
Quota for data retrieved
The first 100 megabytes of logs data retrieved per day via the Logs API calls are free. After this amount is exceeded, no further Logs API calls will succeed unless billing is enabled for your app. If billing is enabled for your app, data in excess of 100 megabytes results in charges of $0.12/GB.
Logs storage
You can control how much log data your application stores by means of its log retention settings in the Google Cloud Platform Console. By default, logs are stored for an application free of charge with the following per-application limits: a maximum of 1 gigabyte for a maximum of up to 90 days. If either limit is exceeded, more recent logs will be shown and older logs will be deleted to stay within the size limit. Logs older than the maximum retention time are also deleted.
If your app has billing enabled, you can pay for higher log size limits by specifying the desired maximum log size in gigabytes in the Cloud Platform Console. You can also set the retention time by specifying the desired number of days to keep logs, up to a maximum of 365 days. The cost of this extra log storage is $0.026 per gigabyte utilized per month.
Limit | Amount | Cost past free threshold |
|---|---|---|
Maximum days storage per log | 90 days free, 365 days if paid | $0.026 per gigabyte utilized per month |
Maximum total logs storage | 1 gigabyte free, unlimited if paid | $0.026 per gigabyte utilized per month |
