Skeleton
This commit is contained in:
parent
74141880c7
commit
5ce6ca7fe1
38
go.sum
Normal file
38
go.sum
Normal file
@ -0,0 +1,38 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec h1:tDOPo9NAXCjvoK35HgZyzQSNLmb3chZqN2tnO273Bro=
|
||||
github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec/go.mod h1:RZEHP3cxXvQlMuMjkpdh6qXA4b0CpjxnUBNxOpR0r30=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
11
previewer.conf
Normal file
11
previewer.conf
Normal file
@ -0,0 +1,11 @@
|
||||
[Server]
|
||||
Address = "localhost"
|
||||
Port = "80"
|
||||
|
||||
[Cache]
|
||||
Capasity = 20
|
||||
|
||||
[Logger]
|
||||
File = "./previewer.log"
|
||||
Level = "INFO"
|
||||
MuteStdout = false
|
11
previewer/application/application.go
Normal file
11
previewer/application/application.go
Normal file
@ -0,0 +1,11 @@
|
||||
package application
|
||||
|
||||
|
||||
type App struct {
|
||||
Server
|
||||
Log logger.Interface
|
||||
}
|
||||
|
||||
func New(logger logger.Interface) *App {
|
||||
return &App{Log: logger}
|
||||
}
|
38
previewer/config/config.go
Normal file
38
previewer/config/config.go
Normal file
@ -0,0 +1,38 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Server struct {
|
||||
Address string
|
||||
Port string
|
||||
}
|
||||
Cache struct {
|
||||
Capasity string
|
||||
}
|
||||
Log struct {
|
||||
File string
|
||||
Level string
|
||||
MuteStdout bool
|
||||
}
|
||||
}
|
||||
|
||||
func NewConfig(configFile string) (Config, error) {
|
||||
f, err := os.Open(configFile)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
s, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
var config Config
|
||||
_, err = toml.Decode(string(s), &config)
|
||||
return config, err
|
||||
}
|
58
previewer/config/config_test.go
Normal file
58
previewer/config/config_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"io/ioutil"
|
||||
oslog "log"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var _ = func() bool {
|
||||
testing.Init()
|
||||
return true
|
||||
}()
|
||||
|
||||
func TestNewConfig(t *testing.T) {
|
||||
|
||||
badfile, err := ioutil.TempFile("", "conf.")
|
||||
if err != nil {
|
||||
oslog.Fatal(err)
|
||||
}
|
||||
defer os.Remove(badfile.Name())
|
||||
badfile.WriteString(`aefSD
|
||||
sadfg
|
||||
RFABND FYGUMG
|
||||
V`)
|
||||
badfile.Sync()
|
||||
|
||||
goodfile, err := ioutil.TempFile("", "conf.")
|
||||
if err != nil {
|
||||
oslog.Fatal(err)
|
||||
}
|
||||
defer os.Remove(goodfile.Name())
|
||||
goodfile.WriteString(`[Server]
|
||||
Address = "localhost"
|
||||
Port = "80"`)
|
||||
goodfile.Sync()
|
||||
|
||||
t.Run("No such file", func(t *testing.T) {
|
||||
c, e := NewConfig("adfergdth")
|
||||
require.Equal(t, Config{}, c)
|
||||
require.Error(t, e)
|
||||
})
|
||||
|
||||
t.Run("Bad file", func(t *testing.T) {
|
||||
c, e := NewConfig(badfile.Name())
|
||||
require.Equal(t, Config{}, c)
|
||||
require.Error(t, e)
|
||||
})
|
||||
|
||||
t.Run("TOML reading", func(t *testing.T) {
|
||||
c, e := NewConfig(goodfile.Name())
|
||||
require.Equal(t, "localhost", c.Server.Address)
|
||||
require.Equal(t, 80, c.Server.Port)
|
||||
require.NoError(t, e)
|
||||
})
|
||||
|
||||
}
|
71
previewer/logger/logger.go
Normal file
71
previewer/logger/logger.go
Normal file
@ -0,0 +1,71 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
amitralog "github.com/amitrai48/logger"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Debugf(format string, args ...interface{})
|
||||
Infof(format string, args ...interface{})
|
||||
Warnf(format string, args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
Logger amitralog.Logger
|
||||
}
|
||||
type Config struct {
|
||||
File string
|
||||
Level string
|
||||
MuteStdout bool
|
||||
}
|
||||
var validLevel = map[string]bool{"debug": true, "info": true, "warn": true, "error": true, "fatal": true}
|
||||
|
||||
func New(conf Config) (Interface, error) {
|
||||
if conf.File == "" || !validLevel[strings.ToLower(conf.Level)] {
|
||||
return nil, errors.New("invalid logger config")
|
||||
}
|
||||
|
||||
c := amitralog.Configuration{
|
||||
EnableConsole: !conf.MuteStdout,
|
||||
ConsoleLevel: amitralog.Fatal,
|
||||
ConsoleJSONFormat: false,
|
||||
EnableFile: true,
|
||||
FileLevel: strings.ToLower(conf.Level),
|
||||
FileJSONFormat: true,
|
||||
FileLocation: conf.File,
|
||||
}
|
||||
|
||||
if err := amitralog.NewLogger(c, amitralog.InstanceZapLogger); err != nil {
|
||||
log.Fatalf("Could not instantiate log %s", err.Error())
|
||||
}
|
||||
l := amitralog.WithFields(amitralog.Fields{"hw": "12"})
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (l *Logger) Debugf(format string, args ...interface{}) {
|
||||
l.Logger.Debugf(format, args)
|
||||
}
|
||||
|
||||
func (l *Logger) Infof(format string, args ...interface{}) {
|
||||
l.Logger.Infof(format, args)
|
||||
}
|
||||
|
||||
func (l *Logger) Warnf(format string, args ...interface{}) {
|
||||
l.Logger.Warnf(format, args)
|
||||
}
|
||||
|
||||
func (l *Logger) Errorf(format string, args ...interface{}) {
|
||||
l.Logger.Errorf(format, args)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalf(format string, args ...interface{}) {
|
||||
l.Logger.Fatalf(format, args)
|
||||
os.Exit(2)
|
||||
}
|
50
previewer/logger/logger_test.go
Normal file
50
previewer/logger/logger_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"io/ioutil"
|
||||
oslog "log"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoggerLogic(t *testing.T) {
|
||||
tmpfile, err := ioutil.TempFile("", "log.")
|
||||
if err != nil {
|
||||
oslog.Fatal(err)
|
||||
}
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
conf := Config{File: tmpfile.Name(), Level: "warn", MuteStdout: false}
|
||||
log, err := New(conf)
|
||||
if err != nil {
|
||||
oslog.Fatal(err)
|
||||
}
|
||||
|
||||
t.Run("Messages arround the level", func(t *testing.T) {
|
||||
log.Debugf("debug message")
|
||||
log.Errorf("error message")
|
||||
|
||||
res, err := ioutil.ReadAll(tmpfile)
|
||||
if err != nil {
|
||||
oslog.Fatal(err)
|
||||
}
|
||||
require.Less(t, strings.Index(string(res), "debug message"), 0)
|
||||
require.Greater(t, strings.Index(string(res), "error message"), 0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoggerNegative(t *testing.T) {
|
||||
t.Run("Bad file name", func(t *testing.T) {
|
||||
conf := Config{File: "", Level: "debug", MuteStdout: true}
|
||||
_, err := New(conf)
|
||||
require.Error(t, err, "invalid logger config")
|
||||
})
|
||||
|
||||
t.Run("Bad level", func(t *testing.T) {
|
||||
conf := Config{File: "asdafad", Level: "wegretryjt", MuteStdout: true}
|
||||
_, err := New(conf)
|
||||
require.Error(t, err, "invalid logger config")
|
||||
})
|
||||
}
|
19
previewer/main.go
Normal file
19
previewer/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
import (
|
||||
"flag"
|
||||
oslog "log"
|
||||
"github/tiburon-777/OTUS_Project/previewer/application"
|
||||
)
|
||||
|
||||
var ConfigFile = flag.String("config", "/etc/previewer.conf", "Path to configuration file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
conf, err := config.NewConfig(*ConfigFile)
|
||||
if err != nil {
|
||||
oslog.Fatal("не удалось открыть файл конфигурации:", err.Error())
|
||||
}
|
||||
|
||||
app := application.New(&conf)
|
||||
app.Run()
|
||||
}
|
5
previewer/models/models.go
Normal file
5
previewer/models/models.go
Normal file
@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
type Config struct {
|
||||
LruCapasity int
|
||||
}
|
54
previewer/webserver/webserver.go
Normal file
54
previewer/webserver/webserver.go
Normal file
@ -0,0 +1,54 @@
|
||||
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
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
func main() {
|
||||
log.Println("Начел кончел стоп медвед")
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user