| 473 | } |
| 474 | |
| 475 | func setResourceLimits(logger *zap.Logger) func() { |
| 476 | // Configure the maximum number of CPUs to use to match the Linux container quota (if any) |
| 477 | // See https://pkg.go.dev/runtime#GOMAXPROCS |
| 478 | undo, err := maxprocs.Set(maxprocs.Logger(logger.Sugar().Infof)) |
| 479 | if err != nil { |
| 480 | logger.Warn("failed to set GOMAXPROCS", zap.Error(err)) |
| 481 | } |
| 482 | |
| 483 | // Configure the maximum memory to use to match the Linux container quota (if any) or system memory |
| 484 | // See https://pkg.go.dev/runtime/debug#SetMemoryLimit |
| 485 | _, _ = memlimit.SetGoMemLimitWithOpts( |
| 486 | memlimit.WithLogger( |
| 487 | slog.New(zapslog.NewHandler( |
| 488 | logger.Core(), |
| 489 | zapslog.WithName("memlimit"), |
| 490 | // the default enables traces at ERROR level, this disables |
| 491 | // them by setting it to a level higher than any other level |
| 492 | zapslog.AddStacktraceAt(slog.Level(127)), |
| 493 | )), |
| 494 | ), |
| 495 | memlimit.WithProvider( |
| 496 | memlimit.ApplyFallback( |
| 497 | memlimit.FromCgroup, |
| 498 | memlimit.FromSystem, |
| 499 | ), |
| 500 | ), |
| 501 | ) |
| 502 | |
| 503 | return undo |
| 504 | } |
| 505 | |
| 506 | // StringSlice is a flag.Value that enables repeated use of a string flag. |
| 507 | type StringSlice []string |