Skip to content
This repository has been archived by the owner on Mar 18, 2022. It is now read-only.
/ goserver Public archive

helper package to setup network apps with ease

License

Notifications You must be signed in to change notification settings

contiamo/goserver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

goserver

Go Report Card Documentation

Scope

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

Example

gRPC

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()
}

HTTP

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()
}

Using goserver as Middleware

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 use 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)
}

To run the server and metrics on a different port:

  go func() {
  	err := http.ListenAndServe(":8080", r)
	if err != nil {
		log.Fatal(err)
	}
  }()

  err = goserver.ListenAndServeMetricsAndHealth(:8081, nil)
  if err != nil {
	log.Fatal(err)
  }