all: switch to log/slog

Change all uses of exp/slog to log/slog.

Change-Id: I7a332966cbcf43c8b77db6ac1a015219f3eda26d
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/687875
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
diff --git a/cmd/worker/main.go b/cmd/worker/main.go
index 84271c2..2dc97a4 100644
--- a/cmd/worker/main.go
+++ b/cmd/worker/main.go
@@ -9,13 +9,13 @@
 	"context"
 	"flag"
 	"fmt"
+	"log/slog"
 	"net/http"
 	"os"
 	"os/signal"
 	"syscall"
 	"time"
 
-	"golang.org/x/exp/slog"
 	"golang.org/x/pkgsite-metrics/internal/config"
 	"golang.org/x/pkgsite-metrics/internal/log"
 	"golang.org/x/pkgsite-metrics/internal/worker"
diff --git a/go.mod b/go.mod
index 3bb14fc..c087866 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@
 	github.com/client9/misspell v0.3.4
 	github.com/google/go-cmp v0.6.0
 	github.com/google/safehtml v0.1.0
-	github.com/jba/slog v0.0.0-20230225143746-b07e7e61ec27
+	github.com/jba/slog v0.2.0
 	github.com/lib/pq v1.10.7
 	go.opencensus.io v0.24.0
 	go.opentelemetry.io/otel v1.11.2
diff --git a/go.sum b/go.sum
index 7a043a5..4e2dc7d 100644
--- a/go.sum
+++ b/go.sum
@@ -247,8 +247,8 @@
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/jba/slog v0.0.0-20230225143746-b07e7e61ec27 h1:W9SGetyKYjBQKdTULKAJBWmXwoY4bViXuita66d9g+0=
-github.com/jba/slog v0.0.0-20230225143746-b07e7e61ec27/go.mod h1:QqJCYdXocPsqwrPQkKIiws04VKccL9CKeAQKJQ/6oIs=
+github.com/jba/slog v0.2.0 h1:jI0U5NRR3EJKGsbeEVpItJNogk0c4RMeCl7vJmogCJI=
+github.com/jba/slog v0.2.0/go.mod h1:0Dh7Vyz3Td68Z1OwzadfincHwr7v+PpzadrS2Jua338=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
diff --git a/internal/log/cloud_handler.go b/internal/log/cloud_handler.go
index 026bbb6..d0e7a08 100644
--- a/internal/log/cloud_handler.go
+++ b/internal/log/cloud_handler.go
@@ -5,10 +5,9 @@
 package log
 
 import (
+	"log/slog"
 	"os"
 	"time"
-
-	"golang.org/x/exp/slog"
 )
 
 // NewGoogleCloudHandler returns a Handler that outputs JSON for the Google
@@ -16,8 +15,7 @@
 // See https://cloud.google.com/logging/docs/agent/logging/configuration#special-fields
 // for treatment of special fields.
 func NewGoogleCloudHandler() slog.Handler {
-	return slog.HandlerOptions{ReplaceAttr: gcpReplaceAttr, Level: slog.LevelDebug}.
-		NewJSONHandler(os.Stderr)
+	return slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ReplaceAttr: gcpReplaceAttr, Level: slog.LevelDebug})
 }
 
 func gcpReplaceAttr(groups []string, a slog.Attr) slog.Attr {
diff --git a/internal/log/line_handler.go b/internal/log/line_handler.go
index bbe4a02..16862f5 100644
--- a/internal/log/line_handler.go
+++ b/internal/log/line_handler.go
@@ -9,10 +9,10 @@
 	"context"
 	"fmt"
 	"io"
+	"log/slog"
 	"sync"
 
 	"github.com/jba/slog/withsupport"
-	"golang.org/x/exp/slog"
 )
 
 // LineHandler is a slog.Handler that writes log events one per line
@@ -36,6 +36,7 @@
 func (h *LineHandler) WithGroup(name string) slog.Handler {
 	return &LineHandler{w: h.w, gora: h.gora.WithGroup(name)}
 }
+
 func (h *LineHandler) WithAttrs(as []slog.Attr) slog.Handler {
 	return &LineHandler{w: h.w, gora: h.gora.WithAttrs(as)}
 }
@@ -57,7 +58,7 @@
 			}
 		}
 	}
-	r.Attrs(func(a slog.Attr) { writeAttr(&buf, prefix, a) })
+	r.Attrs(func(a slog.Attr) bool { writeAttr(&buf, prefix, a); return true })
 	buf.WriteByte('\n')
 	h.mu.Lock()
 	defer h.mu.Unlock()
diff --git a/internal/log/log.go b/internal/log/log.go
index 4440dc0..902b305 100644
--- a/internal/log/log.go
+++ b/internal/log/log.go
@@ -8,8 +8,7 @@
 import (
 	"context"
 	"fmt"
-
-	"golang.org/x/exp/slog"
+	"log/slog"
 )
 
 type loggerKey struct{}
@@ -32,7 +31,8 @@
 func Info(ctx context.Context, msg string, args ...any)  { FromContext(ctx).Info(msg, args...) }
 func Warn(ctx context.Context, msg string, args ...any)  { FromContext(ctx).Warn(msg, args...) }
 func Error(ctx context.Context, msg string, err error, args ...any) {
-	FromContext(ctx).Error(msg, err, args...)
+	args = append([]any{"err", err}, args...)
+	FromContext(ctx).Error(msg, args...)
 }
 
 func Logf(ctx context.Context, level slog.Level, format string, args ...any) {
@@ -45,9 +45,11 @@
 func Debugf(ctx context.Context, format string, args ...any) {
 	Logf(ctx, slog.LevelDebug, format, args...)
 }
+
 func Infof(ctx context.Context, format string, args ...any) {
 	Logf(ctx, slog.LevelInfo, format, args...)
 }
+
 func Warnf(ctx context.Context, format string, args ...any) {
 	Logf(ctx, slog.LevelWarn, format, args...)
 }
@@ -56,6 +58,6 @@
 	level := slog.LevelError
 	l := FromContext(ctx)
 	if l.Enabled(ctx, level) {
-		l.Log(ctx, level, fmt.Sprintf(format, args...), slog.ErrorKey, err)
+		l.Log(ctx, level, fmt.Sprintf(format, args...), "err", err)
 	}
 }
diff --git a/internal/worker/scan_test.go b/internal/worker/scan_test.go
index 2992ab7..206e025 100644
--- a/internal/worker/scan_test.go
+++ b/internal/worker/scan_test.go
@@ -8,10 +8,10 @@
 	"context"
 	"errors"
 	"fmt"
+	"log/slog"
 	"os"
 	"testing"
 
-	"golang.org/x/exp/slog"
 	"golang.org/x/pkgsite-metrics/internal/derrors"
 	"golang.org/x/pkgsite-metrics/internal/log"
 	"golang.org/x/pkgsite-metrics/internal/proxy"