Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,18 @@ linters-settings:
ignore-words: []

wrapcheck:
ignoreSigs: []
ignoreSigRegexps: []
ignoreSigs:
- .Errorf(
- errors.New(
- errors.Unwrap(
- errors.Join(
- .Wrap(
- .Wrapf(
- .WithMessage(
- .WithMessagef(
- .WithStack(
- errs.NewPublicError(
- errs.WithPublicMessage(
- withstack.WithStackDepth(
ignoreSigRegexps:
- \.New.*Error\(
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,39 @@ A logger utility library, with support for TEXT and JSON logging (with optional
Simple [valyala/fasthttp](https://github.com/valyala/fasthttp) wrapper library with user-friendly interface and built-in request/response acquire and release.

[See here](httpclient/go.mod).

## postgres

`postgres` provides a wrapper around `pgx/v5` for connecting to PostgreSQL databases. It simplifies configuration, connection pooling, and integrates structured logging with `slog`.

[See here](postgres/README.md).

## redis

`redis` provides a wrapper around `go-redis` (v9) for connecting to Redis servers. It simplifies configuration and integrates structured logging with `slog`.

[See here](redis/README.md).

## cloudkms

`cloudkms` provides a simplified wrapper around the Google Cloud Key Management Service (KMS) API, making it easier to encrypt and decrypt data using Cloud KMS keys.

[See here](cloudkms/README.md).

## encryption

`encryption` provides simple and secure encryption utilities using ChaCha20-Poly1305, with base64 encoding/decoding support.

[See here](encryption/README.md).

## errs

`errs` defines a set of common application errors, built on top of `cockroachdb/errors`.

[See here](errs/README.md).

## automaxprocs

Automatically set GOMAXPROCS to match Linux container CPU quota by calling `automaxprocs.Init()`.

[See here](automaxprocs/README.md).
12 changes: 12 additions & 0 deletions automaxprocs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/Cleverse/go-utilities/automaxprocs.svg)](https://pkg.go.dev/github.com/Cleverse/go-utilities/automaxprocs)
[![Report card](https://goreportcard.com/badge/github.com/Cleverse/go-utilities/automaxprocs)](https://goreportcard.com/report/github.com/Cleverse/go-utilities/automaxprocs)

# automaxprocs

Automatically set GOMAXPROCS to match Linux container CPU quota by calling `automaxprocs.Init()`.

## Installation

```shell
go get github.com/Cleverse/go-utilities/automaxprocs
```
99 changes: 99 additions & 0 deletions automaxprocs/automaxprocs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package automaxprocs

import (
"context"
"fmt"
"log/slog"
"os"
"runtime"

"github.com/Cleverse/go-utilities/logger"
"github.com/Cleverse/go-utilities/logger/slogx"
"github.com/Cleverse/go-utilities/utils"
"github.com/cockroachdb/errors"
"go.uber.org/automaxprocs/maxprocs"
)

var (
// undo is the undo function returned by maxprocs.Set
undo func()

// autoMaxProcs is the value of GOMAXPROCS set by automaxprocs.
// will be -1 if `automaxprocs` is not initialized.
autoMaxProcs = -1

// initialMaxProcs is the initial value of GOMAXPROCS.
initialMaxProcs = Current()
)

func Init() error {
ctx := logger.WithContext(context.Background(),
slogx.String("package", "automaxprocs"),
slogx.String("event", "set_gomaxprocs"),
slogx.Int("prev_maxprocs", initialMaxProcs),
)

// Create a logger function for `maxprocs.Set`.
setMaxProcLogger := func(format string, v ...any) {
fields := make([]slog.Attr, 0, 1)

// `maxprocs.Set` will always pass current GOMAXPROCS value to logger.
// except when calling `undo` function, it will not pass any value.
if val, ok := utils.Optional(v); ok {
// if `GOMAXPROCS` environment variable is set, then `automaxprocs` will honor it.
if _, exists := os.LookupEnv("GOMAXPROCS"); exists {
val = Current()
}

// add logging field for `set_maxprocs` value if it's present in integer value.
if setmaxprocs, ok := val.(int); ok {
fields = append(fields, slogx.Int("set_maxprocs", setmaxprocs))
}
}

logger.LogAttrs(ctx, slog.LevelInfo, fmt.Sprintf(format, v...), fields...)
}

// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
// any error encountered and an undo function.
//
// Set is a no-op on non-Linux systems and in Linux environments without a
// configured CPU quota.
revert, err := maxprocs.Set(maxprocs.Logger(setMaxProcLogger), maxprocs.Min(1))
if err != nil {
return errors.WithStack(err)
}

// set the result of `maxprocs.Set` to global variable.
autoMaxProcs = Current()
undo = revert
return nil
}

// Undo restores GOMAXPROCS to its previous value.
// or revert to initial value if `automaxprocs` is not initialized.
//
// returns the current GOMAXPROCS value.
func Undo() int {
if undo != nil {
undo()
return Current()
}

runtime.GOMAXPROCS(initialMaxProcs)
return initialMaxProcs
}

// Current returns the current value of GOMAXPROCS.
func Current() int {
return runtime.GOMAXPROCS(0)
}

// Value returns the value of GOMAXPROCS set by automaxprocs.
// returns -1 if `automaxprocs` is not initialized.
func Value() int {
if autoMaxProcs <= 0 {
return -1
}
return autoMaxProcs
}
27 changes: 27 additions & 0 deletions automaxprocs/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module github.com/Cleverse/go-utilities/automaxprocs.go

go 1.25

require (
github.com/Cleverse/go-utilities/logger v0.0.0-20250808171844-1347aec4138e
github.com/Cleverse/go-utilities/utils v0.0.0-20250808171844-1347aec4138e
github.com/cockroachdb/errors v1.12.0
go.uber.org/automaxprocs v1.6.0
)

require (
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lmittmann/tint v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/samber/lo v1.50.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
)
82 changes: 82 additions & 0 deletions automaxprocs/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
github.com/Cleverse/go-utilities/logger v0.0.0-20250808171844-1347aec4138e h1:P9USaX1SmuX2VoUtzxUUN2U284Zsi88Ksxqisy3HPyk=
github.com/Cleverse/go-utilities/logger v0.0.0-20250808171844-1347aec4138e/go.mod h1:FMj+TX4mtdYCx9jbQ33HojfxGjohsCkNORZWfBMea04=
github.com/Cleverse/go-utilities/utils v0.0.0-20250808171844-1347aec4138e h1:QA8akNbOw64X0Ypj3VH0bPn0CDYu39l0PpQo10GoNlk=
github.com/Cleverse/go-utilities/utils v0.0.0-20250808171844-1347aec4138e/go.mod h1:ft8CEDBt0csuZ+yM/bKf7ZlV6lWvWY/TFXzp7+Ze9Jw=
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lmittmann/tint v1.1.1 h1:xmmGuinUsCSxWdwH1OqMUQ4tzQsq3BdjJLAAmVKJ9Dw=
github.com/lmittmann/tint v1.1.1/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/samber/lo v1.50.0 h1:XrG0xOeHs+4FQ8gJR97zDz5uOFMW7OwFWiFVzqopKgY=
github.com/samber/lo v1.50.0/go.mod h1:RjZyNk6WSnUFRKK6EyOhsRJMqft3G+pg7dCWHQCWvsc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
12 changes: 12 additions & 0 deletions cloudkms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/Cleverse/go-utilities/cloudkms.svg)](https://pkg.go.dev/github.com/Cleverse/go-utilities/cloudkms)
[![Report card](https://goreportcard.com/badge/github.com/Cleverse/go-utilities/cloudkms)](https://goreportcard.com/report/github.com/Cleverse/go-utilities/cloudkms)

# cloudkms

`cloudkms` provides a simplified wrapper around the Google Cloud Key Management Service (KMS) API, making it easier to encrypt and decrypt data using Cloud KMS keys.

## Installation

```shell
go get github.com/Cleverse/go-utilities/cloudkms
```
Loading
Loading