Skeleton
parent
5ce6ca7fe1
commit
f7e1c2550b
6
Makefile
6
Makefile
|
@ -1,11 +1,11 @@
|
||||||
build:
|
build:
|
||||||
go build -o bin ./src/main.go
|
go build -o bin ./previewer/main.go
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -race ./src/...
|
go test -race ./previewer/...
|
||||||
|
|
||||||
lint: install-lint-deps
|
lint: install-lint-deps
|
||||||
golangci-lint run ./src/...
|
golangci-lint run ./previewer/...
|
||||||
|
|
||||||
install-lint-deps:
|
install-lint-deps:
|
||||||
(which golangci-lint > /dev/null) || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.31.0
|
(which golangci-lint > /dev/null) || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.31.0
|
||||||
|
|
11
go.mod
11
go.mod
|
@ -1,3 +1,10 @@
|
||||||
module main
|
module github.com/tiburon-777/OTUS_Project
|
||||||
|
|
||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/toml v0.3.1
|
||||||
|
github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/stretchr/testify v1.6.1
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||||
|
)
|
||||||
|
|
|
@ -1,11 +1,62 @@
|
||||||
package application
|
package application
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tiburon-777/OTUS_Project/previewer/config"
|
||||||
|
"github.com/tiburon-777/OTUS_Project/previewer/logger"
|
||||||
|
oslog "log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type App struct {
|
type App struct {
|
||||||
Server
|
*http.Server
|
||||||
Log logger.Interface
|
Log logger.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(logger logger.Interface) *App {
|
func New(conf config.Config) *App {
|
||||||
return &App{Log: logger}
|
loger, err := logger.New(conf.Log)
|
||||||
|
if err != nil {
|
||||||
|
oslog.Fatal("не удалось прикрутить логгер")
|
||||||
|
}
|
||||||
|
return &App{Server: &http.Server{Addr: net.JoinHostPort(conf.Server.Address, conf.Server.Port), Handler: LoggingMiddleware(Handler, loger)}, Log: loger}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(200)
|
||||||
|
_, _ = w.Write([]byte("Hello! I'm calendar app!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoggingMiddleware(next http.HandlerFunc, l logger.Interface) http.HandlerFunc {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
start := time.Now()
|
||||||
|
defer func() {
|
||||||
|
var path, useragent string
|
||||||
|
if r.URL != nil {
|
||||||
|
path = r.URL.Path
|
||||||
|
}
|
||||||
|
if len(r.UserAgent()) > 0 {
|
||||||
|
useragent = r.UserAgent()
|
||||||
|
}
|
||||||
|
latency := time.Since(start)
|
||||||
|
l.Infof("receive %s request from IP: %s on path: %s, duration: %s useragent: %s ", r.Method, r.RemoteAddr, path, latency, useragent)
|
||||||
|
}()
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *App) Start() error {
|
||||||
|
if err := s.ListenAndServe(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Log.Infof("Server starting")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *App) Stop() error {
|
||||||
|
if err := s.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Log.Infof("Server stoped")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
amitralog "github.com/amitrai48/logger"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
amitralog "github.com/amitrai48/logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Fields map[string]interface{}
|
||||||
|
|
||||||
type Interface interface {
|
type Interface interface {
|
||||||
Debugf(format string, args ...interface{})
|
Debugf(format string, args ...interface{})
|
||||||
Infof(format string, args ...interface{})
|
Infof(format string, args ...interface{})
|
||||||
|
@ -18,13 +19,15 @@ type Interface interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
Logger amitralog.Logger
|
amitralog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
File string
|
File string
|
||||||
Level string
|
Level string
|
||||||
MuteStdout bool
|
MuteStdout bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var validLevel = map[string]bool{"debug": true, "info": true, "warn": true, "error": true, "fatal": true}
|
var validLevel = map[string]bool{"debug": true, "info": true, "warn": true, "error": true, "fatal": true}
|
||||||
|
|
||||||
func New(conf Config) (Interface, error) {
|
func New(conf Config) (Interface, error) {
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"github.com/tiburon-777/OTUS_Project/previewer/application"
|
||||||
|
"github.com/tiburon-777/OTUS_Project/previewer/config"
|
||||||
oslog "log"
|
oslog "log"
|
||||||
"github/tiburon-777/OTUS_Project/previewer/application"
|
"os"
|
||||||
|
"os/signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ConfigFile = flag.String("config", "/etc/previewer.conf", "Path to configuration file")
|
var ConfigFile = flag.String("config", "/etc/previewer.conf", "Path to configuration file")
|
||||||
|
@ -14,6 +18,22 @@ func main() {
|
||||||
oslog.Fatal("не удалось открыть файл конфигурации:", err.Error())
|
oslog.Fatal("не удалось открыть файл конфигурации:", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
app := application.New(&conf)
|
app := application.New(conf)
|
||||||
app.Run()
|
|
||||||
|
go func() {
|
||||||
|
signals := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(signals)
|
||||||
|
|
||||||
|
<-signals
|
||||||
|
signal.Stop(signals)
|
||||||
|
|
||||||
|
if err := app.Stop(); err != nil {
|
||||||
|
app.Log.Errorf("failed to close application: " + err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := app.Start(); err != nil {
|
||||||
|
app.Log.Errorf("failed to start application: " + err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
package webserver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
*http.Server
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServer(address string, port string) http.Server {
|
|
||||||
return http.Server{Addr: net.JoinHostPort(address, port), Handler: LoggingMiddleware(Handler)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(200)
|
|
||||||
_, _ = w.Write([]byte("Hello! I'm calendar app!"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
start := time.Now()
|
|
||||||
defer func() {
|
|
||||||
var path, useragent string
|
|
||||||
if r.URL != nil {
|
|
||||||
path = r.URL.Path
|
|
||||||
}
|
|
||||||
if len(r.UserAgent()) > 0 {
|
|
||||||
useragent = r.UserAgent()
|
|
||||||
}
|
|
||||||
latency := time.Since(start)
|
|
||||||
a.Logger.Infof("receive %s request from IP: %s on path: %s, duration: %s useragent: %s ", r.Method, r.RemoteAddr, path, latency, useragent)
|
|
||||||
}()
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
|
||||||
if err := s.ListenAndServe(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.app.Logger.Infof("Server starting")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Stop() error {
|
|
||||||
if err := s.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.app.Logger.Infof("Server stoped")
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue