English/Japanese dictionary

write log also in a file

+66 -66
+4 -1
.gitignore
··· 15 15 result 16 16 17 17 # Annoying OSX files 18 - .DS_Store 18 + .DS_Store 19 + 20 + # Logging 21 + .logs
+2 -2
Justfile
··· 54 54 # Clean up local binaries 55 55 [group('maintenance')] 56 56 clean: 57 - @rm -rf bin/ 57 + @rm -rf bin/ .logs/ 58 58 59 59 # Clean up local binaries and data folder 60 60 [group('maintenance')] 61 61 clean-all: 62 - @rm -rf bin/ data/ 62 + @rm -rf bin/ .logs/ data/
+1 -1
cmd/main.go
··· 32 32 33 33 // Bleve connection 34 34 logger.Info("Connecting to Bleve Index...") 35 - bleveIndex, err := search.NewBleveSearchRepository(configValues.BleveIndexPath) 35 + bleveIndex, err := search.NewBleveSearchRepository(configValues.BleveIndexPath, configValues.BleveExplanationEnable, logger) 36 36 if err != nil { 37 37 log.Fatal(err) 38 38 }
+1
flake.nix
··· 74 74 MONGO_PORT = "27017"; 75 75 MONGO_DATABASE_PATH = "./data/mongodb"; 76 76 BLEVE_INDEX_PATH = "./data/bleve_index"; 77 + BLEVE_EXPLAIN_ENABLE = "true"; 77 78 DEVELOPMENT_TOKEN = "local-dev-token"; 78 79 CGO_ENABLED = "1"; 79 80 };
+1
go.mod
··· 6 6 github.com/blevesearch/bleve/v2 v2.5.7 7 7 github.com/golang-jwt/jwt/v5 v5.3.1 8 8 go.mongodb.org/mongo-driver v1.17.9 9 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 9 10 ) 10 11 11 12 require (
+2 -26
go.sum
··· 4 4 github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 5 5 github.com/blevesearch/bleve/v2 v2.5.7 h1:2d9YrL5zrX5EBBW++GOaEKjE+NPWeZGaX77IM26m1Z8= 6 6 github.com/blevesearch/bleve/v2 v2.5.7/go.mod h1:yj0NlS7ocGC4VOSAedqDDMktdh2935v2CSWOCDMHdSA= 7 - github.com/blevesearch/bleve_index_api v1.3.0 h1:DsMpWVjFNlBw9/6pyWf59XoqcAkhHj3H0UWiQsavb6E= 8 - github.com/blevesearch/bleve_index_api v1.3.0/go.mod h1:xvd48t5XMeeioWQ5/jZvgLrV98flT2rdvEJ3l/ki4Ko= 9 7 github.com/blevesearch/bleve_index_api v1.3.1 h1:LdH3CQgBbIZ5UI/5Pykz87e0jfeQtVnrdZ2WUBrHHwU= 10 8 github.com/blevesearch/bleve_index_api v1.3.1/go.mod h1:xvd48t5XMeeioWQ5/jZvgLrV98flT2rdvEJ3l/ki4Ko= 11 9 github.com/blevesearch/geo v0.2.4 h1:ECIGQhw+QALCZaDcogRTNSJYQXRtC8/m8IKiA706cqk= ··· 16 14 github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= 17 15 github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y= 18 16 github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk= 19 - github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= 20 - github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= 21 17 github.com/blevesearch/mmap-go v1.2.0 h1:l33nNKPFcBjJUMwem6sAYJPUzhUCABoK9FxZDGiFNBI= 22 18 github.com/blevesearch/mmap-go v1.2.0/go.mod h1:Vd6+20GBhEdwJnU1Xohgt88XCD/CTWcqbCNxkZpyBo0= 23 - github.com/blevesearch/scorch_segment_api/v2 v2.4.0 h1:OtipwURRzZv6UFmHQnbEqOY90eotINQ2TtSSpWfYuWU= 24 - github.com/blevesearch/scorch_segment_api/v2 v2.4.0/go.mod h1:JalWE/eyEgISwhqtKXoaHMKf5t+F4kXiYrgg0ds3ylw= 25 19 github.com/blevesearch/scorch_segment_api/v2 v2.4.1 h1:os52/JeCSLZ0YUkOuLk/Z7pu0SKUMofDPUg+VnbrRD0= 26 20 github.com/blevesearch/scorch_segment_api/v2 v2.4.1/go.mod h1:zvilBm4BNfbnTRLW7KgCTNgk2R31JaWzwRc2BEcD7Is= 27 21 github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= ··· 30 24 github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= 31 25 github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A= 32 26 github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ= 33 - github.com/blevesearch/vellum v1.1.0 h1:CinkGyIsgVlYf8Y2LUQHvdelgXr6PYuvoDIajq6yR9w= 34 - github.com/blevesearch/vellum v1.1.0/go.mod h1:QgwWryE8ThtNPxtgWJof5ndPfx0/YMBh+W2weHKPw8Y= 35 27 github.com/blevesearch/vellum v1.2.0 h1:xkDiOEsHc2t3Cp0NsNZZ36pvc130sCzcGKOPMzXe+e0= 36 28 github.com/blevesearch/vellum v1.2.0/go.mod h1:uEcfBJz7mAOf0Kvq6qoEKQQkLODBF46SINYNkZNae4k= 37 - github.com/blevesearch/zapx/v11 v11.4.2 h1:l46SV+b0gFN+Rw3wUI1YdMWdSAVhskYuvxlcgpQFljs= 38 - github.com/blevesearch/zapx/v11 v11.4.2/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc= 39 29 github.com/blevesearch/zapx/v11 v11.4.3 h1:PTZOO5loKpHC/x/GzmPZNa9cw7GZIQxd5qRjwij9tHY= 40 30 github.com/blevesearch/zapx/v11 v11.4.3/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc= 41 - github.com/blevesearch/zapx/v12 v12.4.2 h1:fzRbhllQmEMUuAQ7zBuMvKRlcPA5ESTgWlDEoB9uQNE= 42 - github.com/blevesearch/zapx/v12 v12.4.2/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58= 43 31 github.com/blevesearch/zapx/v12 v12.4.3 h1:eElXvAaAX4m04t//CGBQAtHNPA+Q6A1hHZVrN3LSFYo= 44 32 github.com/blevesearch/zapx/v12 v12.4.3/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58= 45 - github.com/blevesearch/zapx/v13 v13.4.2 h1:46PIZCO/ZuKZYgxI8Y7lOJqX3Irkc3N8W82QTK3MVks= 46 - github.com/blevesearch/zapx/v13 v13.4.2/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk= 47 33 github.com/blevesearch/zapx/v13 v13.4.3 h1:qsdhRhaSpVnqDFlRiH9vG5+KJ+dE7KAW9WyZz/KXAiE= 48 34 github.com/blevesearch/zapx/v13 v13.4.3/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk= 49 - github.com/blevesearch/zapx/v14 v14.4.2 h1:2SGHakVKd+TrtEqpfeq8X+So5PShQ5nW6GNxT7fWYz0= 50 - github.com/blevesearch/zapx/v14 v14.4.2/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8= 51 35 github.com/blevesearch/zapx/v14 v14.4.3 h1:GY4Hecx0C6UTmiNC2pKdeA2rOKiLR5/rwpU9WR51dgM= 52 36 github.com/blevesearch/zapx/v14 v14.4.3/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8= 53 - github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFxEsp31k= 54 - github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw= 55 37 github.com/blevesearch/zapx/v15 v15.4.3 h1:iJiMJOHrz216jyO6lS0m9RTCEkprUnzvqAI2lc/0/CU= 56 38 github.com/blevesearch/zapx/v15 v15.4.3/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw= 57 - github.com/blevesearch/zapx/v16 v16.3.0 h1:hF6VlN15E9CB40RMPyqOIhlDw1OOo9RItumhKMQktxw= 58 - github.com/blevesearch/zapx/v16 v16.3.0/go.mod h1:zCFjv7McXWm1C8rROL+3mUoD5WYe2RKsZP3ufqcYpLY= 59 39 github.com/blevesearch/zapx/v16 v16.3.1 h1:ERxZUSC9UcuKggCQ6b3y4sTkyL4WnGOWuopzglR874g= 60 40 github.com/blevesearch/zapx/v16 v16.3.1/go.mod h1:zCFjv7McXWm1C8rROL+3mUoD5WYe2RKsZP3ufqcYpLY= 61 41 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= ··· 72 52 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 73 53 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 74 54 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 75 - github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= 76 - github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= 77 55 github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= 78 56 github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= 79 57 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= ··· 102 80 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 103 81 go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= 104 82 go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= 105 - go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss= 106 - go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= 107 83 go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU= 108 84 go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ= 109 85 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= ··· 123 99 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 124 100 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 125 101 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 126 - golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= 127 - golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 128 102 golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= 129 103 golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 130 104 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= ··· 141 115 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 142 116 google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= 143 117 google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 118 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= 119 + gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= 144 120 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 145 121 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+19 -7
internal/adapters/config/environment.go
··· 4 4 "dictionary-api/internal/core/ports" 5 5 "fmt" 6 6 "os" 7 + "strconv" 7 8 ) 8 9 9 10 type EnvironmentRepository struct { ··· 13 14 func NewConfigRepository() ports.EnvironmentInterface { 14 15 return &EnvironmentRepository{ 15 16 values: ports.EnvironmentValues{ 16 - HostIp: getRequiredEnv("HOST_IP"), 17 - ServePort: getRequiredEnv("SERVE_PORT"), 18 - MongoPort: getRequiredEnv("MONGO_PORT"), 19 - BleveIndexPath: getRequiredEnv("BLEVE_INDEX_PATH"), 20 - DevelopmentToken: []byte(getRequiredEnv("DEVELOPMENT_TOKEN")), 21 - LogGroup: getEnvOrDefault("LOG_GROUP", "dictionary"), 22 - LogStream: getEnvOrDefault("LOG_STREAM", "default"), 17 + HostIp: getRequiredEnv("HOST_IP"), 18 + ServePort: getRequiredEnv("SERVE_PORT"), 19 + MongoPort: getRequiredEnv("MONGO_PORT"), 20 + BleveIndexPath: getRequiredEnv("BLEVE_INDEX_PATH"), 21 + BleveExplanationEnable: parseBoolean(getEnvOrDefault("BLEVE_EXPLAIN_ENABLE", "false")), 22 + DevelopmentToken: []byte(getRequiredEnv("DEVELOPMENT_TOKEN")), 23 + LogGroup: getEnvOrDefault("LOG_GROUP", "dictionary"), 24 + LogStream: getEnvOrDefault("LOG_STREAM", "default"), 23 25 }, 24 26 } 25 27 } ··· 48 50 49 51 return value 50 52 } 53 + 54 + func parseBoolean(boolStr string) bool { 55 + b, err := strconv.ParseBool(boolStr) 56 + if err != nil { 57 + message := fmt.Sprintf("Conversion error: %s", err.Error()) 58 + panic(message) 59 + } 60 + 61 + return b 62 + }
+28 -22
internal/adapters/secondary/logging/logger.go
··· 3 3 import ( 4 4 "dictionary-api/internal/core/ports" 5 5 "fmt" 6 + "io" 6 7 "log" 8 + "os" 9 + "time" 10 + 11 + "gopkg.in/natefinch/lumberjack.v2" 7 12 ) 8 13 9 14 type Logger struct { ··· 12 17 requestID string 13 18 fields map[string]interface{} 14 19 errorField string 20 + logger *log.Logger 15 21 } 16 22 17 23 func NewLogger(serviceName, environment string) ports.LoggerInterface { 24 + os.MkdirAll(".logs", 0755) 25 + 26 + fileLogger := &lumberjack.Logger{ 27 + Filename: ".logs/app.log", 28 + MaxSize: 10, // megabytes 29 + MaxBackups: 3, 30 + MaxAge: 28, // days 31 + Compress: false, // gzip compression 32 + } 33 + 34 + multiWriter := io.MultiWriter(os.Stdout, fileLogger) 35 + 36 + stdLogger := log.New(multiWriter, "", 0) 37 + 18 38 return &Logger{ 19 39 serviceName: serviceName, 20 40 environment: environment, 21 41 fields: make(map[string]any), 42 + logger: stdLogger, 22 43 } 23 44 } 24 45 ··· 39 60 } 40 61 41 62 func (c *Logger) log(level, message string, args ...any) { 42 - colorReset := "\033[0m" 43 - colorYellow := "\033[33m" 44 - colorRed := "\033[31m" 45 - colorGreen := "\033[32m" 46 - colorBlue := "\033[34m" 63 + plainLog := fmt.Sprintf( 64 + "[%s] (%s): %s", 65 + level, // [DEBUG] etc.. 66 + time.Now().Format(time.UnixDate), // Sun Feb 22 12:35:38 CET 2026 67 + fmt.Sprintf(message, args...), // Whatever logged 68 + ) 47 69 48 - var levelColor string 49 - switch level { 50 - case "DEBUG": 51 - levelColor = colorBlue 52 - case "INFO": 53 - levelColor = colorGreen 54 - case "WARN": 55 - levelColor = colorYellow 56 - case "ERROR": 57 - levelColor = colorRed 58 - default: 59 - levelColor = colorReset 60 - } 61 - 62 - formattedLog := fmt.Sprintf("%s[%s]%s: %s", levelColor, level, colorReset, fmt.Sprintf(message, args...)) 63 - 64 - log.Println(formattedLog) 70 + c.logger.Println(plainLog) 65 71 }
+8 -7
internal/core/ports/interfaces.go
··· 3 3 import "dictionary-api/internal/core/domain" 4 4 5 5 type EnvironmentValues struct { 6 - HostIp string 7 - ServePort string 8 - MongoPort string 9 - BleveIndexPath string 10 - DevelopmentToken []byte 11 - LogGroup string 12 - LogStream string 6 + HostIp string 7 + ServePort string 8 + MongoPort string 9 + BleveIndexPath string 10 + BleveExplanationEnable bool 11 + DevelopmentToken []byte 12 + LogGroup string 13 + LogStream string 13 14 } 14 15 15 16 type EnvironmentInterface interface {