https://github.com/go-masonry/mortar
Mortar is a GO framework/library for building gRPC (and REST) web services.
https://github.com/go-masonry/mortar
dependency-injection di fx golang grpc metrics microservice middleware monitoring opentracing prometheus protobuf trace
Last synced: 6 months ago
JSON representation
Mortar is a GO framework/library for building gRPC (and REST) web services.
- Host: GitHub
- URL: https://github.com/go-masonry/mortar
- Owner: go-masonry
- License: mit
- Created: 2020-08-02T10:50:28.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-12-15T11:41:32.000Z (almost 2 years ago)
- Last Synced: 2024-11-05T13:42:35.818Z (11 months ago)
- Topics: dependency-injection, di, fx, golang, grpc, metrics, microservice, middleware, monitoring, opentracing, prometheus, protobuf, trace
- Language: Go
- Homepage: https://go-masonry.github.io
- Size: 1.89 MB
- Stars: 676
- Watchers: 17
- Forks: 20
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-grpc - Mortar - GO framework for building gRPC (and REST) web services with DI, Telemetry and more (Language-Specific / Go)
README
# Mortar

[](https://codecov.io/gh/go-masonry/mortar)
[](https://pkg.go.dev/mod/github.com/go-masonry/mortar)
[](https://goreportcard.com/report/github.com/go-masonry/mortar)
Mortar is a GO framework/library for building gRPC (and REST) web services. Mortar has out-of-the-box support for configuration, application metrics, logging, tracing, profiling, dependency injection and more. While it comes with predefined defaults, Mortar gives you total control to fully customize it.
## Demo
Clone this [demo](http://github.com/go-masonry/mortar-demo) repository to better understand some of Mortar capabilities.
When you done, read the [documentation](https://go-masonry.github.io).
## Service Template
To help you bootstrap your services with Mortar [here](https://github.com/go-masonry/mortar-template) you can find a template. Read its README first.
## Features
- Bundled [Grpc-Gateway](https://github.com/grpc-ecosystem/grpc-gateway) (REST Reverse-Proxy).
- Dependency Injection using [Uber-FX](https://github.com/uber-go/fx).
- Pimped `*http.Client` with interceptors support.
- Abstract support for Logging, Configuration, Tracing and Monitoring libraries. Use provided wrappers or your own.
- [Jaeger wrapper](https://github.com/go-masonry/bjaeger) client for tracing.
- [Prometheus wrapper](https://github.com/go-masonry/bprometheus) client for monitoring/metrics.
- [Zerolog wrapper](https://github.com/go-masonry/bzerolog) for logging.
- [Viper wrapper](https://github.com/go-masonry/bviper) for configuration.
- Internal HTTP [Handlers](providers/handlers.go)
- _Profiling_ `http://.../debug/pprof`
- _Debug_ `http://.../debug/*`
- _Configuration_ `http://.../self/config`
- _Build Information_ `http://.../self/build`
- _Health_ `http://.../health`
- [Server/Client](providers) Interceptors both for gRPC and HTTP, you can choose which to use and/or add your own.
Some examples
- HTTP Headers can be forwarded to next hop, defined by list.
- HTTP Headers can be included in logs, defined by list.
- Made available in `ctx.Context` via gRPC incoming Metadata.
- Automatic monitoring and tracing (if enabled) for every RPC defined by the API....and more.
### Telemetry (Everything connected)
* Logs have Tracing Information `traceId=6ff7e7e38d1e86f` **across services**
* Also visible in Jaeger `traceId=6ff7e7e38d1e86f` if it's sampled.
### Support for `*http.Client` Interceptors, so you can
* Add request and response info to Trace
* Log/Dump requests and/or responses when http request fails.
```golang
return func(req *http.Request, handler client.HTTPHandler) (resp *http.Response, err error) {
var reqBytes, respBytes []byte
// If the response is Bad Request, log both Request and Response
reqBytes, _ = httputil.DumpRequestOut(req, true) // it can be nil and it's ok
if resp, err = handler(req); err == nil && resp.StatusCode >= http.StatusBadRequest {
respBytes, _ = httputil.DumpResponse(resp, true) // it can be nil
logger.WithError(fmt.Errorf("http request failed")).
WithField("status",resp.StatusCode).
Warn(req.Context(), "\nRequest:\n%s\n\nResponse:\n%s\n", reqBytes, respBytes)
}
return
}
```
* Alter requests and/or responses (useful in [Tests](https://github.com/go-masonry/mortar-demo/blob/master/workshop/app/controllers/workshop_test.go#L162))
```golang
func(*http.Request, clientInt.HTTPHandler) (*http.Response, error) {
// special case, don't go anywhere just return the response
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
ContentLength: 11,
Body: ioutil.NopCloser(strings.NewReader("car painted")),
}, nil
}
```### Monitoring/Metrics support
Export to either Prometheus/Datadog/statsd/etc, it's your choice. Mortar only provides the Interface and also **caches** the metrics so you don't have to.
```golang
counter := w.deps.Metrics.WithTags(monitor.Tags{
"color": request.GetDesiredColor(),
"success": fmt.Sprintf("%t", err == nil),
}).Counter("paint_desired_color", "New paint color for car")counter.Inc()
```> `counter` is actually a *singleton*, uniqueness calculated [here](monitoring/registry.go#L87)

For more information about Mortar Monitoring read [here](https://go-masonry.github.io/middleware/telemetry/monitoring/).
### Additional Features
* `/debug/pprof` and other useful [handlers](handlers)
* Use `config_test.yml` during [tests](https://github.com/go-masonry/mortar-demo/blob/master/workshop/app/controllers/workshop_test.go#L151) to **override** values in `config.yml`, it saves time.There are some features not listed here, please check the [Documentation](#documentation) for more.
## Documentation
Mortar is not a drop-in replacement.
It's important to read its [Documentation](https://go-masonry.github.io) first.