Skip to content

Commit b7944e7

Browse files
committed
drop zerolog; introduce slog
1 parent 2e95ad9 commit b7944e7

File tree

106 files changed

+3433
-10083
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+3433
-10083
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.go text eol=lf

.golangci.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# yaml-language-server: $schema=https://golangci-lint.run/jsonschema/golangci.jsonschema.json
2+
13
# https://golangci-lint.run/usage/configuration/
24
# https://golangci-lint.run/usage/linters/
35

@@ -21,6 +23,8 @@ output:
2123
linters:
2224
enable-all: true
2325
disable:
26+
- exportloopref # deprecated
27+
- execinquery # deprecated
2428
- exhaustruct # TODO: reconsider
2529
- depguard # TODO: reconsider
2630
- funlen # TODO: reconsider
@@ -30,6 +34,11 @@ linters:
3034
- varnamelen
3135
- nonamedreturns
3236
- testpackage
37+
- godox
38+
- godot
39+
- gochecknoglobals
40+
- gomnd
41+
- mnd
3342

3443
issues:
3544
# https://golangci-lint.run/usage/false-positives/#default-exclusions
@@ -50,7 +59,6 @@ linters-settings:
5059
unused:
5160
field-writes-are-uses: false
5261
post-statements-are-reads: false
53-
exported-is-used: true
5462
exported-fields-are-used: true
5563
parameters-are-used: true
5664
local-variables-are-used: false

.vscode/launch.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
],
2323
},
2424
{
25-
"name": "Run Main",
25+
"name": "Debug Main",
2626
"preLaunchTask": "build debug",
2727
"type": "go",
2828
"request": "launch",
29-
"mode": "exec",
30-
"program": "${workspaceFolder}/output/goboilerplate",
29+
"mode": "debug",
30+
"program": "${workspaceFolder}/cmd/goboilerplate",
3131
"debugAdapter": "dlv-dap",
3232
"buildFlags": "",
3333
"env": {
@@ -36,7 +36,7 @@
3636
"APP_HTTP_OUTBOUND_TRAFFIC_LOG_LEVEL": "2",
3737
"APP_HTTP_READ_HEADER_TIMEOUT": "3s",
3838
"APP_SHUTDOWN_TIMEOUT": "6s",
39-
"APP_LOG_LEVEL": "-1"
39+
"APP_LOG_LEVEL": "DEBUG"
4040
}
4141
}
4242
]

README.md

Lines changed: 13 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
# Go service boilerplate
22

33
The boilerplate consists of:
4-
* Go code with [chi](https://github.com/go-chi/chi) http router, [zerolog](https://github.com/rs/zerolog) logging, [knadh/koanf](github.com/knadh/koanf) config library and [testify](github.com/stretchr/testify). Basic code infra with http setup and request and response logger (configurable), logging setup, config setup and graceful shutdown.
4+
* Go code with
5+
* [chi](https://github.com/go-chi/chi) http router.
6+
* [slog](https://pkg.go.dev/log/slog) logging,
7+
* [knadh/koanf](github.com/knadh/koanf) config library.
8+
* [testify](github.com/stretchr/testify).
9+
* Basic code infra with http setup and request and response logger (configurable), logging setup, config setup and graceful shutdown.
10+
* Optional verbose logging of http traffic, with payload,
511
* Makefile targets for local installation of external tools (`staticcheck`, `golangci-lint`, `goimports`, `gofumpt`, `gojq`, `air`).
612
* Makefile targets for linting (installing all necessary tools locally), building, testing, and local run (docker compose or native).
713
* [GitHub Actions](https://github.com/features/actions) for linter checks and tests on each pr.
814
* [Dependabot](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates) setup for updating dependencies.
915
* [Visual Studio Code](https://code.visualstudio.com/) settings, tasks and launch configuration for building, debugging and testing the code.
1016
* Docker compose and development Dockerfile with hot-rebuild (using [air](https://github.com/air-verse/air)) and dlv debug server.
11-
* Production Dockerfile
17+
* Production Dockerfile.
1218

1319
## How to use
1420
1. Click `Use this template` from this repo github page, and choose your destination repo/name (e.g. `github.com/glendale/service`)
@@ -17,6 +23,7 @@ The boilerplate consists of:
1723

1824

1925
## Go package and file structure
26+
The project structure attempts to be on a par with [golang-standards/project-layout](https://github.com/golang-standards/project-layout).
2027

2128
> Every local package that collides with a golang std package is named with `x` postfix. For example `.../internal/httpx` or `.../internal/logx`. By doing this cheat you can avoid putting aliases when you need both of those and you can take advantage of package autocomplete/autoimport features more easily than having colliding names.
2229
@@ -26,125 +33,12 @@ The boilerplate consists of:
2633
| `internal/exec.go` | the `Main` struct that wraps the long running / signal handling / graceful shutdown of the service |
2734
| `internal/config` | this package contain the initialization of `koanf` config. |
2835
| `internal/httpx` | this package contains: the setup of the `chi` router, some helpers functions for parsing/writing http request and http response and some middlewares like for logging each request/response. |
29-
| `internal/logx` | this package contains the setup/init function for `zerolog` logger. |
36+
| `internal/logx` | this package contains the setup/init function for `slog` logger. |
3037

3138
| Folder/File | Description |
3239
|--------------------|-----------------------------------------|
33-
| `deployments` | this folder is intended to hold everything regarding deployment (e.g. helm/kubernetes etc). Inside `compose` directory a `docker-compose.yml` file is included that is intended for local development. |
40+
| `deployments` | this folder is intended to hold everything regarding deployment (e.g. helm/kubernetes etc). Inside `local` directory a `docker-compose.yml` file is included that is intended for local development. |
3441
| `build/docker` | this folder contains production-like docker file as well as a local development one. |
3542

36-
37-
38-
39-
## Make file targets
40-
41-
42-
### Build, Debug and Local Deploy Targets
43-
44-
#### `build`
45-
Builds all binaries under `./cmd` (one for each directory) and outputs the binaries into `./output` folder using this patter `./cmd/<directory name> -> ./output/<directory name>`.
46-
___
47-
48-
#### `cmd.<directory name>`
49-
Builds a specific cmd directory `<directory name>` and outputs the binary into `./output` folder using this pattern `./cmd/<directory name> -> ./output/<directory name>`.
50-
___
51-
52-
#### `clean`
53-
Deletes `./output` folder.
54-
___
55-
56-
#### `compose-up`
57-
Deploys (rebuilds and recreates) the docker compose file `deployments/compose/docker-compose.yml` in attached mode. This docker compose file is intended for local development.<br>
58-
It uses the docker file `build/docker/debug.Dockerfile` and runs `air` target (see below), including hot-reload (rebuild on changes) and debug server.
59-
___
60-
61-
#### `compose-down`
62-
Stops (if started) the containers specified by the docker compose file `deployments/compose/docker-compose.yml` removes containers, cleans up the volumes and delete local docker images.
63-
___
64-
65-
#### `air`
66-
Installs (if needed) [air](https://github.com/air-verse/air) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `air -c .air.toml`. <br>
67-
Air watches for code file changes and rebuilds the binary according to the configuration `.air.toml`. <br>
68-
Current air configuration executes `cmd.goboilerplate` target (on each file change) and then runs the `./build/dlv` that starts the debug server (`dlv exec`) with the produced binary.
69-
___
70-
71-
#### `image`
72-
Builds the docker image using the docker file `./build/docker/Dockerfile`. <br>
73-
This docker file is intended to be used as a production image. <br>
74-
Image name and tag are specified by `IMAGE_NAME` and `IMAGE_TAG`. Default values can be overwritten during execution (eg `make IMAGE_NAME=myimage IMAGE_TAG=1.0.0 image`).
75-
___
76-
77-
78-
### Util Targets
79-
80-
#### `mod`
81-
Runs go mod [tidy](https://go.dev/ref/mod#go-mod-tidy) and [verify](https://go.dev/ref/mod#go-mod-verify).
82-
___
83-
84-
#### `vendor`
85-
Runs [go mod vendor](https://go.dev/ref/mod#go-mod-vendor) that downloads all dependencies into `./vendor` folder.
86-
___
87-
88-
#### `env`
89-
Prints information regarding the local environment. More specifically: go env, all go packages and folders, and the specified tools bin directory.
90-
___
91-
92-
#### `git-reset`
93-
Full hard reset to HEAD. Cleans up all untracked files and restore all staged and un-staged changes.
94-
___
95-
96-
97-
### Tests and Linters Targets
98-
99-
#### `test`
100-
Runs go [test](https://pkg.go.dev/cmd/go/internal/test) with race conditions and prints cover report.
101-
___
102-
103-
#### `tools`
104-
Installs (if needed) all tools (goimports, staticcheck, gofumpt, etc) under `TOOLS_BIN` folder (default is `./.tools/bin`).
105-
___
106-
107-
#### `checks`
108-
Runs all default checks (`vet`, `staticcheck`, `gofumpt`, `goimports`, `golangci-lint`).
109-
___
110-
111-
#### `vet`
112-
Runs go [vet](https://pkg.go.dev/cmd/vet).
113-
___
114-
115-
#### `gofumpt`
116-
Installs (if needed) [gofumpt](https://github.com/mvdan/gofumpt) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `gofumpt` for each folder. <br>
117-
If `gofumpt` finds files that need fix/format it displays those files as list and the target fails (_exit 1_).
118-
___
119-
120-
#### `gofumpt.display`
121-
In case of `gofumpt` fails this target can be used to display the necessary changes. It runs `gofumpt -d` to display the needed changes that can be applied with `make gofumpt.fix`.
122-
___
123-
124-
#### `gofumpt.fix`
125-
Runs `gofumpt -w` to fix/format files (that need fix).
126-
___
127-
128-
#### `goimports`
129-
Installs (if needed) [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `goimports` for each folder. <br>
130-
If `goimports` finds files that need fix/format it displays those files as list and the target fails (_exit 1_).
131-
___
132-
133-
#### `goimports.display`
134-
In case of `goimports` fails this target can be used to display the necessary changes. It runs `goimports -d` to display the needed changes that can be applied with `make goimports.fix`.
135-
___
136-
137-
#### `goimports.fix`
138-
Runs `goimports -w` to fix files (that need fix).
139-
___
140-
141-
#### `staticcheck`
142-
Installs (if needed) [staticcheck](https://staticcheck.io/) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `staticcheck` using all [checks](https://staticcheck.io/docs/checks) excluding [ST1000](https://staticcheck.io/docs/checks/#ST1000). <br>
143-
If issues are found the target fails (due to `staticcheck` exit status).
144-
___
145-
146-
#### `golangci-lint`
147-
Installs (if needed) [golangci-lint](https://golangci-lint.run/) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `golangci-lint`. <br>
148-
If issues are found the target fails (due to `golangci-lint` exit status).
149-
___
150-
43+
## Makefile targets
44+
Makefile targets can be found in [docs/makefile_targets.md](docs/makefile_targets.md) file.

api/sample.http

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
GET http://localhost:8888/about
2+
Accept: application/json
3+
Accept-Encoding: gzip, deflate, br
4+
5+
GET http://localhost:8888/echo
6+
Accept: application/json
7+
Accept-Encoding: gzip, deflate, br
8+
{
9+
"test": "value"
10+
}

build/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# https://docs.docker.com/build/guide/mounts/
55

66
# https://hub.docker.com/_/golang
7-
FROM --platform=$BUILDPLATFORM golang:1.23.0-alpine3.20 AS builder
7+
FROM --platform=$BUILDPLATFORM golang:1.23.2-alpine3.20 AS builder
88
RUN apk update && apk add --no-cache make git bash ca-certificates
99
WORKDIR /app
1010
ARG TARGETOS TARGETARCH

build/docker/debug.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
### https://hub.docker.com/r/docker/dockerfile
33

44
# https://hub.docker.com/_/golang
5-
FROM golang:1.23.0-alpine3.20
5+
FROM golang:1.23.2-alpine3.20
66

77
WORKDIR /wd
88

cmd/goboilerplate/main.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package main
33
import (
44
"context"
55
"fmt"
6+
"log/slog"
7+
"os"
68

79
"github.com/moukoublen/goboilerplate/internal"
810
"github.com/moukoublen/goboilerplate/internal/config"
911
"github.com/moukoublen/goboilerplate/internal/httpx"
1012
"github.com/moukoublen/goboilerplate/internal/logx"
11-
"github.com/rs/zerolog/log"
1213
)
1314

1415
func defaultConfigs() map[string]any {
@@ -31,22 +32,26 @@ func defaultConfigs() map[string]any {
3132
}
3233

3334
func main() {
34-
cnf, err := config.Load("APP_", defaultConfigs())
35+
// pre-init slog with default config
36+
logger := logx.InitSLog(logx.Config{LogType: logx.LogTypeText, Level: slog.LevelInfo})
37+
logger.Info("starting up...")
38+
39+
cnf, err := config.Load(context.Background(), "APP_", defaultConfigs())
3540
if err != nil {
36-
log.Fatal().Err(err).Send()
41+
logger.Error("error during config init", logx.Error(err))
42+
os.Exit(1)
3743
}
3844

39-
logx.SetupLog(logx.ParseConfig(cnf))
40-
log.Info().Msgf("Starting up")
45+
logger = logx.InitSLog(logx.ParseConfig(cnf))
4146

4247
daemon, ctx := internal.NewDaemon(
4348
context.Background(),
49+
logger,
4450
internal.SetShutdownTimeout(cnf.Duration("shutdown_timeout")),
4551
)
46-
_ = ctx
4752

4853
httpConf := httpx.ParseConfig(cnf)
49-
router := httpx.NewDefaultRouter(httpConf)
54+
router := httpx.NewDefaultRouter(ctx, httpConf)
5055

5156
// init services / application
5257
server := httpx.StartListenAndServe(
@@ -55,14 +60,14 @@ func main() {
5560
httpConf.ReadHeaderTimeout,
5661
daemon.FatalErrorsChannel(),
5762
)
58-
log.Info().Msgf("service started at %s:%d", httpConf.IP, httpConf.Port)
63+
logger.InfoContext(ctx, "service started", slog.String("bind", fmt.Sprintf("%s:%d", httpConf.IP, httpConf.Port)))
5964

6065
// set onShutdown for other components/services.
6166
daemon.OnShutDown(
6267
func(ctx context.Context) {
63-
log.Info().Msg("shuting down http server")
68+
logger.InfoContext(ctx, "shuting down http server")
6469
if err := server.Shutdown(ctx); err != nil {
65-
log.Warn().Err(err).Msg("error during http server shutdown")
70+
logger.Warn("error during http server shutdown", logx.Error(err))
6671
}
6772
},
6873
)

docs/makefile_targets.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Makefile targets
2+
3+
| Target | Description |
4+
| -------------------- | ----------- |
5+
| `mod` | Runs go mod [tidy](https://go.dev/ref/mod#go-mod-tidy) and [verify](https://go.dev/ref/mod#go-mod-verify). |
6+
| `vendor` | Runs [go mod vendor](https://go.dev/ref/mod#go-mod-vendor) that downloads all dependencies into `./vendor` folder. |
7+
| `go-deps-upgrade` | Runs updates all `go.mod` dependencies. |
8+
| `env` | Prints information regarding the local environment. More specifically: go env, all go packages and folders, and the specified tools bin directory. |
9+
| `git-reset` | Full hard reset to HEAD. Cleans up all untracked files and restore all staged and un-staged changes. |
10+
| `build` | Builds all binaries under `./cmd` (one for each directory) and outputs the binaries into `./output` folder using this pattern: `./cmd/<directory name> -> ./output/<directory name>`. |
11+
| `cmd.<cmd dir name>` | Builds a specific cmd directory `<directory name>` and outputs the binary into `./output` folder using this pattern: `./cmd/<directory name> -> ./output/<directory name>`.
12+
| `dbg.<cmd dir name>` | Builds a specific cmd directory `<directory name>` (keeping debug symbols) and outputs the binary into `./output` folder using this pattern: `./cmd/<directory name> -> ./output/<directory name>`.
13+
| `clean` | Deletes `./output` folder.
14+
| `compose-up` | Deploys (rebuilds and recreates) the docker compose file `deployments/compose/docker-compose.yml` in attached mode. This docker compose file is intended for local development.<br>It uses the docker file `build/docker/debug.Dockerfile` and runs `air` target (see below), including hot-reload (rebuild on changes) and debug server.
15+
| `compose-down` | Stops (if started) the containers specified by the docker compose file `deployments/compose/docker-compose.yml` removes containers, cleans up the volumes and delete local docker images.
16+
| `air` | Installs (if needed) [air](https://github.com/air-verse/air) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `air -c .air.toml`.<br>Air watches for code file changes and rebuilds the binary according to the configuration `.air.toml`.<br>Current air configuration executes `cmd.goboilerplate` target (on each file change) and then runs the `./build/dlv` that starts the debug server (`dlv exec`) with the produced binary.
17+
| `image` | Builds the docker image using the docker file `./build/docker/Dockerfile`.<br>This docker file is intended to be used as a production image.<br>Image name and tag are specified by `IMAGE_NAME` and `IMAGE_TAG`. Default values can be overwritten during execution (eg `make IMAGE_NAME=myimage IMAGE_TAG=1.0.0 image`).
18+
| `test` | Runs go [test](https://pkg.go.dev/cmd/go/internal/test) with race conditions and prints cover report.
19+
| `tools` | Installs (if needed) all tools (goimports, staticcheck, gofumpt, etc) under `TOOLS_BIN` folder (default is `./.tools/bin`).
20+
| `checks` | Runs all default checks (`vet`, `staticcheck`, `gofumpt`, `goimports`, `golangci-lint`).
21+
| `vet` | Runs go [vet](https://pkg.go.dev/cmd/vet).
22+
| `gofumpt` | Installs (if needed) [gofumpt](https://github.com/mvdan/gofumpt) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `gofumpt` for each folder.<br>If `gofumpt` finds files that need fix/format it displays those files as list and the target fails (_exit 1_).
23+
| `gofumpt.fix` | Runs `gofumpt -w` to fix/format files (that need fix).
24+
| `goimports` | Installs (if needed) [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `goimports` for each folder.<br>If `goimports` finds files that need fix/format it displays those files as list and the target fails (_exit 1_).
25+
| `goimports.fix` | Runs `goimports -w` to fix files (that need fix).
26+
| `staticcheck` | Installs (if needed) [staticcheck](https://staticcheck.io/) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `staticcheck` using all [checks](https://staticcheck.io/docs/checks) excluding [ST1000](https://staticcheck.io/docs/checks/#ST1000).<br>If issues are found the target fails (due to `staticcheck` exit status).
27+
| `golangci-lint` | Installs (if needed) [golangci-lint](https://golangci-lint.run/) under `TOOLS_BIN` folder (default is `./.tools/bin`) and runs `golangci-lint`. <br>If issues are found the target fails (due to `golangci-lint` exit status).
28+

go.mod

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ require (
1010
github.com/knadh/koanf/providers/env v0.1.0
1111
github.com/knadh/koanf/providers/file v1.1.0
1212
github.com/knadh/koanf/v2 v2.1.1
13-
github.com/rs/zerolog v1.33.0
1413
github.com/stretchr/testify v1.9.0
1514
)
1615

@@ -20,11 +19,8 @@ require (
2019
github.com/go-viper/mapstructure/v2 v2.1.0 // indirect
2120
github.com/joho/godotenv v1.5.1 // indirect
2221
github.com/knadh/koanf/maps v0.1.1 // indirect
23-
github.com/mattn/go-colorable v0.1.13 // indirect
24-
github.com/mattn/go-isatty v0.0.20 // indirect
2522
github.com/mitchellh/copystructure v1.2.0 // indirect
2623
github.com/mitchellh/reflectwalk v1.0.2 // indirect
27-
github.com/pkg/errors v0.9.1 // indirect
2824
github.com/pmezard/go-difflib v1.0.0 // indirect
2925
github.com/stretchr/objx v0.5.2 // indirect
3026
golang.org/x/sys v0.25.0 // indirect

0 commit comments

Comments
 (0)