From 355c317eee3c677f10fe7bf5fdac1047245eda35 Mon Sep 17 00:00:00 2001 From: karn Date: Mon, 23 Dec 2024 06:02:45 +0530 Subject: [PATCH] fuck beego project in progress: uber/fx is pretty cool + setting up echo from labstack --- .mise/config.toml | 1 + cmds/api_server/main.go | 1 - cmds/ui_api/main.go | 28 +++++++++++++ conf/conf.go | 1 + config/config.go | 65 +++++++++++++++++++++++++++++ config/config.toml | 9 ++++ go.mod | 27 ++++++++++-- go.sum | 54 +++++++++++++++++++++--- libs/logger/logger.go | 43 +++++++++++++++++++ ui_api/run.go | 92 +++++++++++++++++++++++++++++++++++++++++ zarf/tests/tests.go | 4 +- 11 files changed, 313 insertions(+), 12 deletions(-) create mode 100644 cmds/ui_api/main.go create mode 100644 config/config.go create mode 100644 config/config.toml create mode 100644 libs/logger/logger.go create mode 100644 ui_api/run.go diff --git a/.mise/config.toml b/.mise/config.toml index 7019406..babcf10 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -3,6 +3,7 @@ experimental = true [env] ROOT = '{{env.HOME}}/code/karngyan/maek' +CONFIG_FILE = '{{env.HOME}}/code/karngyan/maek/config/config.toml' RUN_MODE = 'dev' SERVER_PORT = '8080' diff --git a/cmds/api_server/main.go b/cmds/api_server/main.go index 497566e..ad06d15 100644 --- a/cmds/api_server/main.go +++ b/cmds/api_server/main.go @@ -9,7 +9,6 @@ import ( "github.com/beego/beego/v2/core/logs" "github.com/beego/beego/v2/server/web" "github.com/beego/beego/v2/server/web/filter/cors" - "github.com/karngyan/maek/conf" "github.com/karngyan/maek/db" "github.com/karngyan/maek/domains" diff --git a/cmds/ui_api/main.go b/cmds/ui_api/main.go new file mode 100644 index 0000000..e45cb73 --- /dev/null +++ b/cmds/ui_api/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "github.com/karngyan/maek/config" + "github.com/karngyan/maek/libs/logger" + "github.com/karngyan/maek/ui_api" + "go.uber.org/fx" + "go.uber.org/fx/fxevent" + "go.uber.org/zap" +) + +func main() { + fx.New( + fx.Provide( + config.New, + logger.New, + ), + fx.Decorate(func(l *zap.Logger) *zap.Logger { + return l.With(zap.String("service", "ui_api")) + }), + fx.Invoke(ui_api.Run), + fx.WithLogger(func(l *zap.Logger) fxevent.Logger { + return &fxevent.ZapLogger{ + Logger: l, + } + }), + ).Run() +} diff --git a/conf/conf.go b/conf/conf.go index d0d038a..0c3a64a 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -5,6 +5,7 @@ import ( "time" "github.com/beego/beego/v2/server/web" + _ "github.com/karngyan/maek/config" "github.com/pkg/errors" ) diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..982481d --- /dev/null +++ b/config/config.go @@ -0,0 +1,65 @@ +package config + +import ( + "log" + "os" + "strings" + + "github.com/knadh/koanf/providers/env" + + "github.com/knadh/koanf/parsers/toml" + "github.com/knadh/koanf/providers/file" + "github.com/knadh/koanf/v2" +) + +type Config struct { + *koanf.Koanf +} + +func New() (*Config, error) { + k := koanf.New(".") + + configFile := os.Getenv("CONFIG_FILE") + if configFile == "" { + log.Fatal("CONFIG_FILE environment variable is not set") + } + + if _, err := os.Stat(configFile); os.IsNotExist(err) { + log.Fatalf("configuration file does not exist: %s", configFile) + } + + if err := k.Load(file.Provider(configFile), toml.Parser()); err != nil { + log.Fatalf("error loading configuration file (%s): %v", configFile, err) + } + + // e.g. export MAEK_API_SERVER__PORT=8081 + if err := k.Load(env.Provider("MAEK_", ".", func(s string) string { + return strings.ToLower(strings.ReplaceAll(strings.TrimPrefix(s, "MAEK_"), "__", ".")) + }), nil); err != nil { + log.Fatalf("error loading environment variables: %v", err) + } + + c := &Config{k} + + if c.IsDev() { + k.Print() + } + + return c, nil +} + +func (c *Config) IsDev() bool { + return c.String("environment") == "development" +} + +type ServiceMeta struct { + Name string +} + +func NewServiceMetaProvider(name string) func() *ServiceMeta { + return func() *ServiceMeta { + return &ServiceMeta{ + Name: name, + } + } +} diff --git a/config/config.toml b/config/config.toml new file mode 100644 index 0000000..36803a2 --- /dev/null +++ b/config/config.toml @@ -0,0 +1,9 @@ +environment = "development" + +[api_server] +port = 8080 +cors_allowed_origins = ["http://localhost:3000"] + +[database] +dsn = "postgres://maek:passwd@localhost:5432/maek_dev?sslmode=disable" +dsn_test = "postgres://maek:passwd@localhost:5433/maek_test?sslmode=disable" diff --git a/go.mod b/go.mod index b4468ff..81cfa30 100644 --- a/go.mod +++ b/go.mod @@ -6,35 +6,54 @@ require ( github.com/approvals/go-approval-tests v0.0.0-20241211183344-15d1ffb738a9 github.com/beego/beego/v2 v2.3.4 github.com/bluele/go-timecop v0.0.0-20201023003925-b95363da28d2 - github.com/brianvoe/gofakeit/v7 v7.1.2 github.com/deckarep/golang-set/v2 v2.7.0 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.7.1 + github.com/knadh/koanf/parsers/toml v0.1.0 + github.com/knadh/koanf/providers/env v1.0.0 + github.com/knadh/koanf/providers/file v1.1.2 + github.com/knadh/koanf/v2 v2.1.2 + github.com/labstack/echo/v4 v4.13.3 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.10.0 + go.uber.org/fx v1.23.0 + go.uber.org/zap v1.26.0 golang.org/x/crypto v0.31.0 + golang.org/x/sync v0.10.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/knadh/koanf/maps v0.1.1 // indirect + github.com/labstack/gommon v0.4.2 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.10.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.8.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 6b14f05..bffbf39 100644 --- a/go.sum +++ b/go.sum @@ -10,11 +10,8 @@ github.com/bits-and-blooms/bloom/v3 v3.5.0 h1:AKDvi1V3xJCmSR6QhcBfHbCN4Vf8FfxeWk github.com/bits-and-blooms/bloom/v3 v3.5.0/go.mod h1:Y8vrn7nk1tPIlmLtW2ZPV+W7StdVMor6bC1xgpjMZFs= github.com/bluele/go-timecop v0.0.0-20201023003925-b95363da28d2 h1:oNZvBuDygjhiDkgF3mcLa7rqzM0+ttKR1sZUtMwYIM8= github.com/bluele/go-timecop v0.0.0-20201023003925-b95363da28d2/go.mod h1:ruSXaf7e8z1f1Qp1zcVtPJl7OSaM1ERzxbXpg7jRy/8= -github.com/brianvoe/gofakeit/v7 v7.1.2 h1:vSKaVScNhWVpf1rlyEKSvO8zKZfuDtGqoIHT//iNNb8= -github.com/brianvoe/gofakeit/v7 v7.1.2/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -22,6 +19,10 @@ github.com/deckarep/golang-set/v2 v2.7.0 h1:gIloKvD7yH2oip4VLhsv3JyLLFnC0Y2mlusg github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw= github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -36,12 +37,37 @@ github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs= +github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= +github.com/knadh/koanf/parsers/toml v0.1.0 h1:S2hLqS4TgWZYj4/7mI5m1CQQcWurxUz6ODgOub/6LCI= +github.com/knadh/koanf/parsers/toml v0.1.0/go.mod h1:yUprhq6eo3GbyVXFFMdbfZSo928ksS+uo0FFqNMnO18= +github.com/knadh/koanf/providers/env v1.0.0 h1:ufePaI9BnWH+ajuxGGiJ8pdTG0uLEUWC7/HDDPGLah0= +github.com/knadh/koanf/providers/env v1.0.0/go.mod h1:mzFyRZueYhb37oPmC1HAv/oGEEuyvJDA98r3XAa8Gak= +github.com/knadh/koanf/providers/file v1.1.2 h1:aCC36YGOgV5lTtAFz2qkgtWdeQsgfxUkxDOe+2nQY3w= +github.com/knadh/koanf/providers/file v1.1.2/go.mod h1:/faSBcv2mxPVjFrXck95qeoyoZ5myJ6uxN8OOVNJJCI= +github.com/knadh/koanf/v2 v2.1.2 h1:I2rtLRqXRy1p01m/utEtpZSSA6dcJbgGVuE27kW2PzQ= +github.com/knadh/koanf/v2 v2.1.2/go.mod h1:Gphfaen0q1Fc1HTgJgSTC4oRX9R2R5ErYMZJy8fLJBo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= +github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 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= @@ -63,16 +89,34 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/libs/logger/logger.go b/libs/logger/logger.go new file mode 100644 index 0000000..3c6a3e3 --- /dev/null +++ b/libs/logger/logger.go @@ -0,0 +1,43 @@ +package logger + +import ( + "context" + "errors" + "syscall" + + "go.uber.org/fx" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/karngyan/maek/config" +) + +func New(lc fx.Lifecycle, c *config.Config) (*zap.Logger, error) { + cfg := zap.NewProductionConfig() + if c.IsDev() { + cfg = zap.NewDevelopmentConfig() + cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + } + + l, err := cfg.Build() + if err != nil { + return nil, err + } + + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + l.Info("syncing logger before shutdown") + err := l.Sync() + + // ignore ENOTTY errors when logs are written to a console + // https://github.com/uber-go/zap/issues/991#issuecomment-962098428 + if err != nil && !errors.Is(err, syscall.ENOTTY) { + return err + } + + return nil + }, + }) + + return l, nil +} diff --git a/ui_api/run.go b/ui_api/run.go new file mode 100644 index 0000000..5942d4e --- /dev/null +++ b/ui_api/run.go @@ -0,0 +1,92 @@ +package ui_api + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/karngyan/maek/config" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "go.uber.org/fx" + "go.uber.org/zap" +) + +func Run(lc fx.Lifecycle, c *config.Config, l *zap.Logger) error { + e := echo.New() + + e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ + LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error { + l.Info("request", + zap.String("URI", v.URI), + zap.Int("status", v.Status), + zap.Duration("latency", v.Latency), + zap.String("remote_ip", v.RemoteIP), + zap.String("method", v.Method), + zap.String("request_id", v.RequestID), + zap.String("ua", v.UserAgent), + zap.String("content_length", v.ContentLength), + zap.Int64("response_size", v.ResponseSize), + ) + return nil + }, + LogLatency: true, + LogRemoteIP: true, + LogMethod: true, + LogURI: true, + LogRequestID: true, // we set `X-Request-ID` in response + LogUserAgent: true, + LogStatus: true, + LogContentLength: true, + LogResponseSize: true, + })) + + e.Use(middleware.RecoverWithConfig(middleware.RecoverConfig{ + StackSize: 1 << 12, // 4 KB + LogErrorFunc: func(c echo.Context, err error, stack []byte) error { + l.Error("recovered from panic", zap.Error(err), zap.ByteString("stack", stack)) + return nil + }, + })) + + e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ + AllowOrigins: c.Strings("api_server.cors_allowed_origins"), + AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodOptions, http.MethodPatch}, + AllowHeaders: []string{"Content-Type", "Authorization", "Origin", "X-Request-ID"}, + AllowCredentials: true, + ExposeHeaders: []string{"Content-Length"}, + MaxAge: int((24 * time.Hour).Seconds()), + })) + + server := &http.Server{ + Addr: fmt.Sprintf("0.0.0.0:%s", c.String("api_server.port")), + Handler: e, + ReadTimeout: 15 * time.Second, + ReadHeaderTimeout: 5 * time.Second, + WriteTimeout: 15 * time.Second, + IdleTimeout: 60 * time.Second, + MaxHeaderBytes: 1 << 20, // 1 MB + } + + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + go func() { + l.Info("starting ui_api server", zap.String("addr", server.Addr)) + if err := e.StartServer(server); err != nil && errors.Is(err, http.ErrServerClosed) { + l.Error("error starting echo server", zap.Error(err)) + } + }() + return nil + }, + OnStop: func(ctx context.Context) error { + l.Info("shutdown signal received") + return e.Shutdown(ctx) + }, + }) + + l.Info("ui_api server started", zap.String("addr", server.Addr)) + + return nil +} diff --git a/zarf/tests/tests.go b/zarf/tests/tests.go index 035261c..c7bef5d 100644 --- a/zarf/tests/tests.go +++ b/zarf/tests/tests.go @@ -11,11 +11,11 @@ import ( "testing" "time" + "github.com/beego/beego/v2/core/logs" + "github.com/beego/beego/v2/server/web" "github.com/bluele/go-timecop" "github.com/stretchr/testify/assert" - "github.com/beego/beego/v2/core/logs" - "github.com/beego/beego/v2/server/web" "github.com/karngyan/maek/conf" "github.com/karngyan/maek/db" "github.com/karngyan/maek/domains"