From d69c31674b63cc9abdbaaa864dcab35fe94f7a6e Mon Sep 17 00:00:00 2001 From: Ryan Gonzalez Date: Thu, 8 Sep 2022 20:06:18 -0500 Subject: [PATCH] README updates --- README.md | 84 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 8eb277b..f2823c5 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![sr.ht project](https://img.shields.io/badge/sr.ht-alys-blue)](https://sr.ht/~refi64/alys) -Alys is a Crystal memory usage logger, tracking memory allocs, re-allocs, -and frees for later analysis. +Alys is a Crystal memory usage tracer, tracking memory allocs, re-allocs, and +frees for later analysis. **THIS IS ALPHA QUALITY SOFTWARE!** @@ -21,6 +21,8 @@ and frees for later analysis. ## Usage +### Setting Up Tracing + ```crystal require "alys" @@ -40,6 +42,8 @@ change the file's name, use: ALYS_TRACING=file:myfile.alys ./myapp ``` +### Examing Traces with `alys_converter` + The `.alys` file is in a custom binary format, but it can be converted into a JSON file or a Go pprof file via: @@ -47,19 +51,69 @@ JSON file or a Go pprof file via: # Outputs myfile.alys.json: bin/alys_converter myfile.alys # You can rename the output file: -crystal bin/alys_converter myfile.alys myfile.json +bin/alys_converter myfile.alys myfile.json # and/or format & indent the JSON file: -crystal bin/alys_converter --indent myfile.alys -crystal bin/alys_converter --indent myfile.alys myfile.json +bin/alys_converter --indent myfile.alys +bin/alys_converter --indent myfile.alys myfile.json # Outputs myfile.pb.gz (pprof format): -crystal bin/alys_converter -f pprof myfile.alys +bin/alys_converter -f pprof myfile.alys # You can rename the output file: -crystal bin/alys_converter -f pprof myfile.alys myfile.pb.gz +bin/alys_converter -f pprof myfile.alys myfile.pb.gz +``` + +(Note that .alys files are only compatible with an identical alys_converter +version!) + +#### JSON + +alys_converter's JSON format is simply an array of event objects like so: + +```json +{ + "id": 29, + "time": 1.009839517, + "kind": "alloc", + "addr": 281471443894272, + "size": 96, + "stack": [ + { + "ip": 4721576, + "line": 279, + "file": "/home/ryan/code/alys/src/alys.cr", + "name": "record_alloc" + }, + ... + ] +} ``` -In the pprof case, the file can then, of course, be visualized with -[pprof](https://github.com/google/pprof). Two sample indexes are available: +- `id` is a unique ID assigned to each allocation, with reallocation & free + calls using the same ID as the original allocation. In other words, you can + use this to link together allocation and free calls. +- `time` is the number of seconds since program start that this occurred. +- `kind` is one of `alloc`, `realloc`, or `free`. +- `addr` is the memory address that was allocated or freed. +- `size` is the number of bytes allocated. +- For `realloc` events, both of the above point to the *new* size and address, + and two additional keys store the previous values, `prev_addr` and + `prev_size`. +- `stack` is an array of stack frames, each containing (only `ip` is guaranteed + to be present): + - `ip` is the instruction pointer of this frame. + - `file` is the full filename + - `line` is the line number + - `name` is the function name + +You can see some (ugly) example usage of the JSON file for analysis at [this +Colab +notebook](https://colab.research.google.com/drive/1KdJLRIAno837bc5gNZUU_gLM3OmhD32F?usp=sharing)) + +#### pprof + +pprof files can be visualized with Google's +[pprof](https://github.com/google/pprof) CLI tool. Four sample indexes are +available (with similar meanings as to Go's): - `alloc_objects`: number of objects allocated over the course of the program - `alloc_space` (default): amount of bytes allocated over the course of the @@ -76,6 +130,8 @@ on `PORT`, use: pprof -http localhost:PORT myfile.pb.gz ``` +### Backtraces + By default, Alys will also capture a backtrace on each allocation or reallocation, which can result in significant slowdowns. You can control this via `ALYS_BACKTRACE_TYPE`: @@ -84,7 +140,7 @@ via `ALYS_BACKTRACE_TYPE`: - `ALYS_BACKTRACE_TYPE=addr` will create backtraces that only contain the function's memory addresses (i.e. no names, files, or line numbers). A backtrace like this, however, is not very useful, so `alys_converter` can - resolve them when converting to JSON via: + resolve them when running `alys_converter` via: ```bash bin/alys_converter --symbolize ./myapp myfile.alys ``` @@ -106,9 +162,6 @@ via `ALYS_BACKTRACE_TYPE`: - `ALYS_BACKTRACE_TYPE=full` (the default) will create backtraces that contain the function names, as well as the source file paths and line numbers. -TODO: document the JSON format, show examples of using it, -[ugly Colab notebook](https://colab.research.google.com/drive/1KdJLRIAno837bc5gNZUU_gLM3OmhD32F?usp=sharing) - TODO: add support for & document flipping Alys on / off at runtime ## Performance Notes @@ -364,7 +417,10 @@ TODO ## Contributing -TODO +Please see the [guide for submitting patches on +git.sr.ht](https://man.sr.ht/git.sr.ht/#sending-patches-upstream). (If you +choose to use `git send-email`, the patches should be sent to +[~refi64/alys-devel@lists.sr.ht](https://lists.sr.ht/~refi64/alys-devel).)ODO ## Contributors -- 2.45.2