Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #112 from im-kulikov/fix-issue-100
Browse files Browse the repository at this point in the history
Fix #100 drop pprof and metrics separated servers
  • Loading branch information
im-kulikov committed Jan 27, 2022
2 parents 1bb0c96 + cf74f02 commit bf77504
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 175 deletions.
75 changes: 50 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@

* [Why Helium](#why-helium)
* [About Helium and modules](#about-helium-and-modules)
* [Preconfigure](#defaults-and-preconfigure)
* [Group](#group-services)
* [Services](#service-module)
* [Logger](#logger-module)
* [NATS](#nats-module)
* [PostgreSQL](#postgresql-module)
* [Redis](#redis-module)
* [Settings](#settings-module)
* [Web](#web-module)
* [Examples of code](https://github.com/go-helium/demos)
+ [Defaults and preconfigure](#defaults-and-preconfigure)
* [Group (services)](#group--services-)
+ [Service module](#service-module)
+ [Logger module](#logger-module)
* [NATS Module](#nats-module)
* [PostgreSQL Module](#postgresql-module)
* [Redis Module](#redis-module)
* [Settings module](#settings-module)
* [Web Module](#web-module)
* [Project Examples](#project-examples)
* [Example](#example)
* [Supported Go versions](#supported-go-versions)
* [Contribute](#contribute)
* [Credits](#credits)
* [License](#license)

<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>

## Why Helium

When building a modern application or prototype proof of concept, the last thing you want to worry about is boilerplate code or pass dependencies.
Expand Down Expand Up @@ -509,8 +510,6 @@ Viper is a prioritized configuration registry. It maintains a set of configurati
## Web Module
- `ServersModule` puts into container [web.Service](https://github.com/im-kulikov/web/service.go):
- [pprof](https://pkg.go.dev/net/http/pprof) endpoint
- [metrics](https://pkg.go.dev/github.com/prometheus/client_golang) enpoint (by Prometheus)
- [gRPC](https://github.com/golang/protobuf) endpoint
- [Listener](https://github.com/im-kulikov/web/listener.go) allows provide custom web service and run it in scope.
- You can pass `pprof_handler` and/or `metric_handler`, that will be embedded into common handler,
Expand All @@ -532,32 +531,58 @@ Viper is a prioritized configuration registry. It maintains a set of configurati
Configuration:
```yaml
pprof:
ops:
address: :6060
shutdown_timeout: 10s

metrics:
address: :8090
shutdown_timeout: 10s
network: string
disable_metrics: bool
disable_pprof: bool
disable_healthy: bool
read_timeout: duration
read_header_timeout: duration
write_timeout: duration
idle_timeout: duration
max_header_bytes: int

api:
address: :8080
shutdown_timeout: 10s
network: string
disable_metrics: bool
disable_pprof: bool
disable_healthy: bool
read_timeout: duration
read_header_timeout: duration
write_timeout: duration
idle_timeout: duration
max_header_bytes: int
```
```dotenv
PPROF_ADDRESS=string
PPROF_SHUTDOWN_TIMEOUT=duration
METRICS_ADDRESS=string
METRICS_SHUTDOWN_TIMEOUT=duration
OPS_ADDRESS=string
OPS_NETWORK=string
OPS_DISABLE_METRICS=bool
OPS_DISABLE_PPROF=bool
OPS_DISABLE_HEALTHY=bool
OPS_READ_TIMEOUT=duration
OPS_READ_HEADER_TIMEOUT=duration
OPS_WRITE_TIMEOUT=duration
OPS_IDLE_TIMEOUT=duration
OPS_MAX_HEADER_BYTES=int

API_ADDRESS=string
API_NETWORK=string
API_DISABLE_METRICS=bool
API_DISABLE_PPROF=bool
API_DISABLE_HEALTHY=bool
API_READ_TIMEOUT=duration
API_READ_HEADER_TIMEOUT=duration
API_WRITE_TIMEOUT=duration
API_IDLE_TIMEOUT=duration
API_MAX_HEADER_BYTES=int
```
**Possible options for HTTP server**:
- `address` - (string) host and port
- `network` - (string) tcp, udp, etc
- `skip_errors` - allows ignore all errors
- `disabled` - (bool) to disable server
- `read_timeout` - (duration) is the maximum duration for reading the entire request, including the body
- `read_header_timeout` - (duration) is the amount of time allowed to read request headers
- `write_timeout` - (duration) is the maximum duration before timing out writes of the response
Expand Down
2 changes: 1 addition & 1 deletion web/grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestGRPCService(t *testing.T) {

(&gRPC{logger: log.Logger}).Stop(nil)
require.NoError(t, log.Decode())
require.EqualError(t, log, ErrEmptyGRPCServer.Error())
require.EqualError(t, log.Err(), ErrEmptyGRPCServer.Error())
})

t.Run("should fail on net.Listen", func(t *testing.T) {
Expand Down
14 changes: 11 additions & 3 deletions web/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,16 @@ func newTestLogger() *logger {
}
}

func (tl *logger) Error() string {
return tl.Result.E
func (tl *logger) Err() error {
if tl.Result == nil || tl.Result.E == "" {
return nil
}

return tl.Result
}

func (e testLogResult) Error() string {
return e.E
}

func (tl *logger) Cleanup() {
Expand Down Expand Up @@ -119,7 +127,7 @@ func TestHTTPService(t *testing.T) {

(&httpService{logger: log.Logger}).Stop(ctx)
require.NoError(t, log.Decode())
require.EqualError(t, log, ErrEmptyHTTPServer.Error())
require.EqualError(t, log.Err(), ErrEmptyHTTPServer.Error())
})

t.Run("should fail on net.Listen", func(t *testing.T) {
Expand Down
79 changes: 4 additions & 75 deletions web/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package web
import (
"net"
"net/http"
"net/http/pprof"

"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/viper"
"go.uber.org/dig"
"go.uber.org/zap"
Expand Down Expand Up @@ -46,24 +44,6 @@ type (
Server service.Service `group:"services"`
}

profileParams struct {
dig.In

Logger *zap.Logger
Viper *viper.Viper
Handler http.Handler `name:"pprof_handler" optional:"true"`
Listener net.Listener `name:"pprof_listener" optional:"true"`
}

metricParams struct {
dig.In

Logger *zap.Logger
Viper *viper.Viper
Handler http.Handler `name:"metric_handler" optional:"true"`
Listener net.Listener `name:"metric_listener" optional:"true"`
}

grpcParams struct {
dig.In

Expand All @@ -77,10 +57,8 @@ type (
)

const (
apiServer = "api"
gRPCServer = "grpc"
profileServer = "pprof"
metricsServer = "metric"
apiServer = "api"
gRPCServer = "grpc"

// ErrEmptyLogger is raised when empty logger passed into New function.
ErrEmptyLogger = internal.Error("empty logger")
Expand All @@ -91,68 +69,19 @@ var (
// nolint:gochecknoglobals
DefaultServersModule = module.Combine(
DefaultGRPCModule,
ProfilerModule,
MetricsModule,
OpsModule,
APIModule,
)

// APIModule defines API server module.
// nolint:gochecknoglobals
APIModule = module.New(NewAPIServer)

// ProfilerModule defines pprof server module.
// nolint:gochecknoglobals
ProfilerModule = module.New(newProfileServer)

// MetricsModule defines prometheus server module.
// nolint:gochecknoglobals
MetricsModule = module.New(newMetricServer)

// DefaultGRPCModule defines default gRPC server module.
// nolint:gochecknoglobals
DefaultGRPCModule = module.New(newDefaultGRPCServer)
)

func newProfileServer(p profileParams) (ServerResult, error) {
mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)

if p.Handler != nil {
mux.Handle("/", p.Handler)
}

return NewHTTPServer(HTTPParams{
Config: p.Viper,
Logger: p.Logger,
Name: profileServer,
Key: profileServer,
Handler: mux,
Listener: p.Listener,
})
}

func newMetricServer(p metricParams) (ServerResult, error) {
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())

if p.Handler != nil {
mux.Handle("/", p.Handler)
}

return NewHTTPServer(HTTPParams{
Config: p.Viper,
Logger: p.Logger,
Name: metricsServer,
Key: metricsServer,
Handler: mux,
Listener: p.Listener,
})
}

// NewAPIServer creates api server by http.Handler from DI container.
func NewAPIServer(p APIParams) (ServerResult, error) {
return NewHTTPServer(HTTPParams{
Expand Down Expand Up @@ -225,7 +154,7 @@ func newDefaultGRPCServer(p grpcParams) (ServerResult, error) {
return ServerResult{Server: serve}, err
}

// NewHTTPServer creates http-server that will be embedded into multi-server.
// NewHTTPServer creates http-server that will be embedded into multiple server.
func NewHTTPServer(p HTTPParams) (ServerResult, error) {
switch {
case p.Logger == nil:
Expand Down
Loading

0 comments on commit bf77504

Please sign in to comment.