Skip to content

Commit

Permalink
feat: use salt mux for server and update logging to support gcp
Browse files Browse the repository at this point in the history
  • Loading branch information
mabdh committed Sep 9, 2022
1 parent f8305bf commit f832899
Show file tree
Hide file tree
Showing 23 changed files with 346 additions and 206 deletions.
2 changes: 1 addition & 1 deletion cli/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func migrateCmd() *cobra.Command {
return err
}

logger := initLogger(cfg.Log.Level)
logger := initLogger(cfg.Log)
if err := runPostgresMigrations(logger, cfg); err != nil {
return err
}
Expand Down
2 changes: 2 additions & 0 deletions cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/spf13/cobra"
)

const serviceName = "siren"

// Execute runs the command line interface
func Execute() {
rootCmd := &cobra.Command{
Expand Down
50 changes: 39 additions & 11 deletions cli/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import (
"github.com/odpf/siren/core/rule"
"github.com/odpf/siren/core/subscription"
"github.com/odpf/siren/core/template"
"github.com/odpf/siren/internal/api"
"github.com/odpf/siren/internal/server"
"github.com/odpf/siren/internal/store/postgres"
"github.com/odpf/siren/pkg/cortex"
"github.com/odpf/siren/pkg/errors"
"github.com/odpf/siren/pkg/secret"
"github.com/odpf/siren/pkg/slack"
"github.com/odpf/siren/pkg/telemetry"
"github.com/odpf/siren/pkg/zapgcp"
"github.com/spf13/cobra"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
Expand Down Expand Up @@ -54,7 +56,7 @@ func runServer(cfg config.Config) error {
return err
}

logger := initLogger(cfg.Log.Level)
logger := initLogger(cfg.Log)

pgClient, err := postgres.NewClient(logger, cfg.DB)
if err != nil {
Expand Down Expand Up @@ -116,23 +118,49 @@ func runServer(cfg config.Config) error {
subscriptionRepository := postgres.NewSubscriptionRepository(pgClient)
subscriptionService := subscription.NewService(subscriptionRepository, providerService, namespaceService, receiverService, cortexClient)

apiDeps := &api.Deps{
TemplateService: templateService,
RuleService: ruleService,
AlertService: alertHistoryService,
ProviderService: providerService,
NamespaceService: namespaceService,
ReceiverService: receiverService,
SubscriptionService: subscriptionService,
}
return server.RunServer(
cfg.SirenService,
logger,
nr,
templateService,
ruleService,
alertHistoryService,
providerService,
namespaceService,
receiverService,
subscriptionService)
apiDeps,
)
}

func initLogger(logLevel string) log.Logger {
func initLogger(cfg config.Log) log.Logger {
defaultConfig := zap.NewProductionConfig()
defaultConfig.Level = zap.NewAtomicLevelAt(getZapLogLevelFromString(logLevel))
return log.NewZap(log.ZapWithConfig(defaultConfig, zap.AddCaller(), zap.AddStacktrace(zap.DPanicLevel)))
defaultConfig.Level = zap.NewAtomicLevelAt(getZapLogLevelFromString(cfg.Level))

if cfg.GCPCompatible {
defaultConfig = zap.Config{
Level: zap.NewAtomicLevelAt(getZapLogLevelFromString(cfg.Level)),
Encoding: "json",
Development: false,
Sampling: &zap.SamplingConfig{
Initial: 100,
Thereafter: 100,
},
EncoderConfig: zapgcp.EncoderConfig,
OutputPaths: []string{"stdout"},
ErrorOutputPaths: []string{"stderr"},
}
}

return log.NewZap(log.ZapWithConfig(
defaultConfig,
zap.Fields(zapgcp.ServiceContext(serviceName)),
zap.AddCaller(),
zap.AddStacktrace(zap.DPanicLevel),
))

}

// getZapLogLevelFromString helps to set logLevel from string
Expand Down
7 changes: 4 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ func LoadConfig(configFile string) (Config, error) {
return cfg, nil
}

type LogConfig struct {
Level string `mapstructure:"level" default:"info"`
type Log struct {
Level string `mapstructure:"level" default:"info"`
GCPCompatible bool `mapstructure:"gcp_compatible" default:"true"`
}

type SlackApp struct {
Expand All @@ -51,7 +52,7 @@ type Config struct {
Cortex cortex.Config `mapstructure:"cortex"`
NewRelic telemetry.NewRelicConfig `mapstructure:"newrelic"`
SirenService server.Config `mapstructure:"siren_service"`
Log LogConfig `mapstructure:"log"`
Log Log `mapstructure:"log"`
SlackApp SlackApp `mapstructure:"slack_app"`
EncryptionKey string `mapstructure:"encryption_key"`
}
81 changes: 81 additions & 0 deletions internal/api/api.go
Original file line number Diff line number Diff line change
@@ -1 +1,82 @@
package api

import (
"context"

"github.com/odpf/siren/core/alert"
"github.com/odpf/siren/core/namespace"
"github.com/odpf/siren/core/provider"
"github.com/odpf/siren/core/receiver"
"github.com/odpf/siren/core/rule"
"github.com/odpf/siren/core/subscription"
"github.com/odpf/siren/core/template"
)

//go:generate mockery --name=AlertService -r --case underscore --with-expecter --structname AlertService --filename alert_service.go --output=./mocks
type AlertService interface {
Create(context.Context, []*alert.Alert) ([]alert.Alert, error)
List(context.Context, alert.Filter) ([]alert.Alert, error)
}

//go:generate mockery --name=NamespaceService -r --case underscore --with-expecter --structname NamespaceService --filename namespace_service.go --output=./mocks
type NamespaceService interface {
List(context.Context) ([]namespace.Namespace, error)
Create(context.Context, *namespace.Namespace) error
Get(context.Context, uint64) (*namespace.Namespace, error)
Update(context.Context, *namespace.Namespace) error
Delete(context.Context, uint64) error
}

//go:generate mockery --name=ProviderService -r --case underscore --with-expecter --structname ProviderService --filename provider_service.go --output=./mocks
type ProviderService interface {
List(context.Context, provider.Filter) ([]provider.Provider, error)
Create(context.Context, *provider.Provider) error
Get(context.Context, uint64) (*provider.Provider, error)
Update(context.Context, *provider.Provider) error
Delete(context.Context, uint64) error
}

//go:generate mockery --name=ReceiverService -r --case underscore --with-expecter --structname ReceiverService --filename receiver_service.go --output=./mocks
type ReceiverService interface {
List(ctx context.Context, flt receiver.Filter) ([]receiver.Receiver, error)
Create(ctx context.Context, rcv *receiver.Receiver) error
Get(ctx context.Context, id uint64) (*receiver.Receiver, error)
Update(ctx context.Context, rcv *receiver.Receiver) error
Delete(ctx context.Context, id uint64) error
Notify(ctx context.Context, id uint64, payloadMessage receiver.NotificationMessage) error
GetSubscriptionConfig(subsConfs map[string]string, rcv *receiver.Receiver) (map[string]string, error)
}

//go:generate mockery --name=RuleService -r --case underscore --with-expecter --structname RuleService --filename rule_service.go --output=./mocks
type RuleService interface {
Upsert(context.Context, *rule.Rule) error
List(context.Context, rule.Filter) ([]rule.Rule, error)
}

//go:generate mockery --name=SubscriptionService -r --case underscore --with-expecter --structname SubscriptionService --filename subscription_service.go --output=./mocks
type SubscriptionService interface {
List(context.Context, subscription.Filter) ([]subscription.Subscription, error)
Create(context.Context, *subscription.Subscription) error
Get(context.Context, uint64) (*subscription.Subscription, error)
Update(context.Context, *subscription.Subscription) error
Delete(context.Context, uint64) error
}

//go:generate mockery --name=TemplateService -r --case underscore --with-expecter --structname TemplateService --filename template_service.go --output=./mocks
type TemplateService interface {
Upsert(context.Context, *template.Template) error
List(context.Context, template.Filter) ([]template.Template, error)
GetByName(context.Context, string) (*template.Template, error)
Delete(context.Context, string) error
Render(context.Context, string, map[string]string) (string, error)
}

type Deps struct {
TemplateService TemplateService
RuleService RuleService
AlertService AlertService
ProviderService ProviderService
NamespaceService NamespaceService
ReceiverService ReceiverService
SubscriptionService SubscriptionService
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)

//go:generate mockery --name=AlertService -r --case underscore --with-expecter --structname AlertService --filename alert_service.go --output=./mocks
type AlertService interface {
Create(context.Context, []*alert.Alert) ([]alert.Alert, error)
List(context.Context, alert.Filter) ([]alert.Alert, error)
}

func (s *GRPCServer) ListAlerts(ctx context.Context, req *sirenv1beta1.ListAlertsRequest) (*sirenv1beta1.ListAlertsResponse, error) {

alerts, err := s.alertService.List(ctx, alert.Filter{
ResourceName: req.GetResourceName(),
ProviderID: req.GetProviderId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/odpf/salt/log"
"github.com/odpf/siren/core/alert"
"github.com/odpf/siren/internal/api"
"github.com/odpf/siren/internal/api/v1beta1"
"github.com/odpf/siren/internal/api/v1beta1/mocks"
"github.com/odpf/siren/pkg/errors"
Expand All @@ -30,7 +31,7 @@ func TestGRPCServer_ListAlerts(t *testing.T) {
StartTime: 100,
EndTime: 200,
}).Return(dummyAlerts, nil).Once()
dummyGRPCServer := v1beta1.NewGRPCServer(nil, nil, nil, nil, mockedAlertService, nil, nil, nil, nil)
dummyGRPCServer := v1beta1.NewGRPCServer(nil, nil, &api.Deps{AlertService: mockedAlertService})

dummyReq := &sirenv1beta1.ListAlertsRequest{
ResourceName: "foo",
Expand All @@ -52,7 +53,7 @@ func TestGRPCServer_ListAlerts(t *testing.T) {

t.Run("should return error Internal if getting alert history failed", func(t *testing.T) {
mockedAlertService := &mocks.AlertService{}
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), nil, nil, mockedAlertService, nil, nil, nil, nil)
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), &api.Deps{AlertService: mockedAlertService})

mockedAlertService.EXPECT().List(mock.AnythingOfType("*context.emptyCtx"), alert.Filter{
ProviderID: 1,
Expand Down Expand Up @@ -120,7 +121,7 @@ func TestGRPCServer_CreateAlertHistory(t *testing.T) {
}}
mockedAlertService.EXPECT().Create(mock.AnythingOfType("*context.emptyCtx"), payload).
Return(dummyAlerts, nil).Once()
dummyGRPCServer := v1beta1.NewGRPCServer(nil, nil, nil, nil, mockedAlertService, nil, nil, nil, nil)
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), &api.Deps{AlertService: mockedAlertService})

res, err := dummyGRPCServer.CreateCortexAlerts(context.Background(), dummyReq)
assert.Equal(t, 1, len(res.GetAlerts()))
Expand Down Expand Up @@ -177,7 +178,7 @@ func TestGRPCServer_CreateAlertHistory(t *testing.T) {
}}
mockedAlertService.EXPECT().Create(mock.AnythingOfType("*context.emptyCtx"), payload).
Return(dummyAlerts, nil).Once()
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), nil, nil, mockedAlertService, nil, nil, nil, nil)
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), &api.Deps{AlertService: mockedAlertService})

res, err := dummyGRPCServer.CreateCortexAlerts(context.Background(), dummyReq)
assert.Equal(t, 1, len(res.GetAlerts()))
Expand All @@ -193,7 +194,7 @@ func TestGRPCServer_CreateAlertHistory(t *testing.T) {

t.Run("should return error Internal if getting alert history failed", func(t *testing.T) {
mockedAlertService := &mocks.AlertService{}
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), nil, nil, mockedAlertService, nil, nil, nil, nil)
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), &api.Deps{AlertService: mockedAlertService})

mockedAlertService.EXPECT().Create(mock.AnythingOfType("*context.emptyCtx"), payload).
Return(nil, errors.New("random error")).Once()
Expand Down Expand Up @@ -245,7 +246,7 @@ func TestGRPCServer_CreateAlertHistory(t *testing.T) {
Severity: "CRITICAL",
TriggeredAt: time.Now(),
}}
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), nil, nil, mockedAlertService, nil, nil, nil, nil)
dummyGRPCServer := v1beta1.NewGRPCServer(nil, log.NewNoop(), &api.Deps{AlertService: mockedAlertService})

mockedAlertService.EXPECT().Create(mock.AnythingOfType("*context.emptyCtx"), payload).
Return(dummyAlerts, nil).Once()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)

//go:generate mockery --name=NamespaceService -r --case underscore --with-expecter --structname NamespaceService --filename namespace_service.go --output=./mocks
type NamespaceService interface {
List(context.Context) ([]namespace.Namespace, error)
Create(context.Context, *namespace.Namespace) error
Get(context.Context, uint64) (*namespace.Namespace, error)
Update(context.Context, *namespace.Namespace) error
Delete(context.Context, uint64) error
}

func (s *GRPCServer) ListNamespaces(ctx context.Context, _ *sirenv1beta1.ListNamespacesRequest) (*sirenv1beta1.ListNamespacesResponse, error) {
namespaces, err := s.namespaceService.List(ctx)
if err != nil {
Expand Down
Loading

0 comments on commit f832899

Please sign in to comment.