- Introduction
- Installation
- Usage
- Code of Conduct
- Working Language
- Support and Feedback
- How to Contribute
- Licensing
This library is a collection of my personal tools and utilities for the Go programming language. It is designed to be used in a wide range of applications, from simple scripts to complex web applications.
It is designed to be simple and easy to use, with a focus on performance and reliability. It is also designed to be flexible and extensible, so that you can easily add new features and functionality as needed.
The library is divided into several packages, each of which provides a different set of tools and utilities. The following is a brief overview of each package:
- config: A wrapper around spf13/viper to load configuration files with into a struct without the need to write boilerplate code.
- lists: A collection of functions to work with lists, such as filtering, mapping, and reducing.
- executors: Some useful executors to handle common scenarios like retries with exponential backoff.
- metrics: A simple wrapper around otel to get a trace provider based on the provided configuration.
To install, run:
go get github.com/lvlcn-t/go-kit
And then import the wanted package in your code:
import "github.com/lvlcn-t/go-kit/<package>"
The following is a brief overview of how you can use the packages provided by this library:
You can use the config
package to load configuration files into a struct. The package provides a simple API to load configuration files and bind them to a struct.
Here is an example of how you can use the config
package to load a configuration file into a struct:
package main
import (
"fmt"
"github.com/lvlcn-t/go-kit/config"
)
type Config struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
func (c Config) IsEmpty() bool {
return c == (Config{})
}
func main() {
// Load the configuration file
cfg, err := config.Load[Config]("config.yaml")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(cfg.Host) // Output: localhost
fmt.Println(cfg.Port) // Output: 8080
}
You can use the lists
package to work with lists in Go. The package provides a collection of functions to work with lists, such as filtering, mapping, and reducing.
Here is an example of how you can use the lists
package to filter a list of integers:
package main
import (
"fmt"
"github.com/lvlcn-t/go-kit/lists"
)
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
// Filter the list to only include even numbers
evens := lists.Filter(numbers, func(n int) bool {
return n%2 == 0
})
fmt.Println(evens) // Output: [2 4 6 8 10]
}
The executors
package provides some useful executors to handle common scenarios like retries with exponential backoff or a simple executor to run a function with a timeout.
Here is an example of how you can use the executors
package to create an executor with multiple policies that are applied to the task in the order of the method calls:
package main
import (
"context"
"fmt"
"time"
"github.com/lvlcn-t/go-kit/executors"
)
func main() {
// Create a task that may fail and needs to be retried
task := executors.Effector(func(ctx context.Context) error {
// Do something that may fail like an HTTP request
return nil
})
// Apply multiple policies to the task
task = task.WithRetry(executors.DefaultRetrier).
WithTimeout(1*time.Second).
WithRateLimit(executors.RateLimit(1)).
WithCircuitBreaker(3, 1*time.Second)
// Run the task with the applied policies with a context
err := task.Do(context.Background())
if err != nil {
// Handle the error after all retries
fmt.Println(err)
}
}
The metrics
package provides two wrappers around open telemetry and prometheus to initialize a trace provider and a prometheus registry.
Here is an example of how you can use the metrics
package to use both the trace provider and the prometheus registry:
package main
import (
"context"
"fmt"
"github.com/lvlcn-t/go-kit/metrics"
"github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/codes"
)
func main() {
ctx := context.Background()
metrics := metrics.New(metrics.Config{
Exporter: metrics.GRPC,
Url: "localhost:4317",
Token: "my-bearer-token",
CertPath: "path/to/my-otel-provider/cert.pem",
})
// Initialize the open telemetry tracer with the given service name and version
err := metrics.Initialize(ctx, "my-service-name", "v0.1.0")
if err != nil {
fmt.Println("failed to initialize metrics:", err)
return
}
defer func() {
if err := metrics.Shutdown(ctx); err != nil {
fmt.Println("failed to shutdown metrics:", err)
}
}()
// Register some prometheus collectors to the registry
registry := metrics.GetRegistry()
registry.MustRegister(&prometheus.GaugeVec{})
logTraceEvent(ctx)
}
// logTraceEvent logs a trace event using the OpenTelemetry tracer
func logTraceEvent(ctx context.Context) {
tp := otel.GetTracerProvider()
tracer := tp.Tracer("my-service-name")
_, span := tracer.Start(ctx, "my-span")
defer span.End()
span.AddEvent("my-event")
span.SetStatus(codes.Error, "my-error")
span.RecordError(fmt.Errorf("my-error"))
}
This project has adopted the Contributor Covenant in version 2.1 as our code of conduct. Please see the details in our CODE_OF_CONDUCT.md. All contributors must abide by the code of conduct.
We decided to apply English as the primary project language.
Consequently, all content will be made available primarily in English. We also ask all interested people to use English as the preferred language to create issues, in their code (comments, documentation, etc.) and when you send requests to us. The application itself and all end-user facing content will be made available in other languages as needed.
The following channels are available for discussions, feedback, and support requests:
Type | Channel |
---|---|
Issues |
Contribution and feedback is encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines. By participating in this project, you agree to abide by its Code of Conduct at all times.
Copyright (c) 2024 lvlcn-t.
Licensed under the MIT (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at https://www.mit.edu/~amini/LICENSE.md.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an " AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the LICENSE for the specific language governing permissions and limitations under the License.