Skip to content

Commit b91b8cd

Browse files
committed
feat: gRPC server
Start subcommand run gRPC server listenning at :50051. Also setup Slog logger with console and OpenTelemetry export handlers.
1 parent ae398cd commit b91b8cd

14 files changed

Lines changed: 337 additions & 46 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ go.work.sum
3232
.vscode/
3333

3434
# Build artifacts
35+
samarkand
3536
dist/
3637
build/
3738
bin/
39+
.task/

Taskfile.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ tasks:
2525
build:
2626
desc: Build the binary locally
2727
cmds:
28-
- go build -trimpath -ldflags="-s -w" -o {{.BINARY}} ./cmd/samarkand
28+
- go build -trimpath -ldflags="-s -w" -o {{.APP_NAME}} ./cmd/samarkand
2929

3030
mod:
3131
desc: Downloads and tidy Go modules

cmd/samarkand/samarkand.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ package main
33
import (
44
"context"
55
"fmt"
6-
"log"
76
"io"
7+
"log"
8+
"log/slog"
89
"os"
910

1011
"github.com/urfave/cli/v3"
12+
"go.opentelemetry.io/contrib/bridges/otelslog"
1113

1214
"github.com/coding-kelps/samarkand/internal/config"
13-
"github.com/coding-kelps/samarkand/internal/version"
15+
"github.com/coding-kelps/samarkand/internal/logger"
16+
"github.com/coding-kelps/samarkand/internal/server"
17+
"github.com/coding-kelps/samarkand/internal/metadata"
1418
)
1519

1620
func main() {
@@ -37,18 +41,37 @@ func newCommand(w io.Writer, loader func(string) (config.Config, error)) *cli.Co
3741
Action: func(ctx context.Context, cmd *cli.Command) error {
3842
cfg, err := loader(cmd.Root().String("config"))
3943
if err != nil {
40-
return fmt.Errorf("loading config: %w", err)
44+
slog.Error("failed to load configuration", "error", err)
45+
return err
4146
}
4247

43-
fmt.Fprintf(w, "Starting with config: %+v\n", cfg)
44-
return nil
48+
shutdown, err := logger.SetupOTelLogger(&cfg, ctx)
49+
if err != nil {
50+
slog.Error("failed to set up OTel logger", "error", err)
51+
return err
52+
}
53+
defer shutdown(ctx)
54+
55+
// 5. Build a multi-handler: OTel bridge + pretty console output.
56+
otelHandler := otelslog.NewHandler(metadata.GetName())
57+
consoleHandler := slog.NewTextHandler(w, &slog.HandlerOptions{
58+
Level: slog.LevelDebug,
59+
AddSource: true,
60+
})
61+
62+
logger := slog.New(logger.NewMultiHandler(otelHandler, consoleHandler))
63+
slog.SetDefault(logger)
64+
65+
s := server.New(&cfg, logger)
66+
67+
return s.Start()
4568
},
4669
},
4770
{
4871
Name: "version",
4972
Usage: "Get the version samarkand.",
5073
Action: func(context.Context, *cli.Command) error {
51-
fmt.Fprintln(w, version.GetVersionWithBuildInfo())
74+
fmt.Fprintln(w, metadata.GetVersionWithBuildInfo())
5275
return nil
5376
},
5477
},

cmd/samarkand/samarkand_test.go

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ import (
1010
"github.com/coding-kelps/samarkand/internal/config"
1111
)
1212

13-
func successLoader(path string) (config.Config, error) {
14-
return config.Default(), nil
15-
}
16-
1713
func failingLoader(path string) (config.Config, error) {
1814
return config.Config{}, errors.New("config file not found")
1915
}
@@ -35,28 +31,42 @@ func TestVersionCommand_PrintsOutput(t *testing.T) {
3531
}
3632
}
3733

