// ContextTimeout sets a timeout in the context. func ContextTimeout(ctx context.Context, w http.ResponseWriter, r *http.Request, next NextMiddlewareFn) error { secs := 55 * time.Second if r.Header.Get("X-AppEngine-QueueName") != "" || r.Header.Get("X-AppEngine-Cron") != "" { secs = (9*60 + 55) * time.Second } ctx, cancel := context.WithDeadline(ctx, time.Now().Add(secs)) done := make(chan error, 1) go func() { done <- next(ctx) }() select { case err := <-done: cancel() return err case <-time.After(secs): log.Criticalf(ctx, "request timeout") cancel() return nil } panic("should not reach here") }
func (sink *LogSink) writeLogStorage(r *wcg.LogRecord) error { c := sink.ctx formatter := sink.formatter if c == nil { c = NewContext(r.Request) } var text string if r.SourceStack != nil && len(r.SourceStack) > 0 { text = fmt.Sprintf( "%s\n-- Stack Trace --\n%s", string(formatter.Format(r)), strings.Join(r.SourceStack, "\n"), ) } else { text = string(formatter.Format(r)) } switch r.Level { case wcg.LogLevelTrace: log.Debugf(c, "%s", text) // app engine does not support trace level case wcg.LogLevelDebug: log.Debugf(c, "%s", text) case wcg.LogLevelInfo: log.Infof(c, "%s", text) case wcg.LogLevelWarn: log.Warningf(c, "%s", text) case wcg.LogLevelError: log.Errorf(c, "%s", text) case wcg.LogLevelFatal: log.Criticalf(c, "%s", text) default: // nothing } return nil }
func handleAuthorize(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) //retrieve code and state from the callback code, state := req.FormValue("code"), req.FormValue("state") //get session from memcache s := getSession(ctx, req) //compare state from callback with state stored in memcache if state != s.State { http.Error(res, "Detected cross-site attack", http.StatusUnauthorized) log.Criticalf(ctx, "Non-matching states from %s", req.RemoteAddr) return } //exchange the auth code given for an access token tok, err := conf.Exchange(ctx, code) if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) return } //create a client from the token client := conf.Client(ctx, tok) //create a gmail service from the client srv, err := gmail.New(client) if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) return } //request a list of messages in the user's mailbox list, err := srv.Users.Threads.List("me").Do() if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) return } //loop through and print out the first 25 message threads from your mailbox output := "<p>Messages:</p>" if len(list.Threads) > 0 { i := 1 for _, val := range list.Threads { output += "<p>- " + val.Snippet + "...</p>" if i > 25 { break } i++ } } else { output += "<p>You have no messages!</p>" } io.WriteString(res, output) }
func createTables(writer http.ResponseWriter, req *http.Request) { context := appengine.NewContext(req) client, err := google.DefaultClient(context, scope) if err != nil { writer.WriteHeader(http.StatusInternalServerError) log.Criticalf(context, "Unable to get default client: %v", err) return } service, err := bigquery.New(client) if err != nil { log.Criticalf(context, "tables/tables.go: Unable to create bigquery service: %v", err) writer.WriteHeader(http.StatusUnauthorized) return } t := time.Now() for i := 1; i < 3; i++ { t = t.AddDate(0, 0, 1) log.Infof(context, "tables/tables.go: Creating tables for %v-%v-%v", t.Year(), int(t.Month()), t.Day()) insertTablesForTime(t, service, errorHandler(writer, context)) } }
func writeLogMessage(c context.Context, level logLevel, msg string) { const fmt = "%s" switch level { case levelDebug: log.Debugf(c, fmt, msg) case levelWarning: log.Warningf(c, fmt, msg) case levelError: log.Errorf(c, fmt, msg) case levelCritical: log.Criticalf(c, fmt, msg) default: log.Infof(c, fmt, msg) } }
func handleAuthorize(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) code, state := req.FormValue("code"), req.FormValue("state") s := getSession(ctx, req) if s.State != state { http.Error(res, "Detected cross-site attack", http.StatusUnauthorized) log.Criticalf(ctx, "Non-matching states from %s", req.RemoteAddr) return } data, err := getToken(ctx, code) if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) return } io.WriteString(res, data.UID) }
// Criticalf is like Debugf, but at Critical level. func Criticalf(ctx context.Context, format string, args ...interface{}) { log.Criticalf(ctx, format, args...) }
// adminHandler serves an administrative interface. func adminHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if !user.IsAdmin(c) { http.Error(w, "forbidden", http.StatusForbidden) return } var newLink *Link var doErr error if r.Method == "POST" { key := r.FormValue("key") switch r.FormValue("do") { case "Add": newLink = &Link{key, r.FormValue("target")} doErr = putLink(c, newLink) case "Delete": k := datastore.NewKey(c, kind, key, 0, nil) doErr = datastore.Delete(c, k) default: http.Error(w, "unknown action", http.StatusBadRequest) } err := memcache.Delete(c, cacheKey(key)) if err != nil && err != memcache.ErrCacheMiss { log.Warningf(c, "%q: %v", key, err) } } var links []*Link _, err := datastore.NewQuery(kind).Order("Key").GetAll(c, &links) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "%v", err) return } // Put the new link in the list if it's not there already. // (Eventual consistency means that it might not show up // immediately, which might be confusing for the user.) if newLink != nil && doErr == nil { found := false for i := range links { if links[i].Key == newLink.Key { found = true break } } if !found { links = append([]*Link{newLink}, links...) } newLink = nil } var data = struct { BaseURL string Prefix string Links []*Link New *Link Error error }{baseURL, prefix, links, newLink, doErr} if err := adminTemplate.Execute(w, &data); err != nil { log.Criticalf(c, "adminTemplate: %v", err) } }
func mlb_handler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) // prepare the request timezone, err := time.LoadLocation("America/New_York") if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } year, month, day := time.Now().In(timezone).Date() dayString := strconv.Itoa(day) if len(dayString) == 1 { dayString = fmt.Sprint(0, dayString) } monthString := strconv.Itoa(int(month)) if len(monthString) == 1 { monthString = fmt.Sprint(0, monthString) } // make the call client := urlfetch.Client(c) response, err := client.Get(fmt.Sprint("http://gd2.mlb.com/components/game/mlb/year_", year, "/month_", monthString, "/day_", dayString, "/master_scoreboard.json")) if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // parse the response var parsed MLBResponse err = json.NewDecoder(response.Body).Decode(&parsed) if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // find the jays game var jaysGame *Game areJaysHome := false games := parsed.Data.Games.Game for index, game := range games { if game.HomeTeamCity == "Toronto" { jaysGame = &games[index] areJaysHome = true break } else if game.AwayTeamCity == "Toronto" { jaysGame = &games[index] areJaysHome = false break } } if jaysGame != nil { // pull the last alert out of the db q := datastore.NewQuery("jays").Order("-Updated") var alerts []Alert keys, err := q.GetAll(c, &alerts) if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } notify := false jaysGame.Alerts.Updated = time.Now() if len(alerts) == 0 { // put the new alert into the db _, err := datastore.Put(c, datastore.NewIncompleteKey(c, "jays", nil), &jaysGame.Alerts) if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } if jaysGame.Alerts.BriefText != "" { notify = true } } else { // take the latest entity latest := alerts[0] // check if it is different if latest.BriefText != jaysGame.Alerts.BriefText { _, err = datastore.Put(c, keys[0], &jaysGame.Alerts) if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } if jaysGame.Alerts.BriefText != "" { notify = true } } } if notify { color := "#808080" if areJaysHome { if jaysGame.Linescore.Runs.Home > jaysGame.Linescore.Runs.Away { color = "#00cc00" } else if jaysGame.Linescore.Runs.Away > jaysGame.Linescore.Runs.Home { color = "#e50000" } } else { if jaysGame.Linescore.Runs.Home > jaysGame.Linescore.Runs.Away { color = "#e50000" } else if jaysGame.Linescore.Runs.Away > jaysGame.Linescore.Runs.Home { color = "#00cc00" } } _, err = send_to_slack(jaysGame.Alerts.BriefText, color, c) if err != nil { log.Criticalf(c, "%s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } } } }
func (c Context) Criticalf(format string, args ...interface{}) { log.Criticalf(c, format, args...) }
func logCritical(c context.Context, s string, params ...interface{}) { if c != nil && c.Value("stubcontext") == nil { log.Criticalf(c, s, params...) } }