Skip to content

Commit 1ec37f6

Browse files
authored
feat: replace zap with slog (#1527)
1 parent 4ad5e87 commit 1ec37f6

21 files changed

Lines changed: 110 additions & 164 deletions

caddy/caddy.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/json"
88
"errors"
99
"fmt"
10+
"log/slog"
1011
"net/http"
1112
"path/filepath"
1213
"strconv"
@@ -23,7 +24,6 @@ import (
2324
"github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver"
2425
"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
2526
"github.com/dunglas/frankenphp"
26-
"go.uber.org/zap"
2727
)
2828

2929
const defaultDocumentRoot = "public"
@@ -70,7 +70,7 @@ type FrankenPHPApp struct {
7070
MaxWaitTime time.Duration `json:"max_wait_time,omitempty"`
7171

7272
metrics frankenphp.Metrics
73-
logger *zap.Logger
73+
logger *slog.Logger
7474
}
7575

7676
// CaddyModule returns the Caddy module information.
@@ -83,7 +83,7 @@ func (f FrankenPHPApp) CaddyModule() caddy.ModuleInfo {
8383

8484
// Provision sets up the module.
8585
func (f *FrankenPHPApp) Provision(ctx caddy.Context) error {
86-
f.logger = ctx.Logger()
86+
f.logger = ctx.Slogger()
8787

8888
if httpApp, err := ctx.AppIfConfigured("http"); err == nil {
8989
if httpApp.(*caddyhttp.App).Metrics != nil {
@@ -345,7 +345,7 @@ type FrankenPHPModule struct {
345345
resolvedDocumentRoot string
346346
preparedEnv frankenphp.PreparedEnv
347347
preparedEnvNeedsReplacement bool
348-
logger *zap.Logger
348+
logger *slog.Logger
349349
}
350350

351351
// CaddyModule returns the Caddy module information.
@@ -358,7 +358,7 @@ func (FrankenPHPModule) CaddyModule() caddy.ModuleInfo {
358358

359359
// Provision sets up the module.
360360
func (f *FrankenPHPModule) Provision(ctx caddy.Context) error {
361-
f.logger = ctx.Logger()
361+
f.logger = ctx.Slogger()
362362

363363
if f.Root == "" {
364364
if frankenphp.EmbeddedAppPath == "" {

caddy/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ require (
1818
github.com/prometheus/client_golang v1.22.0
1919
github.com/spf13/cobra v1.9.1
2020
github.com/stretchr/testify v1.10.0
21-
go.uber.org/zap v1.27.0
2221
)
2322

2423
require github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect
@@ -186,6 +185,7 @@ require (
186185
go.uber.org/automaxprocs v1.6.0 // indirect
187186
go.uber.org/mock v0.5.1 // indirect
188187
go.uber.org/multierr v1.11.0 // indirect
188+
go.uber.org/zap v1.27.0 // indirect
189189
go.uber.org/zap/exp v0.3.0 // indirect
190190
golang.org/x/crypto v0.37.0 // indirect
191191
golang.org/x/crypto/x509roots/fallback v0.0.0-20250418111936-9c1aa6af88df // indirect

caddy/php-server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package caddy
33
import (
44
"encoding/json"
55
"log"
6+
"log/slog"
67
"net/http"
78
"os"
89
"path/filepath"
@@ -11,7 +12,6 @@ import (
1112
"time"
1213

1314
mercureModule "github.com/dunglas/mercure/caddy"
14-
"go.uber.org/zap/zapcore"
1515

1616
"github.com/caddyserver/caddy/v2"
1717
"github.com/caddyserver/caddy/v2/caddyconfig"
@@ -334,7 +334,7 @@ func cmdPHPServer(fs caddycmd.Flags) (int, error) {
334334
cfg.Logging = &caddy.Logging{
335335
Logs: map[string]*caddy.CustomLog{
336336
"default": {
337-
BaseLog: caddy.BaseLog{Level: zapcore.DebugLevel.CapitalString()},
337+
BaseLog: caddy.BaseLog{Level: slog.LevelDebug.String()},
338338
},
339339
},
340340
}

context.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@ package frankenphp
22

33
import (
44
"context"
5+
"log/slog"
56
"net/http"
67
"os"
78
"strings"
89
"time"
9-
10-
"go.uber.org/zap"
1110
)
1211

1312
// frankenPHPContext provides contextual information about the Request to handle.
1413
type frankenPHPContext struct {
1514
documentRoot string
1615
splitPath []string
1716
env PreparedEnv
18-
logger *zap.Logger
17+
logger *slog.Logger
1918
request *http.Request
2019
originalRequest *http.Request
2120

frankenphp.go

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"errors"
3434
"fmt"
3535
"io"
36+
"log/slog"
3637
"net/http"
3738
"os"
3839
"os/signal"
@@ -43,9 +44,6 @@ import (
4344
"syscall"
4445
"time"
4546
"unsafe"
46-
47-
"go.uber.org/zap"
48-
"go.uber.org/zap/zapcore"
4947
// debug on Linux
5048
//_ "github.com/ianlancetaylor/cgosymbolizer"
5149
)
@@ -66,7 +64,7 @@ var (
6664
isRunning bool
6765

6866
loggerMu sync.RWMutex
69-
logger *zap.Logger
67+
logger *slog.Logger
7068

7169
metrics Metrics = nullMetrics{}
7270

@@ -234,10 +232,9 @@ func Init(options ...Option) error {
234232
}
235233

236234
if opt.logger == nil {
237-
l, err := zap.NewDevelopment()
238-
if err != nil {
239-
return err
240-
}
235+
// set a default logger
236+
// to disable logging, set the logger to slog.New(slog.NewTextHandler(io.Discard, nil))
237+
l := slog.New(slog.NewTextHandler(os.Stdout, nil))
241238

242239
loggerMu.Lock()
243240
logger = l
@@ -294,13 +291,9 @@ func Init(options ...Option) error {
294291

295292
initAutoScaling(mainThread)
296293

297-
if c := logger.Check(zapcore.InfoLevel, "FrankenPHP started 🐘"); c != nil {
298-
c.Write(zap.String("php_version", Version().Version), zap.Int("num_threads", mainThread.numThreads), zap.Int("max_threads", mainThread.maxThreads))
299-
}
294+
logger.LogAttrs(nil, slog.LevelInfo, "FrankenPHP started 🐘", slog.String("php_version", Version().Version), slog.Int("num_threads", mainThread.numThreads), slog.Int("max_threads", mainThread.maxThreads))
300295
if EmbeddedAppPath != "" {
301-
if c := logger.Check(zapcore.InfoLevel, "embedded PHP app 📦"); c != nil {
302-
c.Write(zap.String("path", EmbeddedAppPath))
303-
}
296+
logger.LogAttrs(nil, slog.LevelInfo, "embedded PHP app 📦", slog.String("path", EmbeddedAppPath))
304297
}
305298

306299
return nil
@@ -435,9 +428,7 @@ func go_ub_write(threadIndex C.uintptr_t, cBuf *C.char, length C.int) (C.size_t,
435428

436429
i, e := writer.Write(unsafe.Slice((*byte)(unsafe.Pointer(cBuf)), length))
437430
if e != nil {
438-
if c := fc.logger.Check(zapcore.ErrorLevel, "write error"); c != nil {
439-
c.Write(zap.Error(e))
440-
}
431+
fc.logger.LogAttrs(nil, slog.LevelError, "write error", slog.Any("error", e))
441432
}
442433

443434
if fc.responseWriter == nil {
@@ -456,9 +447,7 @@ func go_apache_request_headers(threadIndex C.uintptr_t) (*C.go_string, C.size_t)
456447
if fc.responseWriter == nil {
457448
// worker mode, not handling a request
458449

459-
if c := logger.Check(zapcore.DebugLevel, "apache_request_headers() called in non-HTTP context"); c != nil {
460-
c.Write(zap.String("worker", fc.scriptFilename))
461-
}
450+
logger.LogAttrs(nil, slog.LevelDebug, "apache_request_headers() called in non-HTTP context", slog.String("worker", fc.scriptFilename))
462451

463452
return nil, 0
464453
}
@@ -489,9 +478,7 @@ func go_apache_request_headers(threadIndex C.uintptr_t) (*C.go_string, C.size_t)
489478
func addHeader(fc *frankenPHPContext, cString *C.char, length C.int) {
490479
parts := strings.SplitN(C.GoStringN(cString, length), ": ", 2)
491480
if len(parts) != 2 {
492-
if c := fc.logger.Check(zapcore.DebugLevel, "invalid header"); c != nil {
493-
c.Write(zap.String("header", parts[0]))
494-
}
481+
fc.logger.LogAttrs(nil, slog.LevelDebug, "invalid header", slog.String("header", parts[0]))
495482

496483
return
497484
}
@@ -545,9 +532,7 @@ func go_sapi_flush(threadIndex C.uintptr_t) bool {
545532
}
546533

547534
if err := http.NewResponseController(fc.responseWriter).Flush(); err != nil {
548-
if c := fc.logger.Check(zapcore.ErrorLevel, "the current responseWriter is not a flusher"); c != nil {
549-
c.Write(zap.Error(err))
550-
}
535+
logger.LogAttrs(nil, slog.LevelError, "the current responseWriter is not a flusher", slog.Any("error", err))
551536
}
552537

553538
return false
@@ -600,24 +585,15 @@ func go_log(message *C.char, level C.int) {
600585

601586
switch le {
602587
case emerg, alert, crit, err:
603-
if c := logger.Check(zapcore.ErrorLevel, m); c != nil {
604-
c.Write(zap.Stringer("syslog_level", syslogLevel(level)))
605-
}
588+
logger.LogAttrs(nil, slog.LevelError, m, slog.String("syslog_level", syslogLevel(level).String()))
606589

607590
case warning:
608-
if c := logger.Check(zapcore.WarnLevel, m); c != nil {
609-
c.Write(zap.Stringer("syslog_level", syslogLevel(level)))
610-
}
611-
591+
logger.LogAttrs(nil, slog.LevelWarn, m, slog.String("syslog_level", syslogLevel(level).String()))
612592
case debug:
613-
if c := logger.Check(zapcore.DebugLevel, m); c != nil {
614-
c.Write(zap.Stringer("syslog_level", syslogLevel(level)))
615-
}
593+
logger.LogAttrs(nil, slog.LevelDebug, m, slog.String("syslog_level", syslogLevel(level).String()))
616594

617595
default:
618-
if c := logger.Check(zapcore.InfoLevel, m); c != nil {
619-
c.Write(zap.Stringer("syslog_level", syslogLevel(level)))
620-
}
596+
logger.LogAttrs(nil, slog.LevelInfo, m, slog.String("syslog_level", syslogLevel(level).String()))
621597
}
622598
}
623599

frankenphp_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"io"
1313
"log"
14+
"log/slog"
1415
"mime/multipart"
1516
"net/http"
1617
"net/http/cookiejar"
@@ -30,7 +31,7 @@ import (
3031
"github.com/dunglas/frankenphp/internal/fastabs"
3132
"github.com/stretchr/testify/assert"
3233
"github.com/stretchr/testify/require"
33-
"go.uber.org/zap"
34+
"go.uber.org/zap/exp/zapslog"
3435
"go.uber.org/zap/zapcore"
3536
"go.uber.org/zap/zaptest"
3637
"go.uber.org/zap/zaptest/observer"
@@ -43,7 +44,7 @@ type testOptions struct {
4344
env map[string]string
4445
nbParallelRequests int
4546
realServer bool
46-
logger *zap.Logger
47+
logger *slog.Logger
4748
initOpts []frankenphp.Option
4849
phpIni map[string]string
4950
}
@@ -60,7 +61,7 @@ func runTest(t *testing.T, test func(func(http.ResponseWriter, *http.Request), *
6061
testDataDir := cwd + "/testdata/"
6162

6263
if opts.logger == nil {
63-
opts.logger = zaptest.NewLogger(t)
64+
opts.logger = slog.New(zapslog.NewHandler(zaptest.NewLogger(t).Core()))
6465
}
6566

6667
initOpts := []frankenphp.Option{frankenphp.WithLogger(opts.logger)}
@@ -445,7 +446,7 @@ func TestLog_worker(t *testing.T) {
445446
}
446447
func testLog(t *testing.T, opts *testOptions) {
447448
logger, logs := observer.New(zapcore.InfoLevel)
448-
opts.logger = zap.New(logger)
449+
opts.logger = slog.New(zapslog.NewHandler(logger))
449450

450451
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
451452
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/log.php?i=%d", i), nil)
@@ -465,7 +466,7 @@ func testConnectionAbort(t *testing.T, opts *testOptions) {
465466
testFinish := func(finish string) {
466467
t.Run(fmt.Sprintf("finish=%s", finish), func(t *testing.T) {
467468
logger, logs := observer.New(zapcore.InfoLevel)
468-
opts.logger = zap.New(logger)
469+
opts.logger = slog.New(zapslog.NewHandler(logger))
469470

470471
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
471472
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/connectionStatusLog.php?i=%d&finish=%s", i, finish), nil)
@@ -819,7 +820,7 @@ func ExampleExecuteScriptCLI() {
819820
}
820821

821822
func BenchmarkHelloWorld(b *testing.B) {
822-
if err := frankenphp.Init(frankenphp.WithLogger(zap.NewNop())); err != nil {
823+
if err := frankenphp.Init(frankenphp.WithLogger(slog.New(slog.NewTextHandler(io.Discard, nil)))); err != nil {
823824
panic(err)
824825
}
825826
defer frankenphp.Shutdown()
@@ -847,7 +848,7 @@ func BenchmarkHelloWorld(b *testing.B) {
847848
}
848849

849850
func BenchmarkEcho(b *testing.B) {
850-
if err := frankenphp.Init(frankenphp.WithLogger(zap.NewNop())); err != nil {
851+
if err := frankenphp.Init(frankenphp.WithLogger(slog.New(slog.NewTextHandler(io.Discard, nil)))); err != nil {
851852
panic(err)
852853
}
853854
defer frankenphp.Shutdown()
@@ -914,7 +915,7 @@ func BenchmarkEcho(b *testing.B) {
914915
}
915916

916917
func BenchmarkServerSuperGlobal(b *testing.B) {
917-
if err := frankenphp.Init(frankenphp.WithLogger(zap.NewNop())); err != nil {
918+
if err := frankenphp.Init(frankenphp.WithLogger(slog.New(slog.NewTextHandler(io.Discard, nil)))); err != nil {
918919
panic(err)
919920
}
920921
defer frankenphp.Shutdown()

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/prometheus/client_golang v1.22.0
1212
github.com/stretchr/testify v1.10.0
1313
go.uber.org/zap v1.27.0
14+
go.uber.org/zap/exp v0.3.0
1415
golang.org/x/net v0.39.0
1516
)
1617

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
4040
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
4141
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
4242
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
43+
go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U=
44+
go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ=
4345
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
4446
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
4547
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=

internal/testserver/main.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
package main
22

33
import (
4+
"log/slog"
45
"net/http"
56
"os"
67

78
"github.com/dunglas/frankenphp"
8-
"go.uber.org/zap"
99
)
1010

1111
func main() {
12-
logger, err := zap.NewDevelopment()
13-
if err != nil {
14-
panic(err)
15-
}
16-
12+
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
1713
if err := frankenphp.Init(frankenphp.WithLogger(logger)); err != nil {
1814
panic(err)
1915
}
@@ -35,5 +31,6 @@ func main() {
3531
port = "8080"
3632
}
3733

38-
logger.Fatal("server error", zap.Error(http.ListenAndServe(":"+port, nil)))
34+
logger.LogAttrs(nil, slog.LevelError, "server error", slog.Any("error", http.ListenAndServe(":"+port, nil)))
35+
os.Exit(1)
3936
}

0 commit comments

Comments
 (0)