Skip to content

Instantly share code, notes, and snippets.

Created Feb 10, 2014
What would you like to do?
Logging Handler
package programs
import (
const recordsPerPage = 5
func logHandler(c appengine.Context, w http.ResponseWriter, r *http.Request, kwds map[string]string) {
if !MustBeAdmin(c, w, r) {
Unauthorized(c, w, r)
// Get the incoming offset param from the Next link to advance through
// the logs. (The first time the page is loaded there won't be any offset.)
offset_str := r.FormValue("offset")
var offset []byte
var err error
if offset_str != "" {
offset, err = base64.URLEncoding.DecodeString(offset_str)
if err != nil {
// Set up a data structure to pass to the HTML template.
var data struct {
Records []*log.Record
Offset string // base-64 encoded string
// Set up a log.Query.
query := &log.Query{
Offset: offset,
AppLogs: true,
StartTime: time.Now().Add(-time.Hour * 24),
EndTime: time.Now(),
// Run the query, obtaining a Result iterator.
res := query.Run(c)
// Iterate through the results populating the data struct.
for i := 0; i < recordsPerPage; i++ {
rec, err := res.Next()
if err == log.Done {
if err != nil {
c.Errorf("Failed to retrieve next log: %v", err)
c.Infof("Saw record %v", rec)
data.Records = append(data.Records, rec)
if i == recordsPerPage-1 {
data.Offset = base64.URLEncoding.EncodeToString(rec.Offset)
// Render the template to the HTTP response.
if err := tmpl.Execute(w, data); err != nil {
c.Errorf("Rendering template: %v", err)
var tmpl = template.Must(template.New("").Parse(`
{{range .Records}}
<h2>Request Log</h2>
<p>{{.EndTime}}: {{.IP}} {{.Method}} {{.Resource}}</p>
{{with .AppLogs}}
<h3>App Logs:</h3>
{{range .}}
<li>{{.Time}}: {{.Message}}</li>
{{with .Offset}}
<a href="?offset={{.}}">Next</a>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment