aboutsummaryrefslogtreecommitdiff
path: root/internal/database/database.go
diff options
context:
space:
mode:
authorJonathan Amsterdam <jba@google.com>2020-09-03 17:28:01 -0400
committerJonathan Amsterdam <jba@google.com>2020-09-09 14:55:00 +0000
commit413cd1d16bb18c8d5a7c0aa9932a6f7e7089e84b (patch)
tree1329aeb6b5e18e3e86b18e6c780261bb04cb13d1 /internal/database/database.go
parent9c7da7d4278a6370598ac872eb896a5024950381 (diff)
downloadgo-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.go129
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 {