Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joe-elliott/4c160e0d8f38d92338d43b724ef70015 to your computer and use it in GitHub Desktop.
Save joe-elliott/4c160e0d8f38d92338d43b724ef70015 to your computer and use it in GitHub Desktop.
HTTP <> GRPC Cortex Distributors
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
"github.com/weaveworks/common/httpgrpc"
"github.com/weaveworks/common/httpgrpc/server"
"google.golang.org/grpc"
)
const grpcServiceConfig = `{"loadBalancingPolicy":"round_robin"}`
type grpcProxy struct {
client httpgrpc.HTTPClient
}
func main() {
// if this DNS entry returns a list of IPs the above grpcServiceConfig will make grpc attempt to load balance over them
distributorHostPort := "localhost:9001"
listenHostPort := "192.168.1.126:8000"
// grpc client (sends to distributor)
dialOptions := []grpc.DialOption{
grpc.WithDefaultServiceConfig(grpcServiceConfig),
grpc.WithInsecure(),
}
conn, err := grpc.Dial(distributorHostPort, dialOptions...)
if err != nil {
panic(err)
}
proxy := &grpcProxy{
client: httpgrpc.NewHTTPClient(conn),
}
// http server (receives from pushes from client)
// Note: the handler has been added to two common paths. Use whatever makes sense for your config
r := mux.NewRouter()
r.HandleFunc("/api/v1/push", proxy.ServeHTTP)
r.HandleFunc("/api/prom/push", proxy.ServeHTTP)
http.Handle("/", r)
handler := http.Handler(r)
srv := &http.Server{
Handler: handler,
Addr: listenHostPort,
}
fmt.Println("listening...")
log.Fatal(srv.ListenAndServe())
}
// ServeHTTP implements http.Handler
func (g *grpcProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
req, err := server.HTTPRequest(r)
if err != nil {
fmt.Println(err)
return
}
resp, err := g.client.Handle(r.Context(), req)
if err != nil {
// Some errors will actually contain a valid resp, just need to unpack it
var ok bool
resp, ok = httpgrpc.HTTPResponseFromError(err)
if !ok {
fmt.Println(err)
return
}
}
if err := server.WriteResponse(w, resp); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment