diff options
| author | Jonathan Amsterdam <jba@google.com> | 2020-09-03 17:28:01 -0400 |
|---|---|---|
| committer | Jonathan Amsterdam <jba@google.com> | 2020-09-09 14:55:00 +0000 |
| commit | 413cd1d16bb18c8d5a7c0aa9932a6f7e7089e84b (patch) | |
| tree | 1329aeb6b5e18e3e86b18e6c780261bb04cb13d1 /internal/database/database.go | |
| parent | 9c7da7d4278a6370598ac872eb896a5024950381 (diff) | |
| download | go-x-pkgsite-413cd1d16bb18c8d5a7c0aa9932a6f7e7089e84b.tar.xz | |
internal/database: move logging code to a separate file
Pure code motion.
Change-Id: Id9a019e114018bbe04ef5bea6eed0f563aeb886c
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/253077
Reviewed-by: Julie Qiu <julie@golang.org>
Diffstat (limited to 'internal/database/database.go')
| -rw-r--r-- | internal/database/database.go | 129 |
1 files changed, 0 insertions, 129 deletions
diff --git a/internal/database/database.go b/internal/database/database.go index bf11757f..a34758f9 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -15,9 +15,6 @@ import ( "regexp" "strings" "sync" - "sync/atomic" - "time" - "unicode" "github.com/lib/pq" "golang.org/x/pkgsite/internal/derrors" @@ -436,132 +433,6 @@ func buildBulkUpdateQuery(table string, columns, types []string) string { ) } -// QueryLoggingDisabled stops logging of queries when true. -// For use in tests only: not concurrency-safe. -var QueryLoggingDisabled bool - -var queryCounter int64 // atomic: per-process counter for unique query IDs - -type queryEndLogEntry struct { - ID string - Query string - Args string - DurationSeconds float64 - Error string `json:",omitempty"` -} - -func logQuery(ctx context.Context, query string, args []interface{}, instanceID string) func(*error) { - if QueryLoggingDisabled { - return func(*error) {} - } - const maxlen = 300 // maximum length of displayed query - - // To make the query more compact and readable, replace newlines with spaces - // and collapse adjacent whitespace. - var r []rune - for _, c := range query { - if c == '\n' { - c = ' ' - } - if len(r) == 0 || !unicode.IsSpace(r[len(r)-1]) || !unicode.IsSpace(c) { - r = append(r, c) - } - } - query = string(r) - if len(query) > maxlen { - query = query[:maxlen] + "..." - } - - uid := generateLoggingID(instanceID) - - // Construct a short string of the args. - const ( - maxArgs = 20 - maxArgLen = 50 - ) - var argStrings []string - for i := 0; i < len(args) && i < maxArgs; i++ { - s := fmt.Sprint(args[i]) - if len(s) > maxArgLen { - s = s[:maxArgLen] + "..." - } - argStrings = append(argStrings, s) - } - if len(args) > maxArgs { - argStrings = append(argStrings, "...") - } - argString := strings.Join(argStrings, ", ") - - log.Debugf(ctx, "%s %s args=%s", uid, query, argString) - start := time.Now() - return func(errp *error) { - dur := time.Since(start) - if errp == nil { // happens with queryRow - log.Debugf(ctx, "%s done", uid) - } else { - derrors.Wrap(errp, "DB running query %s", uid) - entry := queryEndLogEntry{ - ID: uid, - Query: query, - Args: argString, - DurationSeconds: dur.Seconds(), - } - if *errp == nil { - log.Debug(ctx, entry) - } else { - entry.Error = (*errp).Error() - // There are many places in our logs when a query will be - // canceled, because all unfinished search queries for a given - // request are canceled: - // https://github.com/golang/pkgsite/blob/03662129627796aa387a26b8f4f9251caf5d57fd/internal/postgres/search.go#L178 - // - // We don't want to log these as errors, because it makes the logs - // very noisy. Based on - // https://github.com/lib/pq/issues/577#issuecomment-298341053 - // it seems that ctx.Err() could return nil because this error - // is coming from postgres. github.com/lib/pq currently handles - // errors like these in their tests by hardcoding the string: - // https://github.com/lib/pq/blob/e53edc9b26000fec4c4e357122d56b0f66ace6ea/go18_test.go#L89 - logf := log.Error - if errors.Is(ctx.Err(), context.Canceled) || - strings.Contains(entry.Error, "pq: canceling statement due to user request") { - logf = log.Debug - } - logf(ctx, entry) - } - } - } -} - -func (db *DB) logTransaction(ctx context.Context, opts *sql.TxOptions) func(*error) { - if QueryLoggingDisabled { - return func(*error) {} - } - uid := generateLoggingID(db.instanceID) - isoLevel := "default" - if opts != nil { - isoLevel = opts.Isolation.String() - } - log.Debugf(ctx, "%s transaction (isolation %s) started", uid, isoLevel) - start := time.Now() - return func(errp *error) { - log.Debugf(ctx, "%s transaction (isolation %s) finished in %s with error %v", - uid, isoLevel, time.Since(start), *errp) - } -} - -func generateLoggingID(instanceID string) string { - if instanceID == "" { - instanceID = "local" - } else { - // Instance IDs are long strings. The low-order part seems quite random, so - // shortening the ID will still likely result in something unique. - instanceID = instanceID[len(instanceID)-4:] - } - n := atomic.AddInt64(&queryCounter, 1) - return fmt.Sprintf("%s-%d", instanceID, n) -} - // emptyStringScanner wraps the functionality of sql.NullString to just write // an empty string if the value is NULL. type emptyStringScanner struct { |
