This package provides helpers to setup HTTP and gRPC servers following best practices. It includes helpers for
- gRPC and HTTP
- logging
- tracing
- metrics collection
- recovery
- only for gRPC
- credential loading
- reflection
package main
import (
"context"
"github.com/contiamo/goserver"
grpcserver "github.com/contiamo/goserver/grpc"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
func main() {
// setup grpc server with options
grpcServer, err := grpcserver.New(&grpcserver.Config{
Options: []grpcserver.Option{
grpcserver.WithCredentials("cert.pem","key.pem","ca.pem"),
grpcserver.WithTracing("localhost:6831", "example"),
grpcserver.WithLogging("grpc-echo"),
grpcserver.WithMetrics(),
grpcserver.WithRecovery(),
grpcserver.WithReflection(),
},
Extras: []grpc.ServerOption{
grpc.MaxSendMsgSize(1 << 12),
},
Register: func(srv *grpc.Server) {
RegisterEchoServer(srv, &echoServer{})
},
})
if err != nil {
logrus.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
// start server
go grpcserver.ListenAndServe(ctx, ":3001", grpcServer)
// start /metrics endpoint
go goserver.ListenAndServeMonitoring(ctx, ":8080", nil)
<-c
cancel()
}
package main
import (
"io"
"net/http"
"github.com/contiamo/goserver"
httpserver "github.com/contiamo/goserver/http"
"github.com/sirupsen/logrus"
)
func main() {
// setup http server with options
httpServer, err := httpserver.New(&httpserver.Config{
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
span, _ := opentracing.StartSpanFromContext(r.Context(), "logic")
defer span.Finish()
io.Copy(w, r.Body)
}),
Options: []httpserver.Option{
httpserver.WithLogging("http-echo"),
httpserver.WithTracing("localhost:6831", "example", nil, nil),
httpserver.WithMetrics("http-echo", nil),
httpserver.WithRecovery(os.Stderr, true),
},
})
if err != nil {
logrus.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
// start server
go httpserver.ListenAndServe(ctx, ":8000", httpServer)
// start /metrics endpoint
go goserver.ListenAndServeMonitoring(ctx, ":8080", nil)
<-c
cancel()
}
It's not necessary to use goserver's server component. It is also possible to use it just as middleware in other servers. For example, to us 6EC6 e goserver's recovery and logging middleware with chi, you can do the following:
package main
import (
"io"
"net/http"
goserver "github.com/contiamo/goserver/http"
"github.com/go-chi/chi"
)
func main() {
r := chi.NewRouter()
// initialize goserver middleware
logging := goserver.WithLogging("application-name")
recovery := goserver.WithRecovery(os.Stderr, true)
// tell the chi router to use the goserver middleware
r.Use(logging.WrapHandler)
r.Use(recovery.WrapHandler)
// ... setup your routes and handlers...
// start the server
http.ListenAndServe(":8080", r)
}