38-
func TestStartCommand_LoadsDefaultConfig(t *testing.T) {
39-
out, err := run([]string{"samarkand", "start"}, successLoader)
40-
if err != nil {
41-
t.Fatalf("unexpected error: %v", err)
34+
// TestStartCommand_LoadsConfig verifies that the start command invokes the
35+
// config loader. A loader that immediately returns an error is used so that
36+
// execution stops after the loader call, before any OTel / server setup that
37+
// would fail in a unit-test environment.
38+
func TestStartCommand_LoadsConfig(t *testing.T) {
39+
called := false
40+
sentinelErr := errors.New("stop after load")
41+
42+
loader := func(_ string) (config.Config, error) {
43+
called = true
44+
return config.Config{}, sentinelErr
4245
}
43-
if !strings.Contains(out, "Starting with config:") {
44-
t.Errorf("unexpected output: %q", out)
46+
47+
_, err := run([]string{"samarkand", "start"}, loader)
48+
if !called {
49+
t.Fatal("expected config loader to be called, but it was not")
50+
}
51+
if !errors.Is(err, sentinelErr) {
52+
t.Errorf("expected sentinel error, got: %v", err)
4553
}
4654
}
4755

4856
func TestStartCommand_PassesConfigPathToLoader(t *testing.T) {
4957
wantPath := "/etc/samarkand/config.yaml"
5058
var gotPath string
5159

60+
// Return an error so the command halts after the loader call, before
61+
// any OTel / server code that would fail in a test environment.
5262
capturingLoader := func(path string) (config.Config, error) {
5363
gotPath = path
54-
return config.Default(), nil
64+
return config.Config{}, errors.New("stop after load")
5565
}
5666

5767
_, err := run([]string{"samarkand", "--config", wantPath, "start"}, capturingLoader)
58-
if err != nil {
59-
t.Fatalf("unexpected error: %v", err)
68+
if err == nil {
69+
t.Fatal("expected loader error to propagate, got nil")
6070
}
6171
if gotPath != wantPath {
6272
t.Errorf("loader received path %q, want %q", gotPath, wantPath)
@@ -66,14 +76,15 @@ func TestStartCommand_PassesConfigPathToLoader(t *testing.T) {
6676
func TestStartCommand_EmptyConfigPath_WhenFlagOmitted(t *testing.T) {
6777
var gotPath string
6878

79+
// Same strategy: bail out early via an error to avoid OTel / server setup.
6980
capturingLoader := func(path string) (config.Config, error) {
7081
gotPath = path
71-
return config.Default(), nil
82+
return config.Config{}, errors.New("stop after load")
7283
}
7384

7485
_, err := run([]string{"samarkand", "start"}, capturingLoader)
75-
if err != nil {
76-
t.Fatalf("unexpected error: %v", err)
86+
if err == nil {
87+
t.Fatal("expected loader error to propagate, got nil")
7788
}
7889
if gotPath != "" {
7990
t.Errorf("expected empty config path, got %q", gotPath)
@@ -85,14 +96,9 @@ func TestStartCommand_PropagatesLoaderError(t *testing.T) {
8596
if err == nil {
8697
t.Fatal("expected error from failing loader, got nil")
8798
}
88-
if !strings.Contains(err.Error(), "loading config") {
89-
t.Errorf("error should mention 'loading config', got: %v", err)
90-
}
91-
}
92-
93-
func TestUnknownSubcommand_ReturnsError(t *testing.T) {
94-
_, err := run([]string{"samarkand", "notacommand"}, nil)
95-
if err == nil {
96-
t.Fatal("expected error for unknown subcommand, got nil")
99+
// The start action returns the raw loader error, so check for the
100+
// message from failingLoader rather than any wrapper text.
101+
if !strings.Contains(err.Error(), "config file not found") {
102+
t.Errorf("expected error to contain 'config file not found', got: %v", err)
97103
}
98104
}

configs/default.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
---
22
server:
3-
grpc_addr: :50051
4-
http_addr: :80
3+
addr: :50051
54
shutdown_timeout: 30
65
log:
76
level: info

go.mod

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,38 @@ require (
99
github.com/knadh/koanf/providers/structs v1.0.0
1010
github.com/knadh/koanf/v2 v2.3.4
1111
github.com/urfave/cli/v3 v3.7.0
12+
go.opentelemetry.io/contrib/bridges/otelslog v0.17.0
13+
go.opentelemetry.io/otel v1.42.0
14+
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0
15+
go.opentelemetry.io/otel/log v0.18.0
16+
go.opentelemetry.io/otel/sdk v1.42.0
17+
go.opentelemetry.io/otel/sdk/log v0.18.0
18+
golang.org/x/sync v0.20.0
19+
google.golang.org/grpc v1.79.3
1220
)
1321

1422
require (
23+
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
24+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
1525
github.com/fatih/structs v1.1.0 // indirect
1626
github.com/fsnotify/fsnotify v1.9.0 // indirect
27+
github.com/go-logr/logr v1.4.3 // indirect
28+
github.com/go-logr/stdr v1.2.2 // indirect
1729
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
30+
github.com/google/uuid v1.6.0 // indirect
31+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
1832
github.com/knadh/koanf/maps v0.1.2 // indirect
1933
github.com/mitchellh/copystructure v1.2.0 // indirect
2034
github.com/mitchellh/reflectwalk v1.0.2 // indirect
35+
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
36+
go.opentelemetry.io/otel/metric v1.42.0 // indirect
37+
go.opentelemetry.io/otel/trace v1.42.0 // indirect
38+
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
2139
go.yaml.in/yaml/v3 v3.0.4 // indirect
22-
golang.org/x/sys v0.32.0 // indirect
40+
golang.org/x/net v0.52.0 // indirect
41+
golang.org/x/sys v0.42.0 // indirect
42+
golang.org/x/text v0.35.0 // indirect
43+
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
44+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
45+
google.golang.org/protobuf v1.36.11 // indirect
2346
)

go.sum

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
1+
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
2+
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
3+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
4+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
15
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
26
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
37
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
48
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
59
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
610
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
11+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
12+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
13+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
14+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
15+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
716
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
817
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
18+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
19+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
20+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
21+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
22+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
23+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
24+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
25+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
926
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
1027
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
1128
github.com/knadh/koanf/parsers/yaml v1.1.0 h1:3ltfm9ljprAHt4jxgeYLlFPmUaunuCgu1yILuTXRdM4=
@@ -18,8 +35,8 @@ github.com/knadh/koanf/providers/structs v1.0.0 h1:DznjB7NQykhqCar2LvNug3MuxEQsZ
1835
github.com/knadh/koanf/providers/structs v1.0.0/go.mod h1:kjo5TFtgpaZORlpoJqcbeLowM2cINodv8kX+oFAeQ1w=
1936
github.com/knadh/koanf/v2 v2.3.4 h1:fnynNSDlujWE+v83hAp8wKr/cdoxHLO0629SN+U8Urc=
2037
github.com/knadh/koanf/v2 v2.3.4/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28=
21-
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
22-
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
38+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
39+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
2340
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2441
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
2542
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
@@ -28,16 +45,58 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
2845
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
2946
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3047
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
48+
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
49+
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
3150
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
3251
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
3352
github.com/urfave/cli/v3 v3.7.0 h1:AGSnbUyjtLiM+WJUb4dzXKldl/gL+F8OwmRDtVr6g2U=
3453
github.com/urfave/cli/v3 v3.7.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
54+
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
55+
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
56+
go.opentelemetry.io/contrib/bridges/otelslog v0.17.0 h1:NFIS6x7wyObQ7cR84x7bt1sr8nYBx89s3x3GwRjw40k=
57+
go.opentelemetry.io/contrib/bridges/otelslog v0.17.0/go.mod h1:39SaByOyDMRMe872AE7uelMuQZidIw7LLFAnQi0FWTE=
58+
go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho=
59+
go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc=
60+
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY=
61+
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU=
62+
go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg=
63+
go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI=
64+
go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4=
65+
go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI=
66+
go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo=
67+
go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts=
68+
go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw=
69+
go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk=
70+
go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA=
71+
go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw=
72+
go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA=
73+
go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc=
74+
go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY=
75+
go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc=
76+
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
77+
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
3578
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
3679
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
37-
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
38-
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
80+
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
81+
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
82+
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
83+
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
84+
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
85+
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
86+
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
87+
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
88+
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
89+
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
90+
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
91+
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
92+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
93+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
94+
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
95+
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
96+
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
97+
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
3998
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
40-
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
41-
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
99+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
100+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
42101
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
43102
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/config/config.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ type Config struct {
88
}
99

1010
type ServerConfig struct {
11-
GRPCAddr string `koanf:"grpc_addr"`
12-
HTTPAddr string `koanf:"http_addr"`
11+
Addr string `koanf:"addr"`
1312
ShutdownTimeout time.Duration `koanf:"shutdown_timeout"`
1413
}
1514

@@ -20,8 +19,7 @@ type LogConfig struct {
2019
func Default() Config {
2120
return Config{
2221
Server: ServerConfig{
23-
GRPCAddr: ":50051",
24-
HTTPAddr: ":80",
22+
Addr: ":50051",
2523
ShutdownTimeout: 30 * time.Second,
2624
},
2725
Log: LogConfig{

0 commit comments

Comments
 (0)