diff --git a/api/event.go b/api/event.go index d9b8094e..1744ea05 100644 --- a/api/event.go +++ b/api/event.go @@ -47,7 +47,7 @@ func SetEventChannel(chan_envelopes <-chan platform.Envelope) { go func() { for envelope := range chan_envelopes { for conn, _ := range connectionsSSE { - if conn.organizationID == envelope.OrganizationID || conn.organizationID == 0 { + if conn.organizationID == envelope.OrganizationID || envelope.OrganizationID == 0 { log.Debug().Int("type", int(envelope.Event.Type)).Int32("env-org", envelope.OrganizationID).Msg("pushed event to client") conn.chanEvent <- envelope.Event } else if conn.userID == envelope.UserID { diff --git a/lob/cmd/address-list/main.go b/lob/cmd/address-list/main.go index 4b9d4749..0350f67f 100644 --- a/lob/cmd/address-list/main.go +++ b/lob/cmd/address-list/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "flag" "log" "os" @@ -9,6 +10,11 @@ import ( ) func main() { + company := flag.String("company", "", "Filter by addresses belonging to a particular company") + + flag.Parse() + log.Printf("%s", company) + key := os.Getenv("LOB_API_KEY") if key == "" { log.Println("LOB_API_KEY is empty") diff --git a/main.go b/main.go index 71dec99b..cb4b2ed9 100644 --- a/main.go +++ b/main.go @@ -54,8 +54,6 @@ func main() { log.Error().Err(err).Msg("Failed to start sentry connection") os.Exit(2) } - defer sentry.Flush(2 * time.Second) - sentryWriter, err := sentryzerolog.New(sentryzerolog.Config{ ClientOptions: sentry.ClientOptions{ Dsn: config.SentryDSN, @@ -80,6 +78,14 @@ func main() { log.Logger = log.Logger.Level(zerolog.InfoLevel) } + // Defer cleanup in reverse order - these will execute LAST (LIFO) + defer func() { + log.Info().Msg("Final cleanup") + os.Stderr.Sync() + sentryWriter.Close() + sentry.Flush(2 * time.Second) + }() + err = db.InitializeDatabase(context.TODO(), config.PGDSN) if err != nil { log.Error().Err(err).Msg("Failed to connect to database") @@ -147,6 +153,7 @@ func main() { if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Error().Str("err", err.Error()).Msg("HTTP Server Error") } + log.Debug().Msg("Exiting listen-and-serve goroutine") }() chan_envelope := make(chan platform.Envelope, 10) @@ -157,8 +164,11 @@ func main() { signalCh := make(chan os.Signal, 1) signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM) <-signalCh - log.Info().Msg("Received shutdown signal, shutting down...") + // Ensure logs are flushed + os.Stderr.Sync() + + platform.EventShutdown() shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second) defer shutdownCancel() @@ -171,6 +181,7 @@ func main() { platform.WaitForExit() log.Info().Msg("Shutdown complete") + os.Stderr.Sync() } func LoggerMiddleware(logger *zerolog.Logger) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { diff --git a/platform/arcgis.go b/platform/arcgis.go index 46570fe0..f8521877 100644 --- a/platform/arcgis.go +++ b/platform/arcgis.go @@ -628,7 +628,7 @@ func logPermissions(ctx context.Context, fssync *fieldseeker.FieldSeeker) { log.Info().Msg("This oauth token is not allowed to query for admin info") return } - log.Error().Err(err).Msg("Failed to get admin info log permissions") + log.Error().Err(err).Msg("Failed to get admin info during log permissions") return } permissions, err := fssync.PermissionList(ctx) diff --git a/platform/event.go b/platform/event.go index f7b84056..4a8ba68f 100644 --- a/platform/event.go +++ b/platform/event.go @@ -12,6 +12,9 @@ type Event = event.Event const EventTypeHeartbeat = event.EventTypeHeartbeat +func EventShutdown() { + event.Shutdown() +} func SetEventChannel(chan_events chan<- Envelope) { event.SetEventChannel(chan_events) } diff --git a/platform/event/event.go b/platform/event/event.go index 30dcc432..35963a26 100644 --- a/platform/event/event.go +++ b/platform/event/event.go @@ -41,6 +41,7 @@ const ( EventTypeCreated EventType = iota EventTypeDeleted EventTypeHeartbeat + EventTypeShutdown EventTypeSudo EventTypeUnknown EventTypeUpdated @@ -54,6 +55,8 @@ func (et EventType) String() string { return "deleted" case EventTypeHeartbeat: return "heartbeat" + case EventTypeShutdown: + return "shutdown" case EventTypeSudo: return "sudo" case EventTypeUnknown: @@ -71,6 +74,8 @@ func EventTypeFromString(s string) EventType { return EventTypeDeleted case "heartbeat": return EventTypeHeartbeat + case "shutdown": + return EventTypeShutdown case "sudo": return EventTypeSudo case "updated": @@ -108,6 +113,17 @@ func Created(t ResourceType, organization_id int32, uri_id string) { OrganizationID: organization_id, }) } +func Shutdown() { + go Send(Envelope{ + Event: Event{ + Resource: "system", + Time: time.Now(), + Type: EventTypeShutdown, + URI: config.MakeURLNidus("/"), + }, + OrganizationID: 0, + }) +} func Updated(t ResourceType, organization_id int32, uri_id string) { go Send(Envelope{ Event: Event{ diff --git a/start-nidus-sync.sh b/start-nidus-sync.sh index 71686319..602c41c6 100755 --- a/start-nidus-sync.sh +++ b/start-nidus-sync.sh @@ -11,7 +11,7 @@ # force production environment, but with debug logging export $(cat /var/run/secrets/nidus-dev-sync-env | xargs) && \ export $(cat .env | xargs) && \ - ./nidus-sync -prod 2>&1 | tee nidus-sync.log + ./nidus-sync -prod # # Use nix build output, force production environment #export $(cat /var/run/secrets/nidus-dev-sync-env | xargs) && ./result/bin/nidus-sync -prod 2>&1 | tee nidus-sync.log