feat: control API and Tor integration #1
@@ -110,6 +110,7 @@ Options:
|
||||
-v, --verbose Debug logging
|
||||
-q, --quiet Errors only
|
||||
--cprofile [FILE] Enable cProfile, dump to FILE (default: s5p.prof)
|
||||
--tracemalloc [N] Enable tracemalloc, show top N allocators on exit (default: 10)
|
||||
-V, --version Show version
|
||||
```
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ s5p -m 512 # max concurrent connections
|
||||
s5p --api 127.0.0.1:1081 # enable control API
|
||||
s5p --cprofile # profile to s5p.prof
|
||||
s5p --cprofile out.prof # profile to custom file
|
||||
s5p --tracemalloc # memory profile (top 10)
|
||||
s5p --tracemalloc 20 # memory profile (top 20)
|
||||
```
|
||||
|
||||
## Container
|
||||
|
||||
@@ -419,6 +419,15 @@ s5p --cprofile output.prof -c config/s5p.yaml
|
||||
|
||||
# Analyze after stopping
|
||||
python -m pstats s5p.prof
|
||||
|
||||
# Memory profiling with tracemalloc (top 10 allocators on exit)
|
||||
s5p --tracemalloc -c config/s5p.yaml
|
||||
|
||||
# Show top 20 allocators
|
||||
s5p --tracemalloc 20 -c config/s5p.yaml
|
||||
|
||||
# Both profilers simultaneously
|
||||
s5p --cprofile --tracemalloc -c config/s5p.yaml
|
||||
```
|
||||
|
||||
## Testing the Proxy
|
||||
|
||||
@@ -62,6 +62,10 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
||||
"--cprofile", metavar="FILE", nargs="?", const="s5p.prof",
|
||||
help="enable cProfile, dump stats to FILE (default: s5p.prof)",
|
||||
)
|
||||
p.add_argument(
|
||||
"--tracemalloc", metavar="N", nargs="?", const=10, type=int,
|
||||
help="enable tracemalloc, show top N allocators on exit (default: 10)",
|
||||
)
|
||||
return p.parse_args(argv)
|
||||
|
||||
|
||||
@@ -112,6 +116,11 @@ def main(argv: list[str] | None = None) -> int:
|
||||
config.log_level = "error"
|
||||
|
||||
_setup_logging(config.log_level)
|
||||
logger = logging.getLogger("s5p")
|
||||
|
||||
if args.tracemalloc:
|
||||
import tracemalloc
|
||||
tracemalloc.start()
|
||||
|
||||
try:
|
||||
if args.cprofile:
|
||||
@@ -123,13 +132,21 @@ def main(argv: list[str] | None = None) -> int:
|
||||
finally:
|
||||
prof.disable()
|
||||
prof.dump_stats(args.cprofile)
|
||||
logging.getLogger("s5p").info("profile saved to %s", args.cprofile)
|
||||
logger.info("profile saved to %s", args.cprofile)
|
||||
else:
|
||||
asyncio.run(serve(config))
|
||||
except KeyboardInterrupt:
|
||||
return 0
|
||||
except Exception as e:
|
||||
logging.getLogger("s5p").error("%s", e)
|
||||
logger.error("%s", e)
|
||||
return 1
|
||||
finally:
|
||||
if args.tracemalloc:
|
||||
import tracemalloc
|
||||
snapshot = tracemalloc.take_snapshot()
|
||||
stats = snapshot.statistics("lineno")
|
||||
logger.info("tracemalloc: top %d allocations", args.tracemalloc)
|
||||
for stat in stats[:args.tracemalloc]:
|
||||
logger.info(" %s", stat)
|
||||
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user