Repository: envoyproxy/gateway
Pull request #5585 (2025-03-24 04:31:54)

build(deps): bump the github-com group across 1 directory with 2 updates
Bumps the github-com group with 2 updates in the / directory: [github.com/docker/cli](https://github.com/docker/cli) and [github.com/miekg/dns](https://github.com/miekg/dns).

Updates `github.com/docker/cli` from 28.0.1+incompatible to 28.0.2+incompatible
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/docker/cli/commit/0442a7378f37ef9482ade1c8addf618cb8becb00"><code>0442a73</code></a> Merge pull request <a href="https://redirect.github.com/docker/cli/issues/5929">#5929</a> from vvoland/vendor-docker</li>
<li><a href="https://github.com/docker/cli/commit/bb0e9adbc0c11675c11fa86f7efccf8444751c85"><code>bb0e9ad</code></a> remove redundant error-handling for registry.ParseRepositoryInfo</li>
<li><a href="https://github.com/docker/cli/commit/e0979b3adfb4d4c3762d4e1be024acf49fda5f4d"><code>e0979b3</code></a> cli/command: remove ValidateMountWithAPIVersion</li>
<li><a href="https://github.com/docker/cli/commit/cab5164877d5712869512572d195d9035538d7e2"><code>cab5164</code></a> vendor: github.com/docker/docker v28.0.2-dev (bea4de25004d)</li>
<li><a href="https://github.com/docker/cli/commit/888716aa59defc4837ab72f96aef1dbc6b1630d7"><code>888716a</code></a> Merge pull request <a href="https://redirect.github.com/docker/cli/issues/5932">#5932</a> from vvoland/TestConnectAndWait-flaky</li>
<li><a href="https://github.com/docker/cli/commit/667fa7bc929a76566c091619b17a5baf7187ab56"><code>667fa7b</code></a> cli: remove uses of deprecated registry.SetCertsDir</li>
<li><a href="https://github.com/docker/cli/commit/63f5930c1771595ca3375b1ce24b26d137de86ab"><code>63f5930</code></a> Merge pull request <a href="https://redirect.github.com/docker/cli/issues/5784">#5784</a> from thaJeztah/docs_gen_no_pkg_errors</li>
<li><a href="https://github.com/docker/cli/commit/0f75059e9fbb3932f95939f614286f38598db38d"><code>0f75059</code></a> Merge pull request <a href="https://redirect.github.com/docker/cli/issues/5938">#5938</a> from thaJeztah/man_cleans</li>
<li><a href="https://github.com/docker/cli/commit/0ce8989a785d03240028bf56d79c11f182842893"><code>0ce8989</code></a> test/cli-plugins: Try to make TestConnectAndWait less flaky</li>
<li><a href="https://github.com/docker/cli/commit/2f795987d61baf2ab7a7dd19274d44f81d4ad1a0"><code>2f79598</code></a> docs/generate: remove uses of pkg/errors</li>
<li>Additional commits viewable in <a href="https://github.com/docker/cli/compare/v28.0.1...v28.0.2">compare view</a></li>
</ul>
</details>
<br />

Updates `github.com/miekg/dns` from 1.1.63 to 1.1.64
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/miekg/dns/commit/f83d075be8ee87f121b90348792df9c744357d17"><code>f83d075</code></a> Release 1.1.64</li>
<li><a href="https://github.com/miekg/dns/commit/d9125187847d4a06f89b09aad13478b4ed599761"><code>d912518</code></a> Add RESINFO rr (<a href="https://redirect.github.com/miekg/dns/issues/1641">#1641</a>)</li>
<li><a href="https://github.com/miekg/dns/commit/8d0c4128deeb82bf7b296852e35bd6e198a82a40"><code>8d0c412</code></a> Add support for Compact Answers OK flag in EDNS (<a href="https://redirect.github.com/miekg/dns/issues/1639">#1639</a>)</li>
<li><a href="https://github.com/miekg/dns/commit/6425a084b83b879c1b5ab26a81398b4e223827b1"><code>6425a08</code></a> Add the check-soa program, which uses the library (<a href="https://redirect.github.com/miekg/dns/issues/1638">#1638</a>)</li>
<li><a href="https://github.com/miekg/dns/commit/1c19e4901474ca38eae989a814ba67bce3e55eae"><code>1c19e49</code></a> Manually run a go get -u</li>
<li><a href="https://github.com/miekg/dns/commit/494e4d28eb1ed06e14ddb6b3c018b2c481e81dc5"><code>494e4d2</code></a> Merge branch 'master' of github.com:miekg/dns</li>
<li><a href="https://github.com/miekg/dns/commit/37f4827e1cff5d0ed21d2bf9df4e140dfe4b4937"><code>37f4827</code></a> Try to group the dependabot prs</li>
<li><a href="https://github.com/miekg/dns/commit/75e8f27ccd1a3643011fdbfa70a721a4b6e137d1"><code>75e8f27</code></a> Bump golang.org/x/sync from 0.7.0 to 0.11.0 (<a href="https://redirect.github.com/miekg/dns/issues/1635">#1635</a>)</li>
<li><a href="https://github.com/miekg/dns/commit/72fe95ac977d221183a6d2503010e2520b6e2c37"><code>72fe95a</code></a> SVCB is no RFC 9460. (<a href="https://redirect.github.com/miekg/dns/issues/1636">#1636</a>)</li>
<li><a href="https://github.com/miekg/dns/commit/b911878db335d03de066372fa9e3992acf8d39a0"><code>b911878</code></a> Bump golang.org/x/net from 0.31.0 to 0.34.0 (<a href="https://redirect.github.com/miekg/dns/issues/1631">#1631</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/miekg/dns/compare/v1.1.63...v1.1.64">compare view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions


</details>

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/5585?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 65.28%. Comparing base [(`d87fed8`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/d87fed81c9c2d5a4ed7cc586ffdbb58e6b1bf591?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`84a004c`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/84a004c4a62f78f7746ed54e3ed80dd009eba47e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #5585      +/-   ##
==========================================
+ Coverage   65.25%   65.28%   +0.02%     
==========================================
  Files         213      213              
  Lines       34069    34069              
==========================================
+ Hits        22233    22243      +10     
+ Misses      10501    10494       -7     
+ Partials     1335     1332       -3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/5585?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/VERSION b/VERSION
index 757407982..968e750a6 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-v1.3.1
+v1.3.2
diff --git a/go.mod b/go.mod
index 0d79d1adb..72af84252 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/envoyproxy/gateway
 go 1.24.1
 
 require (
-	fortio.org/fortio v1.68.0
+	fortio.org/fortio v1.68.1
 	fortio.org/log v1.17.1
 	github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24
 	github.com/Masterminds/semver/v3 v3.3.1
@@ -12,7 +12,7 @@ require (
 	github.com/cenkalti/backoff/v4 v4.3.0
 	github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
-	github.com/docker/cli v28.0.1+incompatible
+	github.com/docker/cli v28.0.2+incompatible
 	github.com/docker/docker v27.5.1+incompatible
 	github.com/dominikbraun/graph v0.23.0
 	github.com/envoyproxy/go-control-plane v0.13.5-0.20250303232259-0c5cb90447bb
@@ -35,7 +35,7 @@ require (
 	github.com/google/go-cmp v0.7.0
 	github.com/google/go-containerregistry v0.20.3
 	github.com/hashicorp/go-multierror v1.1.1
-	github.com/miekg/dns v1.1.63
+	github.com/miekg/dns v1.1.64
 	github.com/ohler55/ojg v1.26.2
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.21.1
diff --git a/go.sum b/go.sum
index fb2bd2fe4..91d0394fc 100644
--- a/go.sum
+++ b/go.sum
@@ -39,8 +39,8 @@ fortio.org/cli v1.9.2 h1:17eJ8QZPjXHcLBpeCe0QMO/0fj5Bw0ZTxVgL7V9jOqc=
 fortio.org/cli v1.9.2/go.mod h1:7r55OoTV8NXcTvJT4boWk8s3I2LP6TMZh/0LLMJEYw0=
 fortio.org/dflag v1.7.3 h1:yws+v+/fJ67bYgrgcWpLtgdZPEWkYuwdfqz/WyQ8UXo=
 fortio.org/dflag v1.7.3/go.mod h1:O1Pk4lKRolw9wwAGyjTo8IsNyqqNRQGKxPOfpOElMqM=
-fortio.org/fortio v1.68.0 h1:2M9RuitiN+MgW6QlTJCHjW6PJLAPj/YCXegxSCLQ3rw=
-fortio.org/fortio v1.68.0/go.mod h1:1IjDaEoT5crHBN7BRLBwrHE24pIT6rOPKrYG3jEIWaA=
+fortio.org/fortio v1.68.1 h1:dhs9px7xkXLPzS8gVE3AKe+NRD/5aylV/qebD7vfv7E=
+fortio.org/fortio v1.68.1/go.mod h1:bZBFAxe8hfh/fdtEugVOBZvANGJcMdB91cwaul61K8w=
 fortio.org/log v1.17.1 h1:YQoGyZBnXTVIs77/nZw7BppwSOIamP3I092PGBenBZs=
 fortio.org/log v1.17.1/go.mod h1:t58Spg9njjymvRioh5F6qKGSupEsnMjXLGWIS1i3khE=
 fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY=
@@ -313,8 +313,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
 github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/docker/cli v28.0.1+incompatible h1:g0h5NQNda3/CxIsaZfH4Tyf6vpxFth7PYl3hgCPOKzs=
-github.com/docker/cli v28.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v28.0.2+incompatible h1:cRPZ77FK3/IXTAIQQj1vmhlxiLS5m+MIUDwS6f57lrE=
+github.com/docker/cli v28.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@@ -887,8 +887,8 @@ github.com/mgechev/revive v1.6.1 h1:ncK0ZCMWtb8GXwVAmk+IeWF2ULIDsvRxSRfg5sTwQ2w=
 github.com/mgechev/revive v1.6.1/go.mod h1:/2tfHWVO8UQi/hqJsIYNEKELi+DJy/e+PQpLgTB1v88=
 github.com/microsoft/go-mssqldb v1.8.0 h1:7cyZ/AT7ycDsEoWPIXibd+aVKFtteUNhDGf3aobP+tw=
 github.com/microsoft/go-mssqldb v1.8.0/go.mod h1:6znkekS3T2vp0waiMhen4GPU1BiAsrP+iXHcE7a7rFo=
-github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
-github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
+github.com/miekg/dns v1.1.64 h1:wuZgD9wwCE6XMT05UU/mlSko71eRSXEAm2EbjQXLKnQ=
+github.com/miekg/dns v1.1.64/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck=
 github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
 github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
 github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
diff --git a/internal/cmd/certgen.go b/internal/cmd/certgen.go
index 6b34158a8..835a583d9 100644
--- a/internal/cmd/certgen.go
+++ b/internal/cmd/certgen.go
@@ -9,6 +9,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"io"
 	"path"
 
 	"github.com/spf13/cobra"
@@ -36,7 +37,7 @@ func GetCertGenCommand() *cobra.Command {
 		Use:   "certgen",
 		Short: "Generate Control Plane Certificates",
 		RunE: func(cmd *cobra.Command, args []string) error {
-			return certGen(cmd.Context(), local)
+			return certGen(cmd.Context(), cmd.OutOrStdout(), local)
 		},
 	}
 
@@ -48,8 +49,8 @@ func GetCertGenCommand() *cobra.Command {
 }
 
 // certGen generates control plane certificates.
-func certGen(ctx context.Context, local bool) error {
-	cfg, err := config.New()
+func certGen(ctx context.Context, logOut io.Writer, local bool) error {
+	cfg, err := config.New(logOut)
 	if err != nil {
 		return err
 	}
diff --git a/internal/cmd/egctl/status.go b/internal/cmd/egctl/status.go
index 814bd1593..cdb243369 100644
--- a/internal/cmd/egctl/status.go
+++ b/internal/cmd/egctl/status.go
@@ -9,7 +9,6 @@ import (
 	"context"
 	"fmt"
 	"io"
-	"os"
 	"reflect"
 	"strconv"
 	"strings"
@@ -93,27 +92,27 @@ func newStatusCommand() *cobra.Command {
 			switch strings.ToLower(resourceType) {
 			case "all":
 				for _, rt := range supportedAllTypes {
-					if err = runStatus(ctx, k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil {
+					if err = runStatus(ctx, cmd.OutOrStdout(), k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil {
 						return err
 					}
 				}
 				return nil
 			case "xroute":
 				for _, rt := range supportedXRouteTypes {
-					if err = runStatus(ctx, k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil {
+					if err = runStatus(ctx, cmd.OutOrStdout(), k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil {
 						return err
 					}
 				}
 				return nil
 			case "xpolicy":
 				for _, rt := range supportedXPolicyTypes {
-					if err = runStatus(ctx, k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil {
+					if err = runStatus(ctx, cmd.OutOrStdout(), k8sClient, rt, namespace, quiet, verbose, allNamespaces, true, true); err != nil {
 						return err
 					}
 				}
 				return nil
 			default:
-				return runStatus(ctx, k8sClient, resourceType, namespace, quiet, verbose, allNamespaces, false, false)
+				return runStatus(ctx, cmd.OutOrStdout(), k8sClient, resourceType, namespace, quiet, verbose, allNamespaces, false, false)
 			}
 		},
 	}
@@ -138,11 +137,11 @@ func writeStatusTable(table *tabwriter.Writer, header []string, body [][]string)
 }
 
 // runStatus find and write the summary table of status for a specific resource type.
-func runStatus(ctx context.Context, cli client.Client, inputResourceType, namespace string, quiet, verbose, allNamespaces, ignoreEmpty, typedName bool) error {
+func runStatus(ctx context.Context, logOut io.Writer, cli client.Client, inputResourceType, namespace string, quiet, verbose, allNamespaces, ignoreEmpty, typedName bool) error {
 	var (
 		resourcesList client.ObjectList
 		resourceKind  string
-		table         = newStatusTableWriter(os.Stdout)
+		table         = newStatusTableWriter(logOut)
 	)
 
 	if allNamespaces {
diff --git a/internal/cmd/envoy/shutdown_manager.go b/internal/cmd/envoy/shutdown_manager.go
index 627c2f034..e35793df9 100644
--- a/internal/cmd/envoy/shutdown_manager.go
+++ b/internal/cmd/envoy/shutdown_manager.go
@@ -21,7 +21,8 @@ import (
 	"github.com/envoyproxy/gateway/internal/xds/bootstrap"
 )
 
-var logger = logging.DefaultLogger(egv1a1.LogLevelInfo).WithName("shutdown-manager")
+// TODO: Remove the global logger and localize the scope of the logger.
+var logger = logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo).WithName("shutdown-manager")
 
 const (
 	// ShutdownManagerPort is the port Envoy shutdown manager will listen on.
diff --git a/internal/cmd/server.go b/internal/cmd/server.go
index 99c1856b4..6a39bcc24 100644
--- a/internal/cmd/server.go
+++ b/internal/cmd/server.go
@@ -105,7 +105,7 @@ func getConfig(logOut io.Writer) (*config.Server, error) {
 // make `cfgPath` an argument to test it without polluting the global var
 func getConfigByPath(logOut io.Writer, cfgPath string) (*config.Server, error) {
 	// Initialize with default config parameters.
-	cfg, err := config.New()
+	cfg, err := config.New(logOut)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/envoygateway/config/config.go b/internal/envoygateway/config/config.go
index e8d1fece3..63d740de1 100644
--- a/internal/envoygateway/config/config.go
+++ b/internal/envoygateway/config/config.go
@@ -7,6 +7,7 @@ package config
 
 import (
 	"errors"
+	"io"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/api/v1alpha1/validation"
@@ -41,12 +42,12 @@ type Server struct {
 }
 
 // New returns a Server with default parameters.
-func New() (*Server, error) {
+func New(logOut io.Writer) (*Server, error) {
 	return &Server{
 		EnvoyGateway: egv1a1.DefaultEnvoyGateway(),
 		Namespace:    env.Lookup("ENVOY_GATEWAY_NAMESPACE", DefaultNamespace),
 		DNSDomain:    env.Lookup("KUBERNETES_CLUSTER_DOMAIN", DefaultDNSDomain),
-		Logger:       logging.DefaultLogger(egv1a1.LogLevelInfo),
+		Logger:       logging.DefaultLogger(logOut, egv1a1.LogLevelInfo),
 		Elected:      make(chan struct{}),
 	}, nil
 }
diff --git a/internal/logging/log.go b/internal/logging/log.go
index e38af9082..394e3919e 100644
--- a/internal/logging/log.go
+++ b/internal/logging/log.go
@@ -19,6 +19,7 @@ import (
 
 type Logger struct {
 	logr.Logger
+	out           io.Writer
 	logging       *egv1a1.EnvoyGatewayLogging
 	sugaredLogger *zap.SugaredLogger
 }
@@ -28,6 +29,7 @@ func NewLogger(w io.Writer, logging *egv1a1.EnvoyGatewayLogging) Logger {
 
 	return Logger{
 		Logger:        zapr.NewLogger(logger),
+		out:           w,
 		logging:       logging,
 		sugaredLogger: logger.Sugar(),
 	}
@@ -45,16 +47,18 @@ func FileLogger(file string, name string, level egv1a1.LogLevel) Logger {
 	return Logger{
 		Logger:        zapr.NewLogger(logger).WithName(name),
 		logging:       logging,
+		out:           writer,
 		sugaredLogger: logger.Sugar(),
 	}
 }
 
-func DefaultLogger(level egv1a1.LogLevel) Logger {
+func DefaultLogger(out io.Writer, level egv1a1.LogLevel) Logger {
 	logging := egv1a1.DefaultEnvoyGatewayLogging()
-	logger := initZapLogger(os.Stdout, logging, level)
+	logger := initZapLogger(out, logging, level)
 
 	return Logger{
 		Logger:        zapr.NewLogger(logger),
+		out:           out,
 		logging:       logging,
 		sugaredLogger: logger.Sugar(),
 	}
@@ -67,11 +71,12 @@ func DefaultLogger(level egv1a1.LogLevel) Logger {
 // more information).
 func (l Logger) WithName(name string) Logger {
 	logLevel := l.logging.Level[egv1a1.EnvoyGatewayLogComponent(name)]
-	logger := initZapLogger(os.Stdout, l.logging, logLevel)
+	logger := initZapLogger(l.out, l.logging, logLevel)
 
 	return Logger{
 		Logger:        zapr.NewLogger(logger).WithName(name),
 		logging:       l.logging,
+		out:           l.out,
 		sugaredLogger: logger.Sugar().Named(name),
 	}
 }
diff --git a/internal/message/watchutil.go b/internal/message/watchutil.go
index 77caa4af3..fc0f65dcc 100644
--- a/internal/message/watchutil.go
+++ b/internal/message/watchutil.go
@@ -7,6 +7,7 @@ package message
 
 import (
 	"fmt"
+	"os"
 	"runtime/debug"
 	"time"
 
@@ -19,7 +20,8 @@ import (
 
 type Update[K comparable, V any] watchable.Update[K, V]
 
-var logger = logging.DefaultLogger(egv1a1.LogLevelInfo).WithName("watchable")
+// TODO: Remove the global logger and localize the scope of the logger.
+var logger = logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo).WithName("watchable")
 
 type Metadata struct {
 	Runner  string
diff --git a/release-notes/v1.3.2.yaml b/release-notes/v1.3.2.yaml
new file mode 100644
index 000000000..3422655b4
--- /dev/null
+++ b/release-notes/v1.3.2.yaml
@@ -0,0 +1,19 @@
+date: March 24, 2025
+
+bug fixes: |
+  Added support for BackendTLSPolicy and EnvoyExtensionPolicy parsing in Standalone mode.
+  Fixed updates of endpoints when mirrored backend Pod IPs are changed.
+  Fix not logging an error and returning it in the K8s Reconcile method when a GatewayClass is not accepted.
+  Fix allowing empty text field for opentelemetry sink when using JSON format.
+  Fixed validation of host header in RequestHeaderModifier filter.
+  Retrigger reconciliation when backendRef of type ServiceImport is updated or when EndpointSlice(s) for a ServiceImport are updated.
+
+# Enhancements that improve performance.
+performance improvements: |
+  Added a cache for the Wasm OCI image permission checks and check the pullSecrets against the OCI image registry in
+  a background goroutine.
+
+# Other notable changes not covered by the above sections.
+Other changes: |
+  Bumped envoy to v1.33.1.
+  Bumped ratelimit to 0141a24f.
diff --git a/site/content/en/news/releases/notes/v1.3.2.md b/site/content/en/news/releases/notes/v1.3.2.md
new file mode 100644
index 000000000..73760e606
--- /dev/null
+++ b/site/content/en/news/releases/notes/v1.3.2.md
@@ -0,0 +1,23 @@
+---
+title: "v1.3.2"
+publishdate: 2025-03-24
+---
+
+Date: March 24, 2025
+
+## Bug fixes
+- Added support for BackendTLSPolicy and EnvoyExtensionPolicy parsing in Standalone mode.
+- Fixed updates of endpoints when mirrored backend Pod IPs are changed.
+- Fix not logging an error and returning it in the K8s Reconcile method when a GatewayClass is not accepted.
+- Fix allowing empty text field for opentelemetry sink when using JSON format.
+- Fixed validation of host header in RequestHeaderModifier filter.
+- Retrigger reconciliation when backendRef of type ServiceImport is updated or when EndpointSlice(s) for a ServiceImport are updated.
+
+## Performance improvements
+- Added a cache for the Wasm OCI image permission checks and check the pullSecrets against the OCI image registry in
+- a background goroutine.
+
+## Other changes
+- Bumped envoy to v1.33.1.
+- Bumped ratelimit to 0141a24f.
+


Test patch:
diff --git a/internal/crypto/certgen_test.go b/internal/crypto/certgen_test.go
index 429fea518..5e3a6f1d3 100644
--- a/internal/crypto/certgen_test.go
+++ b/internal/crypto/certgen_test.go
@@ -10,6 +10,7 @@ import (
 	"encoding/base64"
 	"encoding/pem"
 	"fmt"
+	"os"
 	"testing"
 	"time"
 
@@ -25,7 +26,7 @@ func TestGenerateCerts(t *testing.T) {
 		wantEnvoyDNSName        string
 	}
 
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	run := func(t *testing.T, name string, tc testcase) {
diff --git a/internal/envoygateway/config/config_test.go b/internal/envoygateway/config/config_test.go
index 59bba1294..1e68977ea 100644
--- a/internal/envoygateway/config/config_test.go
+++ b/internal/envoygateway/config/config_test.go
@@ -6,6 +6,7 @@
 package config
 
 import (
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -21,7 +22,7 @@ var (
 )
 
 func TestValidate(t *testing.T) {
-	cfg, err := New()
+	cfg, err := New(os.Stdout)
 	require.NoError(t, err)
 
 	testCases := []struct {
@@ -56,7 +57,7 @@ func TestValidate(t *testing.T) {
 			name: "unspecified envoy gateway",
 			cfg: &Server{
 				Namespace: "test-ns",
-				Logger:    logging.DefaultLogger(egv1a1.LogLevelInfo),
+				Logger:    logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo),
 			},
 			expect: false,
 		},
diff --git a/internal/envoygateway/config/loader/configloader_test.go b/internal/envoygateway/config/loader/configloader_test.go
index b5aa30bf1..fe6186c88 100644
--- a/internal/envoygateway/config/loader/configloader_test.go
+++ b/internal/envoygateway/config/loader/configloader_test.go
@@ -32,7 +32,7 @@ func TestConfigLoader(t *testing.T) {
 
 	cfgPath := tmpDir + "/config.yaml"
 	require.NoError(t, os.WriteFile(cfgPath, []byte(defaultConfig), 0o600))
-	s, err := config.New()
+	s, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	ctx, cancel := context.WithCancel(context.TODO())
diff --git a/internal/gatewayapi/runner/runner_test.go b/internal/gatewayapi/runner/runner_test.go
index 58515da7e..4596a8290 100644
--- a/internal/gatewayapi/runner/runner_test.go
+++ b/internal/gatewayapi/runner/runner_test.go
@@ -7,6 +7,7 @@ package runner
 
 import (
 	"context"
+	"os"
 	"reflect"
 	"testing"
 	"time"
@@ -30,7 +31,7 @@ func TestRunner(t *testing.T) {
 	pResources := new(message.ProviderResources)
 	xdsIR := new(message.XdsIR)
 	infraIR := new(message.InfraIR)
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	extMgr, closeFunc, err := registry.NewInMemoryManager(egv1a1.ExtensionManager{}, &pb.UnimplementedEnvoyGatewayExtensionServer{})
 	require.NoError(t, err)
@@ -116,7 +117,7 @@ func TestDeleteStatusKeys(t *testing.T) {
 	pResources := new(message.ProviderResources)
 	xdsIR := new(message.XdsIR)
 	infraIR := new(message.InfraIR)
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	extMgr, closeFunc, err := registry.NewInMemoryManager(egv1a1.ExtensionManager{}, &pb.UnimplementedEnvoyGatewayExtensionServer{})
 	require.NoError(t, err)
@@ -217,7 +218,7 @@ func TestDeleteAllStatusKeys(t *testing.T) {
 	pResources := new(message.ProviderResources)
 	xdsIR := new(message.XdsIR)
 	infraIR := new(message.InfraIR)
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	extMgr, closeFunc, err := registry.NewInMemoryManager(egv1a1.ExtensionManager{}, &pb.UnimplementedEnvoyGatewayExtensionServer{})
 	require.NoError(t, err)
diff --git a/internal/globalratelimit/runner/runner_test.go b/internal/globalratelimit/runner/runner_test.go
index 80598f790..bbb8b4fda 100644
--- a/internal/globalratelimit/runner/runner_test.go
+++ b/internal/globalratelimit/runner/runner_test.go
@@ -8,6 +8,7 @@ package runner
 import (
 	"context"
 	"fmt"
+	"os"
 	"testing"
 	"time"
 
@@ -209,7 +210,7 @@ func Test_subscribeAndTranslate(t *testing.T) {
 			defer cancel()
 			xdsIR := new(message.XdsIR)
 			defer xdsIR.Close()
-			cfg, err := config.New()
+			cfg, err := config.New(os.Stdout)
 			require.NoError(t, err)
 
 			r := New(&Config{
diff --git a/internal/infrastructure/host/proxy_infra_test.go b/internal/infrastructure/host/proxy_infra_test.go
index de3651da4..2d82cc689 100644
--- a/internal/infrastructure/host/proxy_infra_test.go
+++ b/internal/infrastructure/host/proxy_infra_test.go
@@ -8,6 +8,7 @@ package host
 import (
 	"bytes"
 	"context"
+	"os"
 	"path"
 	"testing"
 
@@ -42,7 +43,7 @@ func newMockInfra(t *testing.T, cfg *config.Server) *Infra {
 
 	infra := &Infra{
 		HomeDir:         homeDir,
-		Logger:          logging.DefaultLogger(egv1a1.LogLevelInfo),
+		Logger:          logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo),
 		EnvoyGateway:    cfg.EnvoyGateway,
 		proxyContextMap: make(map[string]*proxyContext),
 		sdsConfigPath:   proxyDir,
@@ -51,7 +52,7 @@ func newMockInfra(t *testing.T, cfg *config.Server) *Infra {
 }
 
 func TestInfraCreateProxy(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	infra := newMockInfra(t, cfg)
 
diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
index c005a5db4..478a70dec 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
@@ -116,7 +116,7 @@ func newTestInfraWithAnnotationsAndLabels(annotations, labels map[string]string)
 }
 
 func TestDeployment(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cases := []struct {
@@ -645,7 +645,7 @@ func loadDeployment(caseName string) (*appsv1.Deployment, error) {
 }
 
 func TestDaemonSet(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cases := []struct {
@@ -1074,7 +1074,7 @@ func loadDaemonSet(caseName string) (*appsv1.DaemonSet, error) {
 }
 
 func TestService(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	svcType := egv1a1.ServiceTypeClusterIP
@@ -1222,7 +1222,7 @@ func loadService(caseName string) (*corev1.Service, error) {
 }
 
 func TestConfigMap(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	cases := []struct {
 		name  string
@@ -1265,7 +1265,7 @@ func loadConfigmap(tc string) (*corev1.ConfigMap, error) {
 }
 
 func TestServiceAccount(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	cases := []struct {
 		name  string
@@ -1308,7 +1308,7 @@ func loadServiceAccount(tc string) (*corev1.ServiceAccount, error) {
 }
 
 func TestPDB(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cases := []struct {
@@ -1414,7 +1414,7 @@ func TestPDB(t *testing.T) {
 }
 
 func TestHorizontalPodAutoscaler(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cases := []struct {
diff --git a/internal/infrastructure/kubernetes/proxy_configmap_test.go b/internal/infrastructure/kubernetes/proxy_configmap_test.go
index ec4c0ec74..60ccbbca6 100644
--- a/internal/infrastructure/kubernetes/proxy_configmap_test.go
+++ b/internal/infrastructure/kubernetes/proxy_configmap_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -26,7 +27,7 @@ import (
 )
 
 func TestCreateOrUpdateProxyConfigMap(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	infra := ir.NewInfra()
@@ -128,7 +129,7 @@ func TestCreateOrUpdateProxyConfigMap(t *testing.T) {
 }
 
 func TestDeleteConfigProxyMap(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	infra := ir.NewInfra()
diff --git a/internal/infrastructure/kubernetes/proxy_daemonset_test.go b/internal/infrastructure/kubernetes/proxy_daemonset_test.go
index 2c1265862..d60c9a617 100644
--- a/internal/infrastructure/kubernetes/proxy_daemonset_test.go
+++ b/internal/infrastructure/kubernetes/proxy_daemonset_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -47,7 +48,7 @@ func daemonsetWithSelectorAndLabel(ds *appsv1.DaemonSet, selector *metav1.LabelS
 }
 
 func TestCreateOrUpdateProxyDaemonSet(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	infra := ir.NewInfra()
diff --git a/internal/infrastructure/kubernetes/proxy_deployment_test.go b/internal/infrastructure/kubernetes/proxy_deployment_test.go
index 188c92961..73460e00e 100644
--- a/internal/infrastructure/kubernetes/proxy_deployment_test.go
+++ b/internal/infrastructure/kubernetes/proxy_deployment_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -52,7 +53,7 @@ func deploymentWithSelectorAndLabel(deploy *appsv1.Deployment, selector *metav1.
 }
 
 func TestCreateOrUpdateProxyDeployment(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	infra := ir.NewInfra()
@@ -264,7 +265,7 @@ func TestDeleteProxyDeployment(t *testing.T) {
 		WithObjects().
 		WithInterceptorFuncs(interceptorFunc).
 		Build()
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	testCases := []struct {
diff --git a/internal/infrastructure/kubernetes/proxy_infra_test.go b/internal/infrastructure/kubernetes/proxy_infra_test.go
index de0690e82..5363b4e80 100644
--- a/internal/infrastructure/kubernetes/proxy_infra_test.go
+++ b/internal/infrastructure/kubernetes/proxy_infra_test.go
@@ -9,6 +9,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"os"
 	"reflect"
 	"testing"
 
@@ -81,7 +82,7 @@ func TestCmpBytes(t *testing.T) {
 }
 
 func newTestInfraWithClient(t *testing.T, cli client.Client) *Infra {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cfg.EnvoyGateway = &egv1a1.EnvoyGateway{
diff --git a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
index 44732bf6b..18aa79ffd 100644
--- a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
+++ b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -167,7 +168,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			cfg, err := config.New()
+			cfg, err := config.New(os.Stdout)
 			require.NoError(t, err)
 			cfg.Namespace = tc.ns
 
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
index d3bd7243d..5c2a1edf0 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
@@ -89,7 +89,7 @@ func TestRateLimitLabels(t *testing.T) {
 }
 
 func TestServiceAccount(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cfg.EnvoyGateway.RateLimit = &egv1a1.RateLimit{
@@ -122,7 +122,7 @@ func loadServiceAccount() (*corev1.ServiceAccount, error) {
 }
 
 func TestService(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cases := []struct {
@@ -185,7 +185,7 @@ func loadService(caseName string) (*corev1.Service, error) {
 }
 
 func TestConfigmap(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cfg.EnvoyGateway.RateLimit = &egv1a1.RateLimit{
@@ -226,7 +226,7 @@ func loadConfigmap() (*corev1.ConfigMap, error) {
 }
 
 func TestDeployment(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	rateLimit := &egv1a1.RateLimit{
 		Backend: egv1a1.RateLimitDatabaseBackend{
@@ -798,7 +798,7 @@ func loadDeployment(caseName string) (*appsv1.Deployment, error) {
 }
 
 func TestHorizontalPodAutoscaler(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	cases := []struct {
 		caseName            string
diff --git a/internal/infrastructure/kubernetes/ratelimit_deployment_test.go b/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
index ea0e5017f..e66b69a06 100644
--- a/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -23,7 +24,7 @@ import (
 )
 
 func TestCreateOrUpdateRateLimitDeployment(t *testing.T) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 
 	cfg.EnvoyGateway.RateLimit = &egv1a1.RateLimit{
diff --git a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
index 630fa2e33..2e5805129 100644
--- a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -103,7 +104,7 @@ func TestCreateOrUpdateRateLimitServiceAccount(t *testing.T) {
 					Build()
 			}
 
-			cfg, err := config.New()
+			cfg, err := config.New(os.Stdout)
 			require.NoError(t, err)
 			cfg.Namespace = tc.ns
 
diff --git a/internal/logging/log_test.go b/internal/logging/log_test.go
index 265df4111..a5f75e438 100644
--- a/internal/logging/log_test.go
+++ b/internal/logging/log_test.go
@@ -38,7 +38,7 @@ func TestLogger(t *testing.T) {
 
 	logger.WithName(string(egv1a1.LogComponentGlobalRateLimitRunner)).WithValues("runner", egv1a1.LogComponentGlobalRateLimitRunner).Info("msg", "k", "v")
 
-	defaultLogger := DefaultLogger(egv1a1.LogLevelInfo)
+	defaultLogger := DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 	assert.NotNil(t, defaultLogger.logging)
 	assert.NotNil(t, defaultLogger.sugaredLogger)
 
diff --git a/internal/provider/file/file_test.go b/internal/provider/file/file_test.go
index 8f681d47d..57909ea69 100644
--- a/internal/provider/file/file_test.go
+++ b/internal/provider/file/file_test.go
@@ -50,7 +50,7 @@ func newDefaultResourcesParam() *resourcesParam {
 }
 
 func newFileProviderConfig(paths []string) (*config.Server, error) {
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go
index d008e7b2f..b2d6cdaf7 100644
--- a/internal/provider/kubernetes/controller_test.go
+++ b/internal/provider/kubernetes/controller_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -256,7 +257,7 @@ func TestProcessGatewayClassParamsRef(t *testing.T) {
 		tc := testCases[i]
 
 		// Create the reconciler.
-		logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+		logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 		r := &gatewayAPIReconciler{
 			log:             logger,
@@ -421,7 +422,7 @@ func TestProcessEnvoyExtensionPolicyObjectRefs(t *testing.T) {
 			objs := []client.Object{tc.envoyExtensionPolicy, tc.backend, tc.referenceGrant}
 
 			// Create the reconciler.
-			logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+			logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 			ctx := context.Background()
 
diff --git a/internal/provider/kubernetes/extensionpolicies_test.go b/internal/provider/kubernetes/extensionpolicies_test.go
index 3d74ff270..54010a19e 100644
--- a/internal/provider/kubernetes/extensionpolicies_test.go
+++ b/internal/provider/kubernetes/extensionpolicies_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -206,7 +207,7 @@ func TestProcessExtensionPolicies(t *testing.T) {
 			objs := []client.Object{}
 
 			// Create the reconciler.
-			logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+			logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 			ctx := context.Background()
 
diff --git a/internal/provider/kubernetes/kubernetes_test.go b/internal/provider/kubernetes/kubernetes_test.go
index 4665f510e..5daf6fba6 100644
--- a/internal/provider/kubernetes/kubernetes_test.go
+++ b/internal/provider/kubernetes/kubernetes_test.go
@@ -60,7 +60,7 @@ func TestProvider(t *testing.T) {
 	require.NoError(t, err)
 
 	// Setup and start the kube provider.
-	svr, err := config.New()
+	svr, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	resources := new(message.ProviderResources)
 	provider, err := New(context.Background(), cliCfg, svr, resources)
@@ -1263,7 +1263,7 @@ func TestNamespacedProvider(t *testing.T) {
 	require.NoError(t, err)
 
 	// Setup and start the kube provider.
-	svr, err := config.New()
+	svr, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	// config to watch a subset of namespaces
 	svr.EnvoyGateway.Provider.Kubernetes = &egv1a1.EnvoyGatewayKubernetesProvider{
@@ -1323,7 +1323,7 @@ func TestNamespaceSelectorProvider(t *testing.T) {
 	require.NoError(t, err)
 
 	// Setup and start the kube provider.
-	svr, err := config.New()
+	svr, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	// config to watch a subset of namespaces
 	svr.EnvoyGateway.Provider.Kubernetes = &egv1a1.EnvoyGatewayKubernetesProvider{
diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go
index 5c9dbba1c..0ccb4999c 100644
--- a/internal/provider/kubernetes/predicates_test.go
+++ b/internal/provider/kubernetes/predicates_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"fmt"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -52,7 +53,7 @@ func TestGatewayClassHasMatchingController(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
@@ -104,7 +105,7 @@ func TestGatewayClassHasMatchingNamespaceLabels(t *testing.T) {
 		},
 	}
 
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	for _, tc := range testCases {
 		r := gatewayAPIReconciler{
@@ -158,7 +159,7 @@ func TestValidateGatewayForReconcile(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
@@ -384,7 +385,7 @@ func TestValidateSecretForReconcile(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
@@ -512,7 +513,7 @@ func TestValidateEndpointSliceForReconcile(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
@@ -941,7 +942,7 @@ func TestValidateServiceForReconcile(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController:    egv1a1.GatewayControllerName,
@@ -1060,7 +1061,7 @@ func TestValidateObjectForReconcile(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
@@ -1167,7 +1168,7 @@ func TestCheckObjectNamespaceLabels(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
@@ -1320,7 +1321,7 @@ func TestValidateHTTPRouteFilerForReconcile(t *testing.T) {
 	}
 
 	// Create the reconciler.
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 	r := gatewayAPIReconciler{
 		classController: egv1a1.GatewayControllerName,
diff --git a/internal/provider/kubernetes/routes_test.go b/internal/provider/kubernetes/routes_test.go
index d1850b9bf..a9e1f7820 100644
--- a/internal/provider/kubernetes/routes_test.go
+++ b/internal/provider/kubernetes/routes_test.go
@@ -7,6 +7,7 @@ package kubernetes
 
 import (
 	"context"
+	"os"
 	"testing"
 	"time"
 
@@ -596,7 +597,7 @@ func TestProcessHTTPRoutes(t *testing.T) {
 			objs := []client.Object{gc, gw}
 
 			// Create the reconciler.
-			logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+			logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 			ctx := context.Background()
 
@@ -756,7 +757,7 @@ func TestProcessGRPCRoutes(t *testing.T) {
 			objs := []client.Object{gc, gw}
 
 			// Create the reconciler.
-			logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+			logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 
 			ctx := context.Background()
 
diff --git a/internal/wasm/cache_test.go b/internal/wasm/cache_test.go
index ba40c0625..6d3edd572 100644
--- a/internal/wasm/cache_test.go
+++ b/internal/wasm/cache_test.go
@@ -691,7 +691,7 @@ func TestWasmCache(t *testing.T) {
 			if c.wasmModuleExpiry != 0 {
 				options.ModuleExpiry = c.wasmModuleExpiry
 			}
-			cache := newLocalFileCache(options, logging.DefaultLogger(egv1a1.LogLevelInfo))
+			cache := newLocalFileCache(options, logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 			cache.httpFetcher.initialBackoff = time.Microsecond
 			ctx, cancel := context.WithTimeout(context.Background(), time.Second*60)
 			cache.Start(ctx)
@@ -878,7 +878,7 @@ func TestWasmCachePolicyChangesUsingHTTP(t *testing.T) {
 	tmpDir := t.TempDir()
 	options := defaultCacheOptions()
 	options.CacheDir = tmpDir
-	cache := newLocalFileCache(options, logging.DefaultLogger(egv1a1.LogLevelInfo))
+	cache := newLocalFileCache(options, logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*60)
 	cache.Start(ctx)
 	defer cancel()
@@ -944,7 +944,7 @@ func TestAllInsecureServer(t *testing.T) {
 	options := defaultCacheOptions()
 	options.CacheDir = tmpDir
 	options.InsecureRegistries = sets.New[string]("*")
-	cache := newLocalFileCache(options, logging.DefaultLogger(egv1a1.LogLevelInfo))
+	cache := newLocalFileCache(options, logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*60)
 	cache.Start(ctx)
 	defer cancel()
diff --git a/internal/wasm/httpfetcher_test.go b/internal/wasm/httpfetcher_test.go
index 98fdda500..3a27e19f1 100644
--- a/internal/wasm/httpfetcher_test.go
+++ b/internal/wasm/httpfetcher_test.go
@@ -27,6 +27,7 @@ import (
 	"fmt"
 	"net/http"
 	"net/http/httptest"
+	"os"
 	"regexp"
 	"strings"
 	"testing"
@@ -97,7 +98,7 @@ func TestWasmHTTPFetch(t *testing.T) {
 				gotNumRequest++
 			}))
 			defer ts.Close()
-			fetcher := NewHTTPFetcher(DefaultHTTPRequestTimeout, DefaultHTTPRequestMaxRetries, logging.DefaultLogger(egv1a1.LogLevelInfo))
+			fetcher := NewHTTPFetcher(DefaultHTTPRequestTimeout, DefaultHTTPRequestMaxRetries, logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 			fetcher.initialBackoff = time.Microsecond
 			ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
 			defer cancel()
@@ -156,7 +157,7 @@ func TestWasmHTTPInsecureServer(t *testing.T) {
 				gotNumRequest++
 			}))
 			defer ts.Close()
-			fetcher := NewHTTPFetcher(DefaultHTTPRequestTimeout, DefaultHTTPRequestMaxRetries, logging.DefaultLogger(egv1a1.LogLevelInfo))
+			fetcher := NewHTTPFetcher(DefaultHTTPRequestTimeout, DefaultHTTPRequestMaxRetries, logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 			fetcher.initialBackoff = time.Microsecond
 			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 			defer cancel()
@@ -257,7 +258,7 @@ func TestWasmHTTPFetchCompressedOrTarFile(t *testing.T) {
 				gotNumRequest++
 			}))
 			defer ts.Close()
-			fetcher := NewHTTPFetcher(DefaultHTTPRequestTimeout, DefaultHTTPRequestMaxRetries, logging.DefaultLogger(egv1a1.LogLevelInfo))
+			fetcher := NewHTTPFetcher(DefaultHTTPRequestTimeout, DefaultHTTPRequestMaxRetries, logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 			fetcher.initialBackoff = time.Microsecond
 			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 			defer cancel()
diff --git a/internal/wasm/httpserver_test.go b/internal/wasm/httpserver_test.go
index 0f054ea84..0fd7c099b 100644
--- a/internal/wasm/httpserver_test.go
+++ b/internal/wasm/httpserver_test.go
@@ -12,6 +12,7 @@ import (
 	"net/http"
 	"net/http/httptest"
 	"net/url"
+	"os"
 	"strings"
 	"testing"
 	"time"
@@ -327,7 +328,7 @@ func setupFakeRegistry(host string) error {
 }
 
 func startLocalHTTPServer(ctx context.Context, cacheDir string, maxFailedAttempts int, failedAttemptResetDelay, failedAttemptsResetInterval time.Duration) (*HTTPServer, error) {
-	logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
+	logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
 	s := NewHTTPServerWithFileCache(
 		SeverOptions{
 			Salt:                        []byte("salt"),
diff --git a/internal/wasm/premissioncache_test.go b/internal/wasm/premissioncache_test.go
index 2fdb95ff1..5066a4189 100644
--- a/internal/wasm/premissioncache_test.go
+++ b/internal/wasm/premissioncache_test.go
@@ -25,6 +25,7 @@ import (
 	"net/http"
 	"net/http/httptest"
 	"net/url"
+	"os"
 	"sync"
 	"testing"
 	"time"
@@ -256,7 +257,7 @@ func setupTestPermissionCache(options permissionCacheOptions, image, latestImage
 	// Setup the permission cache.
 	cache := newPermissionCache(
 		options,
-		logging.DefaultLogger(egv1a1.LogLevelInfo))
+		logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo))
 
 	entry := &permissionCacheEntry{
 		image: image,
diff --git a/internal/xds/server/runner/runner_test.go b/internal/xds/server/runner/runner_test.go
index e0517d1fa..69dd798b8 100644
--- a/internal/xds/server/runner/runner_test.go
+++ b/internal/xds/server/runner/runner_test.go
@@ -195,7 +195,7 @@ func TestServeXdsServerListenFailed(t *testing.T) {
 	require.NoError(t, err)
 	defer l.Close()
 
-	cfg, _ := config.New()
+	cfg, _ := config.New(os.Stdout)
 	r := New(&Config{
 		Server: *cfg,
 	})
diff --git a/internal/xds/translator/runner/runner_test.go b/internal/xds/translator/runner/runner_test.go
index a154b9f82..ee1765f48 100644
--- a/internal/xds/translator/runner/runner_test.go
+++ b/internal/xds/translator/runner/runner_test.go
@@ -8,6 +8,7 @@ package runner
 import (
 	"context"
 	"fmt"
+	"os"
 	"testing"
 	"time"
 
@@ -28,7 +29,7 @@ func TestRunner(t *testing.T) {
 	xdsIR := new(message.XdsIR)
 	xds := new(message.Xds)
 	pResource := new(message.ProviderResources)
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	r := New(&Config{
 		Server:            *cfg,
@@ -108,7 +109,7 @@ func TestRunner_withExtensionManager(t *testing.T) {
 	xds := new(message.Xds)
 	pResource := new(message.ProviderResources)
 
-	cfg, err := config.New()
+	cfg, err := config.New(os.Stdout)
 	require.NoError(t, err)
 	r := New(&Config{
 		Server:            *cfg,
diff --git a/site/content/en/latest/tasks/traffic/grpc-routing.md b/site/content/en/latest/tasks/traffic/grpc-routing.md
index 15f10601b..3a36e9fd7 100644
--- a/site/content/en/latest/tasks/traffic/grpc-routing.md
+++ b/site/content/en/latest/tasks/traffic/grpc-routing.md
@@ -99,7 +99,7 @@ as well as a match for all services with a method name `Ping` which matches `yag
 
 ```shell
 cat <<EOF | kubectl apply -f -
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
 kind: GRPCRoute
 metadata:
   name: yages
@@ -132,7 +132,7 @@ Save and apply the following resource to your cluster:
 
 ```yaml
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
 kind: GRPCRoute
 metadata:
   name: yages
@@ -184,7 +184,7 @@ with match type `RegularExpression`. It matches all the services and methods wit
 
 ```shell
 cat <<EOF | kubectl apply -f -
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
 kind: GRPCRoute
 metadata:
   name: yages
@@ -219,7 +219,7 @@ Save and apply the following resource to your cluster:
 
 ```yaml
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha2
+apiVersion: gateway.networking.k8s.io/v1
 kind: GRPCRoute
 metadata:
   name: yages