|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- // Copyright 2016 The Go Authors. All rights reserved.
- //
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file or at
- // https://developers.google.com/open-source/licenses/bsd.
-
- package main
-
- import (
- "crypto/rand"
- "encoding/hex"
- "log"
- "net/http"
- "time"
-
- "cloud.google.com/go/logging"
- "github.com/golang/gddo/database"
- )
-
- // newGCELogger returns a handler that wraps h but logs each request
- // using Google Cloud Logging service.
- func newGCELogger(cli *logging.Logger) *GCELogger {
- return &GCELogger{cli}
- }
-
- type GCELogger struct {
- cli *logging.Logger
- }
-
- // LogEvent creates an entry in Cloud Logging to record user's behavior. We should only
- // use this to log events we are interested in. General request logs are handled by GAE
- // automatically in request_log and stderr.
- func (g *GCELogger) LogEvent(w http.ResponseWriter, r *http.Request, content interface{}) {
- const sessionCookieName = "GODOC_ORG_SESSION_ID"
- cookie, err := r.Cookie(sessionCookieName)
- if err != nil {
- // Generates a random session id and sends it in response.
- rs, err := randomString()
- if err != nil {
- log.Println("error generating a random session id: ", err)
- return
- }
- // This cookie is intentionally short-lived and contains no information
- // that might identify the user. Its sole purpose is to tie query
- // terms and destination pages together to measure search quality.
- cookie = &http.Cookie{
- Name: sessionCookieName,
- Value: rs,
- Expires: time.Now().Add(time.Hour),
- }
- http.SetCookie(w, cookie)
- }
-
- // We must not record the client's IP address, or any other information
- // that might compromise the user's privacy.
- payload := map[string]interface{}{
- sessionCookieName: cookie.Value,
- "path": r.URL.RequestURI(),
- "method": r.Method,
- "referer": r.Referer(),
- }
- if pkgs, ok := content.([]database.Package); ok {
- payload["packages"] = pkgs
- }
-
- // Log queues the entry to its internal buffer, or discarding the entry
- // if the buffer was full.
- g.cli.Log(logging.Entry{
- Payload: payload,
- })
- }
-
- func randomString() (string, error) {
- b := make([]byte, 8)
- _, err := rand.Read(b)
- return hex.EncodeToString(b), err
- }
|