Question: How to: Third-party integrations

Answer:
* [FreeBSD Port](https://www.freshports.org/security/maltrail)
* [OPNSense Gateway Plugin](https://github.com/opnsense/plugins/pull/1257)
* [D4 Project](https://www.d4-project.org/2019/09/25/maltrail-integration.html)
* [BlackArch Linux](https://github.com/BlackArch/blackarch/blob/master/packages/maltrail/PKGBUILD)
* [Validin LLC](https://x.com/ValidinLLC/status/1719666086390517762)
* [Maltrail Add-on for Splunk](https://splunkbase.splunk.com/app/7211)
* [Maltrail decoder and rules for Wazuh](https://github.com/MikhailKasimov/maltrail-wazuh-decoder-and-rules)
* [GScan](https://github.com/grayddq/GScan)
1
* [MalwareWorld](https://www.malwareworld.com/)
1
* [oisd | domain blocklist](https://oisd.nl/?p=inc)
1
* [NextDNS](https://github.com/nextdns/metadata/blob/e0c9c7e908f5d10823b517ad230df214a7251b13/security/threat-intelligence-feeds.json)
1
* [NoTracking](https://github.com/notracking/hosts-blocklists/blob/master/SOURCES.md)
1
* [OWASP Mobile Audit](https://github.com/mpast/mobileAudit#environment-variables)
1
* [Mobile-Security-Framework-MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF/commit/12b07370674238fa4281fc7989b34decc2e08876)
1
* [pfBlockerNG-devel](https://github.com/pfsense/FreeBSD-ports/blob/devel/net/pfSense-pkg-pfBlockerNG-devel/files/usr/local/www/pfblockerng/pfblockerng_feeds.json)
1
* [Sansec eComscan](https://sansec.io/kb/about-ecomscan/ecomscan-license)
1
* [Palo Alto Networks Cortex XSOAR](https://xsoar.pan.dev/docs/reference/integrations/github-maltrail-feed)
2
1
Using (only) trails
2
Connector to trails (only)


Question: How to: sudo docker rm xbme

Answer:
....

Then proceed normally in the guest: install packages, and build:

....
apt-get update && \
apt-get install -y git && \
git clone https://github.com/cirosantilli/x86-bare-metal-examples && \
cd x86-bare-metal-examples && \
./configure -y && \
make
....

To overcome the lack of GUI, we can use QEMU's VNC implementation instead of the default SDL, which is visible on the host due to `--net=host`:

....
./run bios_hello_world run -vnc :0
....

and then on host:

....
sudo apt-get install vinagre
vinagre localhost:5900
....

TODO: get sound working from docker: <
>: https://stackoverflow.com/questions/41083436/how-to-play-sound-in-a-docker-container

It should also be possible to run a GUI inside the container, but I haven't tested: https://stackoverflow.com/questions/40658095/how-to-open-ubuntu-gui-inside-a-docker-image/57636624#57636624

=== GDB step debug

To GDB step debug the program, run it with:

....
./run bios_hello_world debug
....

This will leave you at the very first instruction executed by our program, which is the beginning of our `BEGIN` macro.

Note however that this is not the very first instruction QEMU executes: that will actually be BIOS setup code that runs before our program itself.

You can then basically debug as you would a normal userland program, notably:

* I then highly recommend that you use https://github.com/cyrus-and/gdb-dashboard[GDB Dashboard] to see what is going on.
* `n` skips over macros
* `ni` steps within macros. But you will need to enable the printing of assembly code on GDB Dashboard to see where you are at

With this God-like GDB Dashboard setup, at 89cbe7be83f164927caebc9334bc42990e499cb1 I see a perfect program view such as:

....
 1 /* https://github.com/cirosantilli/x86-bare-metal-examples#bios-hello-world */
 2
 3 #include "common.h"
 4 BEGIN
 5     mov $msg, %si
 6     mov $0x0e, %ah
 7 loop:
 8     lodsb
 9     or %al, %al
10     jz halt
11     int $0x10
12     jmp loop
─── Assembly ────────────────────────────────────────────────────────────────────────────
0x00007c00 __start+0  cli
0x00007c01 __start+1  ljmp   $0xc031,$0x7c06
0x00007c08 __start+8  mov    %eax,%ds
0x00007c0a __start+10 mov    %eax,%es
0x00007c0c __start+12 mov    %eax,%fs
0x00007c0e __start+14 mov    %eax,%gs
0x00007c10 __start+16 mov    %eax,%ebp
0x00007c12 __start+18 mov    %eax,%ss
0x00007c14 __start+20 mov    %ebp,%esp
─── Registers ───────────────────────────────────────────────────────────────────────────
   eax 0x0000aa55    ecx 0x00000000    edx 0x00000080    ebx 0x00000000    esp 0x00006f04
   ebp 0x00000000    esi 0x00000000    edi 0x00000000    eip 0x00007c00 eflags [ IF ]
    cs 0x00000000     ss 0x00000000     ds 0x00000000     es 0x00000000     fs 0x00000000
    gs 0x00000000
─── Stack ───────────────────────────────────────────────────────────────────────────────
[0] from 0x00007c00 in __start+0 at bios_hello_world.S:4
(no arguments)
─────────────────────────────────────────────────────────────────────────────────────────
>>>
....

Debug symbols are obtained by first linking ELF files, and then using `objcopy` on them to generate the final image. We then pass the ELF files with the debug information to GDB:  https://stackoverflow.com/questions/32955887/how-to-disassemble-16-bit-x86-boot-sector-code-in-gdb-with-x-i-pc-it-gets-tr/32960272#32960272

How to step over `int` calls: http://stackoverflow.com/questions/24491516/how-to-step-over-interrupt-calls-when-debugging-a-bootloader-bios-with-gdb-and-q

Single stepping until a given opcode can be helpful sometimes: https://stackoverflow.com/questions/14031930/break-on-instruction-with-specific-opcode-in-gdb/31249378#31249378

TODO: detect if we are on 16 or 32 bit automatically from control registers. Now I'm using 2 functions `16` and `32` to switch manually, but that sucks. The problem is that it's not possible to read them directly: http://stackoverflow.com/a/31340294/895245 If we had `cr0`, it would be easy to do with an `if cr0 & 1` inside a hook-stop.

TODO: Take segmentation offsets into account: http://stackoverflow.com/questions/10354063/how-to-use-a-logical-address-in-gdb

=== Build the documentation locally

....
make doc
xdg-open README.html
....

== Minimal examples

These are the first ones you should look at.

[[printf]]
=== Create a minimal image with printf

....
make -C printf run
....

Outcome: QEMU window opens up, prints a few boot messages, and hangs.

Our program itself does not print anything to the screen itself, just makes the CPU halt.

This example is generated with `printf` byte by byte: you can't get more minimal than this!

It basically consists of:

* byte 0: a `hlt` instruction
* bytes 1 through 509: zeroes, could be anything
* bytes 510 and 511: mandatory magic bytes `0xAA55`, which are required for BIOS to consider our disk.

=== Minimal GAS example

Minimal example that just halts the CPU without using our mini-library link:common.h[]:

....
./run min
....

Source: link:min.S


Question: How to: [⏫](#contents) Continuous Tests Monitoring with [codecov.io](https://app.codecov.io)

Answer:
Track tests duration, errors, flackiness. Run JUnit test output converter and submit result to codecov.io via GitHub Action. — https://codecov.io

```
go test -coverprofile=coverage.out -cover -json ./... | gotestsum --junitfile tests.xml
```
Requirements
```
go install gotest.tools/gotestsum@latest
```


Question: How to: [⏫](#contents) Make treemap of coverage with [go-cover-treemap](https://github.com/nikolaydubina/go-cover-treemap)

Answer:
Visualize distribution of code coverage in your project. This helps to identify code areas with high and low coverage. Useful when you have large project with lots of files and packages. This 2D "image-hash" of your project should be more representative than a single number. Also available at https://go-cover-treemap.io. — [@nikolaydubina](https://github.com/nikolaydubina)

```
go test -coverprofile cover.out ./...
go-cover-treemap -coverprofile cover.out > out.svg
```
Requirements
```
go install github.com/nikolaydubina/go-cover-treemap@latest
```


Question: How to: [⏫](#contents) Browse coverage

Answer:
This is very helpful tool from the official Go toolchain. Similar visualization is integrated into VSCode and Goland, but can be used separately.

```
go test -coverprofile cover.out ./...
go tool cover -html=cover.out
```


Question: How to: [⏫](#contents) Browse coverage with [gocov-html](https://github.com/matm/gocov-html)

Answer:
Browse code coverage in statically generated HTML page. Multiple styles are supported. You may need to convert coverage report into `gocov` format. — [@matm](https://github.com/matm)

```
gocov test strings | gocov-html -t golang > strings.html
gocov test encoding/csv strings | gocov-html -t kit > strings.html
gocov test strings|./gocov-html -cmax 90 > strings.html # show functions with <90% coverage
```
Requirements
```
go install github.com/axw/gocov/gocov@latest
go install github.com/matm/gocov-html/cmd/gocov-html@latest
```


Question: How to: [⏫](#contents) Browse coverage with [xgo](https://github.com/xhd2015/xgo)

Answer:
The displayed coverage is a combination of coverage and git diff. By default, only modified lines were shown. This helps to quickly locate changes that were not covered, and add tests for them incrementally. — [@xhd2015](https://github.com/xhd2015)

```
xgo tool coverage serve cover.out
```
Requirements
```
go install github.com/xhd2015/xgo/cmd/xgo@latest
```


Question: How to: [⏫](#contents) Browse coverage in terminal with [gocovsh](https://github.com/orlangure/gocovsh)

Answer:
Browse code coverage similarly to HTML provided by official Go toolchain, but in terminal. Other notable features are package level statistics, coverage only for changed files. — [@orlangure](https://github.com/orlangure)

```
go test -cover -coverprofile coverage.out
gocovsh                        # show all files from coverage report
git diff --name-only | gocovsh # only show changed files
git diff | gocovsh             # show coverage on top of current diff
gocovsh --profile profile.out  # for other coverage profile names
```
Requirements
```
go install github.com/orlangure/gocovsh@latest
```


Question: How to: [⏫](#contents) Pretty print coverage in terminal with [nikandfor/cover](https://github.com/nikandfor/cover)

Answer:
It is similar to `go tool cover -html=cover.out` but in terminal. You can filter by functions, packages, minimum coverage, and more. — [@nikandfor](https://github.com/nikandfor)

```
cover
```
Requirements
```
go install github.com/nikandfor/cover@latest
```


Question: How to: [⏫](#contents) Run coverage collector server with [goc](https://github.com/qiniu/goc)

Answer:
This tool allows to collect coverage as soon as code is executed. — [@qiniu](https://github.com/qiniu)

```
goc server
goc build
goc profile
```
Requirements
```
go install github.com/qiniu/goc@latest
```


Question: How to: [⏫](#contents) Visualize live coverage in VSCode with [goc](https://github.com/qiniu/goc)

Answer:
Official Go VSCode plugin already has coverage highlighting. In addition to that, this tool shows covered lines as soon as they are executed. This can be useful for running manual integration or system tests or debugging. — [@qiniu](https://github.com/qiniu)
Requirements
```
go install github.com/qiniu/goc@latest
```


Question: How to: [⏫](#contents) Detect drops in coverage with [go-test-coverage](https://github.com/vladopajic/go-test-coverage)

Answer:
This tool designed to report issues when test coverage falls below a specified threshold. Likely you would want to use it in the CI. — [@vladopajic](https://github.com/vladopajic)

```
go-test-coverage --config=./.testcoverage.yml
```

Requirements
```
go install github.com/vladopajic/go-test-coverage/v2@latest
```


Question: How to: [⏫](#contents) :gift: Comment code coverage reports in pull request with [go-coverage-report](https://github.com/fgrosse/go-coverage-report)

Answer: A CLI tool and GitHub Action to post Go code coverage reports as comment to your pull requests. — [@fgrosse](https://github.com/fgrosse)


Question: How to: [⏫](#contents) :gift: Differential coverage

Answer: This is a useful basic technique that should be more widely known (just like bisect). Read more in the blog post. — [@rsc](https://github.com/rsc)


Question: How to: [⏫](#contents) :gift: Manipulate coverage profiles with [gopherage](https://github.com/kubernetes/test-infra/blob/master/gopherage)

Answer:
Kubernetes test-infra contains couple useful granular tools to manipulate coverage profiles. — [@kubernetes](https://github.com/kubernetes)

```
aggregate [files...]
diff [first] [second]
filter [file]
html [coverage]
junit [profile]
merge [files...]
metadata [...fields]
```

Requirements
```
go install k8s.io/test-infra/gopherage/cmd/aggregate@latest
go install k8s.io/test-infra/gopherage/cmd/diff@latest
go install k8s.io/test-infra/gopherage/cmd/filter@latest
go install k8s.io/test-infra/gopherage/cmd/html@latest
go install k8s.io/test-infra/gopherage/cmd/junit@latest
go install k8s.io/test-infra/gopherage/cmd/metadata@latest
go install k8s.io/test-infra/gopherage/cmd/merge@latest
```


Question: How to: [⏫](#contents) Shuffle tests

Answer:
This is less known option that is disabled by default. However, for robust test suite it is beneficial. More test flags and full description is available at `go help testflag`.

```
go test -shuffle=on
```


Question: How to: [⏫](#contents) Run tests sequentially

Answer:
Use when you need to synchronize tests, for example in integration tests that share environment. [Official documentation](https://pkg.go.dev/cmd/go#hdr-Testing_flags).

```
go test -p 1 -parallel 1 ./...
```


Question: How to: [⏫](#contents) Run tests in parallel

Answer:
Add `t.Parallel` to your tests case function bodies. As per documentation, by default `-p=GOMAXPROCS` and `-parallel=GOMAXPROCS` when you run `go test`. Different packages by default run in parallel, and tests within package can be enforced to run in parallel too. Make sure to copy test case data to new variable, why explained [here](https://gist.github.com/posener/92a55c4cd441fc5e5e85f27bca008721). [Official documentation](https://pkg.go.dev/cmd/go#hdr-Testing_flags).

```go
...
for _, tc := range tests {
    tc := tc
    t.Run(tc.name, func(t *testing.T) {
        t.Parallel()
        ...
```


Question: How to: [⏫](#contents) Run all Fuzz tests

Answer:
Standard tool runs only single fuzz test. Use following to run all fuzz tests in a package.

```
go test -list . | grep Fuzz | xargs -P 8 -I {} go test -fuzz {} -fuzztime 5s .
```


Question: How to: [⏫](#contents) :gift: Fuzz Go binaries using LibAFL with [GoLibAFL](https://github.com/srlabs/golibafl)

Answer: This project provides a setup for fuzzing Go binaries using LibAFL. By leveraging Go native libFuzzer-compatible instrumentation (`sancov_8bit`), we enable advanced fuzzing capabilities beyond Go built-in fuzzing support. — [@srlabs](https://github.com/srlabs)


Question: How to: [⏫](#contents) Detect goroutine leaks with [goleak](https://github.com/uber-go/goleak)

Answer:
Instrument your test cases with verification call. Alternatively, you can add single call in `TestMain`. This tool was recommended by Pyroscope in [blog](https://grafana.com/blog/2023/04/19/how-to-troubleshoot-memory-leaks-in-go-with-grafana-pyroscope/). — Uber

```go
func TestA(t *testing.T) {
  defer goleak.VerifyNone(t)
  ...
}
```

Requirements
```
go get -u go.uber.org/goleak
```


Question: How to: [⏫](#contents) Detect goroutine leaks with [leaktest](https://github.com/fortytw2/leaktest)

Answer:
Refactored, tested variant of the goroutine leak detector found in both `net/http` tests and the cockroachdb source tree. You have to call this library in your tests. — [@fortytw2](https://github.com/fortytw2)

```
func TestPoolContext(t *testing.T) {
  ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  defer cancel()
  defer leaktest.CheckContext(ctx, t)()

  go func() {
    for {
      time.Sleep(time.Second)
    }
  }()
}
```


Question: How to: [⏫](#contents) Visualize test runs with [vgt](https://github.com/roblaszczak/vgt)

Answer:
This tool visualizes Go test results in a browser. It's helpful with understanding parallelism of tests and identifying slow tests. More information can be found in our blog post about optimizing Go tests parallelism. — [@roblaszczak](https://github.com/roblaszczak)

```
go test -json ./... | vgt
```
Requirements
```
go install github.com/roblaszczak/vgt@latest
```


Question: How to: [⏫](#contents) Summarize `go test` with [tparse](https://github.com/mfridman/tparse)

Answer:
This lightweight wrapper around STDOUT of JSON of `go test` will nicely render colorized test status, details of failures, duration, coverage, and package summary. — [@mfridman](https://github.com/mfridman)

```
set -o pipefail && go test ./... -json | tparse -all
```
Requirements
```
go install github.com/mfridman/tparse@latest
```


Question: How to: [⏫](#contents) Decorate `go test` with [richgo](https://github.com/kyoh86/richgo)

Answer:
Add colors and enrich `go test` output. It can be used in CI pipeline and has lots of alternative visualizations and options. — [@kyoh86](https://github.com/kyoh86)

```
richgo test ./...
```
Requirements
```
go install github.com/kyoh86/richgo@latest
```


Question: How to: [⏫](#contents) Decorate `go test` with [gotest](https://github.com/rakyll/gotest)

Answer:
Add colors to `go test` output. Very lightweight wrapper around `go test` STDOUT. — [@rakyll](https://github.com/rakyll)

```
gotest ./...
```
Requirements
```
go install github.com/rakyll/gotest@latest
```


Question: How to: [⏫](#contents) Decorate `go test` with [gotestsum](https://github.com/gotestyourself/gotestsum)

Answer:
This wrapper around `go test` renders test output in easy to read format. Also supports JUnit, JSON output, skipping slow tests, running custom binary. — [@dnephin](https://github.com/dnephin)

```
gotestsum --format dots
```
Requirements
```
go install gotest.tools/gotestsum@latest
```


Question: How to: [⏫](#contents) Format `go test` results as documentation with [gotestdox](https://github.com/bitfield/gotestdox)

Answer:
Decorates `go test` results by converting CamelCaseTestNames into readable sentences. — [@bitfield](https://github.com/bitfield)

```
gotestdox ./...
```
Requirements
```
go install github.com/bitfield/gotestdox/cmd/gotestdox@latest
```


Question: How to: [⏫](#contents) Get slowest tests with [gotestsum](https://github.com/gotestyourself/gotestsum)

Answer:
This is subcommand of `gotestsum` that processes JSON output of `go test` to find slowest tests. — [@dnephin](https://github.com/dnephin)

```
go test -json -short ./... | gotestsum tool slowest --threshold 500ms
```

Example
```
gotest.tools/example TestSomething 1.34s
gotest.tools/example TestSomethingElse 810ms
```

Requirements
```
go install gotest.tools/gotestsum@latest
```


Question: How to: [⏫](#contents) Automatically re-run failed tests with [gotestsum](https://github.com/gotestyourself/gotestsum)

Answer:
Other useful option of `gotestsum` is to re-run failed tests. For example, if you have flaky tests that are idempotent, then re-running them may be a quick fix. — [@dnephin](https://github.com/dnephin)

```
gotestsum --rerun-fails --packages="./..."
```

Requirements
```
go install gotest.tools/gotestsum@latest
```


Question: How to: [⏫](#contents) Make `JSUnit` test report with [gotestsum](https://github.com/gotestyourself/gotestsum)

Answer:
JUnit is widely used format for test reporting. — [@dnephin](https://github.com/dnephin)

```
go test -json ./... | gotestsum --junitfile unit-tests.xml
```

Requirements
```
go install gotest.tools/gotestsum@latest
```


Question: How to: [⏫](#contents) Get packages without tests

Answer:
If code coverage does not report packages without tests. For example for CI or quality control.

```
go list -json ./... | jq -rc 'select((.TestGoFiles | length)==0) | .ImportPath'
```

Example
```
github.com/gin-gonic/gin/ginS
github.com/gin-gonic/gin/internal/json
```

Requirements
```
https://stedolan.github.io/jq/download/
```


Question: How to: [⏫](#contents) Perform Mutation Testing with [ooze](https://github.com/gtramontina/ooze)

Answer:
Mutation testing is a technique used to assess the quality and coverage of test suites. It involves introducing controlled changes to the code base, simulating common programming mistakes. These changes are, then, put to test against the test suites. A failing test suite is a good sign. It indicates that the tests are identifying mutations in the code—it "killed the mutant". If all tests pass, we have a surviving mutant. This highlights an area with weak coverage. It is an opportunity for improvement. — [@gtramontina](https://github.com/gtramontina)

```
go test -v -tags=mutation
```
Requirements
```
go get github.com/gtramontina/ooze
```


Question: How to: [⏫](#contents) Perform Mutation Testing with [avito-tech/go-mutesting](https://github.com/avito-tech/go-mutesting)

Answer:
This is fork of [zimmski/go-mutesting](https://github.com/zimmski/go-mutesting). It has more mutators and latest updates. — [@vasiliyyudin](https://github.com/vasiliyyudin)

```
go-mutesting ./...
```

```go
for _, d := range opts.Mutator.DisableMutators {
  pattern := strings.HasSuffix(d, "*")

-	if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || (!pattern && name == d) {
+	if (pattern && strings.HasPrefix(name, d[:len(d)-2])) || false {
    continue MUTATOR
  }
}
```

Requirements
```
go install github.com/avito-tech/go-mutesting/cmd/go-mutesting@latest
```


Question: How to: [⏫](#contents) Trace tests with [go-test-trace](https://github.com/rakyll/go-test-trace)

Answer:
Collect test execution as distributed traces. This is useful for tracking test duration, failures, flakiness. You distributed tracing storage, search, UI, exploration, dashboards, alarms — all will automatically become test status collection. If you run integration tests in your CI, then it is particularly handy to investigate your integration tests same way as real requests, such as Go processes, databases, etc. However, if you do not have distributed traces, it is still useful for adhoc investigations. This tool processes STDOUT of `go test`. No automatic instrumentation is done. — [@rakyll](https://github.com/rakyll)

```
go-test-trace ./...
```
Requirements
```


Question: How to: traces UI (Datadog, Jaeger, Honeycomb, NewRelic)

Answer:
go install github.com/rakyll/go-test-trace@latest
```


Question: How to: [⏫](#contents) Speedup tests for large codebases

Answer:
As of 2023-12-11, large codebases may be slow to run tests by default commands. Compiling package test binaries first and executing them later can lead to significant overall speedup.

```
go test -c ./pkg/mypackage -o my_pkg_test_binary.bin
./my_pkg_test_binary.bin | ... # normal test output post processing
```


Question: How to: [⏫](#contents) Upgrade dependencies

Answer:
In case VSCode or GoLand broke and you need to update dependencies manually.

```
go get -u ./...
```


Question: How to: [⏫](#contents) Get Go version of current module

Answer:
For example, setup correct Go version automatically from `go.mod` in CI.

```
go mod edit -json | jq -r .Go
```

Requirements
```
https://stedolan.github.io/jq/download/
```


Question: How to: [⏫](#contents) Get Go versions of upstream modules

Answer:
Use this when upgrading version of Go or finding old modules.

```
go list -deps -json ./... | jq -rc 'select(.Standard!=true and .Module.GoVersion!=null) | [.Module.GoVersion,.Module.Path] | join(" ")' | sort -V | uniq
```

Example
```
1.11 github.com/ugorji/go/codec
1.11 golang.org/x/crypto
1.12 github.com/golang/protobuf
```

Requirements
```
https://stedolan.github.io/jq/download/
```


Question: How to: [⏫](#contents) Get directly dependent modules that can be upgraded

Answer:
Keep your modules updated. Similar function is integrated in VSCode official Go plugin and GoLand.

```
go list -u -m $(go list -m -f '{{.Indirect}} {{.}}' all | grep '^false' | cut -d ' ' -f2) | grep '\['
```

Example
```
github.com/goccy/go-json v0.5.1 [v0.7.3]
github.com/golang/protobuf v1.3.3 [v1.5.2]
github.com/json-iterator/go v1.1.9 [v1.1.11]
```


Question: How to: [⏫](#contents) Get available module versions

Answer:
This works even if you did not download or install module locally. This is useful to check to which version you can upgrade to, what is the latest version, and whether there are v2+ major versions recognized by Go toolchain.

```
go list -m -versions github.com/google/gofuzz
```


Question: How to: [⏫](#contents) Get go module libyear, number of releases, version delta with [go-libyear](https://github.com/nieomylnieja/go-libyear)

Answer:
[libyear](https://libyear.com) is a simple measure of software dependency freshness. It is a single number telling you how up-to-date your dependencies are. For example Rails 5.0.0 (June 2016) is 1 libyear behind 5.1.2 (June 2017). This tool can also compute number of releases, and version number delta. — [@nieomylnieja](https://github.com/nieomylnieja)

```
go-libyear /path/to/go.mod
```

Example
```
package                             version  date        latest   latest_date  libyear
github.com/nieomylnieja/go-libyear           2023-11-06                        2.41
github.com/pkg/errors               v0.8.1   2019-01-03  v0.9.1   2020-01-14   1.03
github.com/urfave/cli/v2            v2.20.0  2022-10-14  v2.25.7  2023-06-14   0.67
golang.org/x/mod                    v0.12.0  2023-06-21  v0.14.0  2023-10-25   0.35
golang.org/x/sync                   v0.3.0   2023-06-01  v0.5.0   2023-10-11   0.36
```

Requirements
```
go install github.com/nieomylnieja/go-libyear/cmd/go-libyear@latest
```


Question: How to: [⏫](#contents) Make graph of upstream modules with [modgraphviz](https://golang.org/x/exp/cmd/modgraphviz)

Answer:
For each module, the node representing the greatest version (i.e., the version chosen by Go's minimal version selection algorithm) is colored green. Other nodes, which aren't in the final build list, are colored grey. — official Go team

```
go mod graph | modgraphviz | dot -Tsvg -o mod-graph.svg
```
Requirements
```
https://graphviz.org/download/
go install golang.org/x/exp/cmd/modgraphviz@latest
```


Question: How to: [⏫](#contents) Make graph of upstream packages with [import-graph](https://github.com/nikolaydubina/import-graph)

Answer:
Find unexpected dependencies or visualize project. Works best for small number of packages, for large projects use `grep` to narrow down subgraph. Without `-deps` only for current module. — [@nikolaydubina](https://github.com/nikolaydubina)

```
go list -deps -json ./... | jq -c 'select(.Standard!=true) | {from: .ImportPath, to: .Imports[]}' | jsonl-graph | dot -Tsvg > package-graph.svg
```
Requirements
```
https://stedolan.github.io/jq/download/
https://graphviz.org/download/
go install github.com/nikolaydubina/import-graph@latest
go install github.com/nikolaydubina/jsonl-graph@latest
```


Question: How to: [⏫](#contents) Scrape details about upstream modules and make graph with [import-graph](https://github.com/nikolaydubina/import-graph)

Answer:
Find low quality or unmaintained dependencies. — [@nikolaydubina](https://github.com/nikolaydubina)

```
go mod graph | import-graph -i=gomod | jsonl-graph -color-scheme=file://$PWD/basic.json | dot -Tsvg > output.svg
```
Requirements
```
https://graphviz.org/download/
go install github.com/nikolaydubina/import-graph@latest
go install github.com/nikolaydubina/jsonl-graph@latest
```


Question: How to: [⏫](#contents) Scrape licenses of upstream dependencies with [go-licenses](https://github.com/google/go-licenses)

Answer:
Collect all the licenses for checking if you can use the project, for example in proprietary or commercial environment. — Google

```
go-licenses csv github.com/gohugoio/hugo
```

Example
```
github.com/cli/safeexec,https://github.com/cli/safeexec/blob/master/LICENSE,BSD-2-Clause
github.com/bep/tmc,https://github.com/bep/tmc/blob/master/LICENSE,MIT
github.com/aws/aws-sdk-go,https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt,Apache-2.0
github.com/jmespath/go-jmespath,https://github.com/jmespath/go-jmespath/blob/master/LICENSE,Apache-2.0
github.com/gorilla/websocket,https://github.com/gorilla/websocket/blob/master/LICENSE,BSD-2-Clause
github.com/pelletier/go-toml/v2,https://github.com/pelletier/go-toml/blob/master/v2/LICENSE,MIT
github.com/spf13/cobra,https://github.com/spf13/cobra/blob/master/LICENSE.txt,Apache-2.0
github.com/kyokomi/emoji/v2,https://github.com/kyokomi/emoji/blob/master/v2/LICENSE,MIT
go.opencensus.io,Unknown,Apache-2.0
github.com/Azure/azure-storage-blob-go/azblob,https://github.com/Azure/azure-storage-blob-go/blob/master/azblob/LICENSE,MIT
github.com/yuin/goldmark-highlighting,https://github.com/yuin/goldmark-highlighting/blob/master/LICENSE,MIT
```

Requirements
```
go install github.com/google/go-licenses@latest
```


Question: How to: [⏫](#contents) Explore dependencies with [goda](https://github.com/loov/goda)

Answer:
This tool has extensive syntax for filtering dependencies graphs. It can work with packages and modules. — [Egon Elbre](egonelbre@gmail.com)

```
goda graph . | dot -Tsvg -o graph.svg
goda graph -cluster -short "github.com/nikolaydubina/go-cover-treemap:all" | dot -Tsvg -o graph.svg
```
Requirements
```
https://graphviz.org/download/
go install github.com/loov/goda@latest
```


Question: How to: [⏫](#contents) Explore dependencies interactively with [spaghetti](https://github.com/adonovan/spaghetti)

Answer:
Useful in large refactorings, dependency breaking, physical layout changes. — [Alan Donovan](https://github.com/adonovan), official Go team
Requirements
```
go install github.com/adonovan/spaghetti@latest
```


Question: How to: [⏫](#contents) Explore dependencies graph interactively with [modview](https://github.com/bayraktugrul/modview)

Answer:
Transform your Go project's dependency graph into a dynamic, interactive visualization with modview. This powerful tool takes the complexity out of your module graph, offering a clear and explorable view of your project's dependencies. — [@bayraktugrul](https://github.com/bayraktugrul)

```
modview --open
```
Requirements
```
go install github.com/bayraktugrul/modview@latest
```


Question: How to: [⏫](#contents) Explore dependencies graph in CLI with [depth](https://github.com/KyleBanks/depth)

Answer:
Use this tool to retrieve and visualize Go source code dependency trees in CLI. You can also visualize multiple packages at once, set max depth, select internal only, and show explanation. — [@KyleBanks](https://github.com/KyleBanks)

```
depth github.com/KyleBanks/depth/cmd/depth
```

Example
```
github.com/KyleBanks/depth/cmd/depth
  ├ encoding/json
  ├ flag
  ├ fmt
  ├ io
  ├ log
  ├ os
  ├ strings
  └ github.com/KyleBanks/depth
    ├ fmt
    ├ go/build
    ├ path
    ├ sort
    └ strings
12 dependencies (11 internal, 1 external, 0 testing).
```

Requirements
```
go install github.com/KyleBanks/depth/cmd/depth@latest
```


Question: How to: [⏫](#contents) Explore your `GOPATH` with GUI with [goggles](https://github.com/KyleBanks/goggles)

Answer:
Browse and search local packages. View package documentation.  Displays badges for GoDoc, Goreportcard, and Travis.CI (if .travis.yml is present). — [@KyleBanks](https://github.com/KyleBanks)

```
goggles
```
Requirements
```
go install github.com/KyleBanks/goggles/cmd/goggles@latest
```


Question: How to: [⏫](#contents) Enforce Go code architecture with [go-arch-lint](https://github.com/fe3dback/go-arch-lint)

Answer:
Architecture linter. Will check all project import path and compare with arch rules defined in yml file. Useful for hexagonal / onion / ddd / mvc / etc patterns. — [@fe3dback](https://github.com/fe3dback)

```
go-arch-lint
```
Requirements
```
go install github.com/fe3dback/go-arch-lint@latest
```


Question: How to: [⏫](#contents) Check Clean Architecture with [go-cleanarch](https://github.com/roblaszczak/go-cleanarch)

Answer:
Clean architecture validator for go, like a The Dependency Rule and interaction between packages in your Go projects. — [@roblaszczak](https://github.com/roblaszczak)

```
go-cleanarch
```

Requirements
```
go install github.com/roblaszczak/go-cleanarch@latest
```


Question: How to: [⏫](#contents) Use `go mod` directives

Answer:
Tell Go compiler which versions of upstreams to include in your build. Tell all users of your module how to deal with versions of your module.

```
// Deprecated: use example.com/mod/v2 instead.
module example.com/mod

go 1.16

require example.com/other/thing v1.0.2
require example.com/new/thing/v2 v2.3.4
exclude example.com/old/thing v1.2.3
replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5
retract [v1.9.0, v1.9.5]
```


Question: How to: [⏫](#contents) Locally patch dependency with ``replace``

Answer:
This can be useful for development. First appeared on [blog](https://eli.thegreenplace.net/2024/locally-patching-dependencies-in-go).

```


Question: How to: make changes

Answer:
go mod edit -replace github.com/google/go-cmp=$DEP
```


Question: How to: [⏫](#contents) Make C4 diagram with [go-structurizr](https://github.com/krzysztofreczek/go-structurizr)

Answer:
This library provides tools to generate [C4](https://c4model.com) diagrams. The process is a bit involved, however you get diagram generated from real Go code automatically. Steps are outlined in [blog](https://threedots.tech/post/auto-generated-c4-architecture-diagrams-in-go/). — [@krzysztofreczek](https://github.com/krzysztofreczek)
Requirements
```
manually defining Go main.go script to invoke library
graphviz
manual coloring spec (DB, classes)
```


Question: How to: [⏫](#contents) Make graph of function calls with [callgraph](https://golang.org/x/tools/cmd/callgraph)

Answer:
Visualize complex or new project quickly or to study project. Requires `main.go` in module. Supports Graphviz output format. Has many options for filtering and formatting. — official Go team

```
callgraph -format graphviz . | dot -Tsvg -o graph.svg
recommend: grep
recommend: grep -v Error since many packages report error
recommend: adding `rankdir=LR;` to graphviz file for denser graph
recommend: you would have to manually fix graphviz file first and last line
```
Requirements
```
go install golang.org/x/tools/cmd/callgraph@latest
```


Question: How to: [⏫](#contents) Make graph of function calls in package with [go-callvis](https://github.com/ofabry/go-callvis)

Answer:
Quickly track which packages current package is calling and why. — [@ofabry](https://github.com/ofabry)

```
go-callvis .
```
Requirements
```
go install github.com/ofabry/go-callvis
```


Question: How to: [⏫](#contents) Make PlantUML diagram with [goplantuml](https://github.com/jfeliu007/goplantuml)

Answer:
Generates class diagram in widely used format with the information on structs, interfaces and their relationships. Render `.puml` files in for example [planttext.com](https://www.planttext.com). — [@jfeliu007](https://github.com/jfeliu007)

```
goplantuml -recursive path/to/gofiles path/to/gofiles2
```
Requirements
```
go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest
```


Question: How to: [⏫](#contents) Visualize the entropy of a code base with a 3D force-directed graph with [dep-tree](https://github.com/gabotechs/dep-tree)

Answer: This excellent interactive visualisation tool lets you explore code base as 3D graph. The more decoupled and modular a code base is, the more spread and clustered the graph will look like. — [@gabotechs](https://github.com/gabotechs)


Question: How to: [⏫](#contents) Make 3D chart of Go codebase with [gocity](https://github.com/rodrigo-brito/gocity)

Answer:
Fresh artistic perspective on Go codebase. `GoCity` is an implementation of the Code City metaphor for visualizing source code - folders are districts; files are buildings; structs are buildings on the top of their files. This project has research paper "[GoCity Code City for Go](https://homepages.dcc.ufmg.br/~mtov/pub/2019-saner-gocity.pdf)" at SANER'19. Also available at [go-city.github.io](https://go-city.github.io). — [@rodrigo-brito](https://github.com/rodrigo-brito)
Requirements
```
go install github.com/rodrigo-brito/gocity@latest
```


Question: How to: [⏫](#contents) Make histogram of Go files per package

Answer:
Find when package is too big or too small. Adjust histogram length to maximum value.

```
go list -json ./... | jq -rc '[.ImportPath, (.GoFiles | length | tostring)] | join(" ")' | perl -lane 'print (" " x (20 - $F[1]), "=" x $F[1], " ", $F[1], "\t", $F[0])'
```

Example
```
================== 18	github.com/gin-gonic/gin
     ============= 13	github.com/gin-gonic/gin/binding
                 = 1	github.com/gin-gonic/gin/internal/bytesconv
                 = 1	github.com/gin-gonic/gin/internal/json
       =========== 11	github.com/gin-gonic/gin/render
```

Requirements
```
https://stedolan.github.io/jq/download/
```


Question: How to: [⏫](#contents) Explore Go code in browser powered by `go-guru` with [pythia](https://github.com/fzipp/pythia)

Answer:
Explore Go source code in browser. It provides exported symbols summary for navigation. It answers questions like: definition; callers; implementers. It is browser frontend based on [go-guru](https://docs.google.com/document/d/1_Y9xCEMj5S-7rv2ooHpZNH15JgRT5iM742gJkw5LtmQ/edit), which was developed by Go core team from Google. — [@fzipp](https://github.com/fzipp)

```
pythia net/http
```
Requirements
```
go install github.com/fzipp/pythia@latest
go install golang.org/x/tools/cmd/guru@latest
```


Question: How to: [⏫](#contents) Interactively visualize packages with [goexplorer](https://github.com/ofabry/goexplorer)

Answer: Based on `go-callvis`, this tool is an interactive package explorer of packages. This tool have not been updated for a long time. — [@ofabry](https://github.com/ofabry)


Question: How to: [⏫](#contents) Make D2 graph of architecture and dependencies with [go-arch-lint graph](https://github.com/fe3dback/go-arch-lint)

Answer:
Can include vendors or not, and be of type 'flow' or 'di'. — [@fe3dback](https://github.com/fe3dback)

```
go-arch-lint graph
```
Requirements
```
go install github.com/fe3dback/go-arch-lint@latest
```


Question: How to: [⏫](#contents) Run `go:generate` in parallel

Answer:
Official Go team [encourages](https://github.com/golang/go/issues/20520) to run sequentially. However, in certain situations, such as lots of mocks, parallelization helps a lot, albeit, you should consider including your generated files in git. The solution below spawns multiple processes, each per pkg.

```
grep -rnw "go:generate" -E -l "${1:-*.go}" . | xargs -L1 dirname | sort -u | xargs -P 8 -I{} go generate {}
```


Question: How to: [⏫](#contents) Generate `String` method for enum types

Answer:
This is an official tool for generating `String` for enums. It supports overrides via comments. — official Go team

```go
package painkiller

//go:generate stringer -type=Pill -linecomment

type Pill int

const (
  Placebo Pill = iota
  Ibuprofen
  Paracetamol
  PillAspirin   // Aspirin
  Acetaminophen = Paracetamol
)

// "Acetaminophen"
var s string = Acetaminophen.String()
```

Requirements
```
go install golang.org/x/tools/cmd/stringer@latest
```


Question: How to: [⏫](#contents) Generate enums encoding with [go-enum-encoding](https://github.com/nikolaydubina/go-enum-encoding)

Answer:
Generate encoding code for enums. This follows json struct tag notation. — [@nikolaydubina](https://github.com/nikolaydubina)

```
go generate ./...
```

```go
type Color struct{ c uint }

//go:generate go-enum-encoding -type=Color
var (
  Undefined = Color{}  // json:"-"
  Red       = Color{1} // json:"red"
  Green     = Color{2} // json:"green"
  Blue      = Color{3} // json:"blue"
)
```

Requirements
```
go install github.com/nikolaydubina/go-enum-encoding@latest
```


Question: How to: [⏫](#contents) Generate enums with [goenums](https://github.com/zarldev/goenums)

Answer:
Generate strict and fast enums. Generated code is much more tightly typed than just iota defined enums. You will get JSON decoder and encoder as well. This tool allows to generate extra fields and default values in enum structs. — [@zarldev](https://github.com/zarldev)

```
goenums
```

```go
package milkyway

type planet int // Gravity[float64],RadiusKm[float64],MassKg[float64],OrbitKm[float64],OrbitDays[float64],SurfacePressureBars[float64],Moons[int],Rings[bool]

//go:generate goenums planets.go
const (
  unknown planet = iota // invalid
  mercury               // Mercury 0.378,2439.7,3.3e23,57910000,88,0.0000000001,0,false
  venus                 // Venus 0.907,6051.8,4.87e24,108200000,225,92,0,false
  earth                 // Earth 1,6378.1,5.97e24,149600000,365,1,1,false
  mars                  // Mars 0.377,3389.5,6.42e23,227900000,687,0.01,2,false
  jupiter               // Jupiter 2.36,69911,1.90e27,778600000,4333,20,4,true
  saturn                // Saturn 0.916,58232,5.68e26,1433500000,10759,1,7,true
  uranus                // Uranus 0.889,25362,8.68e25,2872500000,30687,1.3,13,true
  neptune               // Neptune 1.12,24622,1.02e26,4495100000,60190,1.5,2,true
)
```

Requirements
```
go install github.com/zarldev/goenums@latest
```


Question: How to: [⏫](#contents) Generate data types from JSON Schema with [go-jsonschema](https://github.com/omissis/go-jsonschema)

Answer:
JSON Schema is widely used standard for definition of structured data types. This tool will generate Go struct, decoder and validation based on JSON Schema spec. — [@omissis](https://github.com/omissis)

```
go-jsonschema -p main myschema.jsonschema
```

```go
// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.

package main

import "encoding/json"
import "fmt"

type Veggie struct {
        // Do I like this vegetable?
        VeggieLike bool `json:"veggieLike" yaml:"veggieLike" mapstructure:"veggieLike"`

        // The name of the vegetable.
        VeggieName string `json:"veggieName" yaml:"veggieName" mapstructure:"veggieName"`
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *Veggie) UnmarshalJSON(b []byte) error {
        var raw map[string]interface{}
        if err := json.Unmarshal(b, &raw); err != nil {
                return err
        }
        if v, ok := raw["veggieLike"]; !ok || v == nil {
                return fmt.Errorf("field veggieLike in Veggie: required")
        }
        if v, ok := raw["veggieName"]; !ok || v == nil {
                return fmt.Errorf("field veggieName in Veggie: required")
        }
        type Plain Veggie
        var plain Plain
        if err := json.Unmarshal(b, &plain); err != nil {
                return err
        }
        *j = Veggie(plain)
        return nil
}

// A representation of a person, company, organization, or place
type A2Schema struct {
        // Fruits corresponds to the JSON schema field "fruits".
        Fruits []string `json:"fruits,omitempty" yaml:"fruits,omitempty" mapstructure:"fruits,omitempty"`

        // Vegetables corresponds to the JSON schema field "vegetables".
        Vegetables []Veggie `json:"vegetables,omitempty" yaml:"vegetables,omitempty" mapstructure:"vegetables,omitempty"`
}
```

Example
```
{
      "$id": "https://example.com/arrays.schema.json",
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "description": "A representation of a person, company, organization, or place",
      "type": "object",
      "properties": {
            "fruits": {
                  "type": "array",
                  "items": {
                        "type": "string"
                  }
            },
            "vegetables": {
                  "type": "array",
                  "items": {
                        "$ref": "#/$defs/veggie"
                  }
            }
      },
      "$defs": {
            "veggie": {
                  "type": "object",
                  "required": [
                        "veggieName",
                        "veggieLike"
                  ],
                  "properties": {
                        "veggieName": {
                              "type": "string",
                              "description": "The name of the vegetable."
                        },
                        "veggieLike": {
                              "type": "boolean",
                              "description": "Do I like this vegetable?"
                        }
                  }
            }
      }
}
```

Requirements
```
go get github.com/atombender/go-jsonschema/...
go install github.com/atombender/go-jsonschema@latest
```


Question: How to: [⏫](#contents) Generate constructor for a struct with [gonstructor](https://github.com/moznion/gonstructor)

Answer:
Constructor is a widely used useful pattern. This tool generates basic version of it that passes arguments to struct. It also supports initializer method. — [@moznion](https://github.com/moznion)

```go
//go:generate gonstructor --type=Structure --constructorTypes=allArgs
type Structure struct {
  foo string
  bar io.Reader
  Buz chan interface{}
}
```

Requirements
```
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/moznion/gonstructor/cmd/gonstructor@latest
```


Question: How to: [⏫](#contents) Generate Table Driven Tests with [gotests](https://github.com/cweill/gotests)

Answer: This tool generates basic test placeholder. It is included into official Go plugin in VSCode and other major code editors. — [@cweill](https://github.com/cweill)


Question: How to: [⏫](#contents) Generate mocks with [mockgen](https://github.com/uber-go/mock)

Answer:
This mocking framework integrates well with Go's built-in `testing` package, but can be used in other contexts too. — Go Core team, Uber

```
mockgen . Conn,Driver
```

```go


Question: How to: foo_test.go

Answer:
func TestFoo(t *testing.T) {
  ctrl := gomock.NewController(t)

  m := NewMockFoo(ctrl)

  // Does not make any assertions. Executes the anonymous functions and returns
  // its result when Bar is invoked with 99.
  m.
    EXPECT().
    Bar(gomock.Eq(99)).
    DoAndReturn(func(_ int) int {
      time.Sleep(1*time.Second)
      return 101
    }).
    AnyTimes()

  // Does not make any assertions. Returns 103 when Bar is invoked with 101.
  m.
    EXPECT().
    Bar(gomock.Eq(101)).
    Return(103).
    AnyTimes()

  SUT(m)
}
```

Requirements
```
go install go.uber.org/mock/mockgen@latest
```


Question: How to: [⏫](#contents) Generate interface for a struct with [ifacemaker](https://github.com/vburenin/ifacemaker)

Answer:
This is a development helper program that generates a Golang interface by inspecting the structure methods of an existing .go file. The primary use case is to generate interfaces for [gomock](https://github.com/golang/mock), so that [gomock](https://github.com/golang/mock) can generate mocks from those interfaces. This makes unit testing easier. — [@vburenin](https://github.com/vburenin)

```
ifacemaker -f human.go -s Human -i HumanIface -p humantest -y "HumanIface makes human interaction easy" -c "DONT EDIT: Auto generated"
```

```go


Question: How to: human_interface.go

Answer:
// DONT EDIT: Auto generated
package humantest

// HumanIface makes human interaction easy
type HumanIface interface {
  // Returns the name of our Human.
  GetName() string
  // Our Human just had a birthday! Increase its age.
  Birthday()
  // Make the Human say hello.
  SayHello()
}
```

Requirements
```
go install github.com/vburenin/ifacemaker@latest
```


Question: How to: [⏫](#contents) Generate interface for a struct with [interfacer](https://github.com/rjeczalik/interfaces)

Answer:
This tool generates interface for a struct. Can be invoked in `go:generate`. — [@rjeczalik](https://github.com/rjeczalik)

```
interfacer -for os.File -as mock.File
```

```go
// Created by interfacer; DO NOT EDIT

package mock

import (
        "os"
)

// File is an interface generated for "os".File.
type File interface {
        Chdir() error
        Chmod(os.FileMode) error
        Chown(int, int) error
        Close() error
        Fd() uintptr
        Name() string
        Read([]byte) (int, error)
        ReadAt([]byte, int64) (int, error)
        Readdir(int) ([]os.FileInfo, error)
        Readdirnames(int) ([]string, error)
        Seek(int64, int) (int64, error)
        Stat() (os.FileInfo, error)
        Sync() error
        Truncate(int64) error
        Write([]byte) (int, error)
        WriteAt([]byte, int64) (int, error)
        WriteString(string) (int, error)
}
```

Requirements
```
go install github.com/rjeczalik/interfaces/cmd/interfacer@latest
```


Question: How to: [⏫](#contents) Generate interface for a struct with [struct2interface](https://github.com/reflog/struct2interface)

Answer:
This is alternative tool for interface generation that is aimed to be faster and leaner. It generates only pointer method receiver methods for a struct. — [@reflog](https://github.com/reflog)

```
struct2interface -f . -i IDecimal -p fpdecimal -s Decimal -o idecimal.go
```

Requirements
```
go install github.com/reflog/struct2interface@latest
```


Question: How to: [⏫](#contents) Generate interface for `CSV` file with [structer](https://github.com/rjeczalik/interfaces)

Answer:
This tool generates struct that can read and write `CSV` file of this struct. Order of fields is hardcoded. — [@rjeczalik](https://github.com/rjeczalik)

```
structer -f aws-billing.csv -tag json -as billing.Record
```

```go


Question: How to: [⏫](#contents) Generate decorator for interface with [gowrap](https://github.com/hexdigest/gowrap)

Answer:
GoWrap is a command line tool that generates decorators for Go interface types using simple templates. With GoWrap you can easily add metrics, tracing, fallbacks, pools, and many other features into your existing code in a few seconds. — [@hexdigest](https://github.com/hexdigest)

```
gowrap gen -p io -i Reader -t prometheus -o reader_with_metrics.go
```
Requirements
```
go install github.com/hexdigest/gowrap/cmd/gowrap@latest
```


Question: How to: [⏫](#contents) Modify struct field tags with [gomodifytags](https://github.com/fatih/gomodifytags)

Answer:
This tool makes it easy to update, add or delete the tags and options in a struct field. You can add new tags, update existing tags (such as appending a new key, i.e: db, xml, etc..) or remove existing tags. It's intended to be used by an editor, but also has modes to run it from the terminal. — [@fatih](https://github.com/fatih)
Requirements
```
go install github.com/fatih/gomodifytags@latest
```


Question: How to: [⏫](#contents) Generate code from OpenAPI 3 specification with [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen)

Answer:
Generate Go client and server boilerplate from OpenAPI 3 specifications. — [@deepmap](https://github.com/deepmap)

```
oapi-codegen --config=config.yaml api.yaml
```

Requirements
```
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
```


Question: How to: [⏫](#contents) Generate C-Go Bindings with [c-for-go](https://github.com/xlab/c-for-go?tab=readme-ov-file)

Answer: This project allows to reuse existing C/C++ libraries in your Go applications, by automatically creating c-go bindings for a given set of C headers and the manifest file. We believe in component-based software engineering and think that reusing C/C++ code in Go applications could bring a huge boost to developer's productivity and system's performance. Read more about the motivation: top reasons to use bindings. — [@xlab](https://github.com/xlab)


Question: How to: [⏫](#contents) Enum via generics with [enum](https://github.com/orsinium-labs/enum)

Answer:
Type safe enums for Go without code generation or reflection. — [@orsinium](https://github.com/orsinium)

```go
type Color enum.Member[string]

var (
  Red    = Color{"red"}
  Green  = Color{"green"}
  Blue   = Color{"blue"}
  Colors = enum.New(Red, Green, Blue)
)
```


Question: How to: [⏫](#contents) Replace symbol with `gofmt`

Answer:
I found this in announcement [notice](https://github.com/golang/go/commit/2580d0e08d5e9f979b943758d3c49877fb2324cb) of Go 1.18 for changes to `interface{}` to `any`. This can be useful for other refactorings too.

```
gofmt -w -r 'interface{} -> any' .
```


Question: How to: [⏫](#contents) Apply refactoring patches with [gopatch](https://github.com/uber-go/gopatch)

Answer:
With this tool it is very easy to perform refactorings. It is also possible to organize and maintain your refactoring procedures through patches. — Uber

```go
@@
@@
-import "errors"

-errors.New(fmt.Sprintf(...))
+fmt.Errorf(...)
```

Example
```
return errors.New(fmt.Sprintf("invalid port: %v", err))
// becomes
return fmt.Errorf("invalid port: %v", err)
```


Question: How to: [⏫](#contents) Keep consistent ordering of imports with [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)

Answer:
This is official tool for for grouping and sorting imports. However, it has only basic grouping functionality. — Go Core team

```
goimports -w -local .
```

Requirements
```
go install golang.org/x/tools/cmd/goimports@latest
```


Question: How to: [⏫](#contents) Keep consistent ordering of imports with [gci](https://github.com/daixiang0/gci)

Answer:
This tool splits all import blocks into different sections, now support five section types: standard (e.g. 'fmt'); custom; default; blank; dot. It will keep each section sorted and keep ordering of sections consistent. — [@daixiang0](https://github.com/daixiang0)

```
gci write -s standard -s default -s "prefix(github.com/daixiang0/gci)" main.go
```

```go
// before
package main
import (
  "golang.org/x/tools"

  "fmt"

  "github.com/daixiang0/gci"
)

// after
package main
import (
    "fmt"

    "golang.org/x/tools"

    "github.com/daixiang0/gci"
)
```

Requirements
```
go install github.com/daixiang0/gci@latest
```


Question: How to: [⏫](#contents) Errors with return traces with [errtrace](https://github.com/bracesdev/errtrace)

Answer:
Return trace is the path that error took to return to user. This can be more illustrative than typical stack trace that produced the error. This tool have convenience automatic instrumentation CLI to update your code. — [@bracesdev](https://github.com/bracesdev)

```
git ls-files -- '*.go' | xargs errtrace -w
```

Requirements
```
use package "braces.dev/errtrace"
instrument code by wrapping errors through all functions with this library
```


Question: How to: [⏫](#contents) Errors with stack traces and source fragments with [tracerr](https://github.com/ztrue/tracerr)

Answer:
This library collects stack traces and pretty prints code fragments. Stack traces induce performance penalty. — [@ztrue](https://github.com/ztrue)

```go
package main

import (
  "io/ioutil"

  "github.com/ztrue/tracerr"
)

func main() {
  if err := read(); err != nil {
    tracerr.PrintSourceColor(err)
  }
}

func read() error {
  return readNonExistent()
}

func readNonExistent() error {
  _, err := ioutil.ReadFile("/tmp/non_existent_file")
  // Add stack trace to existing error, no matter if it's nil.
  return tracerr.Wrap(err)
}
```


Question: How to: [⏫](#contents) Pretty print `panic` messages with [panicparse](https://github.com/maruel/panicparse)

Answer:
Read `panic` messages easier. Need to redirect STDERR to this tool with `panic` stack traces. The tool has HTML output and does lots of deduplication and enhancements. Refer to examples in original repo. — [@maruel](https://github.com/maruel)

```
go test -v |& pp
```
Requirements
```
go install github.com/maruel/panicparse/v2/cmd/pp@latest
```


Question: How to: [⏫](#contents) :gift: Generate errors from a spec with [zederr](https://github.com/amanbolat/zederr)

Answer:
This is a tool for error codes documentation and code generation. You can define all the errors in one YAML file and generate strictly typed error constructors. Error public messages are automatically localized on initialization based on the user locale. — [@amanbolat](https://github.com/amanbolat)

```
zederr gen --go-out ./out --spec zederr_spec.yaml
```

Requirements
```
go install github.com/amanbolat/zederr/cmd/zederr@latest
```


Question: How to: [⏫](#contents) Fetch private dependencies in CI

Answer:
If you are building in CI (e.g. GitHub Actions), you need to download private repositories. Common way to accomplish this is with job like below.

```yaml
name: go private modules
env:
  USER: ${{ secrets.USER }}
  TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
run: git config --global url."https://${USER}:${TOKEN}@github.com".insteadOf "https://github.com"
```


Question: How to: [⏫](#contents) Show compiler optimization decisions on heap and inlining

Answer:
Building with `-m` flag will show decisions of compiler on inlining and heap escape. This can help you to validate your understanding of your code and optimize it.

```
go build -gcflags="-m -m" . 2>&1 | grep inline
```

Example
```
...
./passengerfp.go:25:6: cannot inline (*PassengerFeatureTransformer).Fit: function too complex: cost 496 exceeds budget 80
...
./passengerfp.go:192:6: can inline (*PassengerFeatureTransformer).NumFeatures with cost 35 as: method(*PassengerFeatureTransformer) func() int { if e == nil { return 0 }; count := 6; count += (*transformers.OneHotEncoder).NumFeatures(e.Sex); count += (*transformers.OneHotEncoder).NumFeatures(e.Embarked); return count }
...
./passengerfp.go:238:43: inlining call to transformers.(*OneHotEncoder).FeatureNames
./passengerfp.go:238:43: inlining call to transformers.(*OneHotEncoder).NumFeatures
...
./passengerfp.go:151:7: parameter e leaks to {heap} with derefs=0:
./passengerfp.go:43:11: make(map[string]uint) escapes to heap
```


Question: How to: [⏫](#contents) Disable inlining

Answer:
Usually you may not need it, but can reduce binary size and even improve performance.

```
go build -gcflags="-l" .
```


Question: How to: [⏫](#contents) :gift: Reduce size of binary

Answer:
First, get breakdown of how much specific packages take space in your binary. Very often you will see some dependnecy taking 80% of your binary size, yet often you can have more slim version of it. (e.g. `elasticsearch`, `gcp` clients). Then, apply compiler directives to strip away non-essential information.

```
go build -ldflags="-s -w" .
```


Question: How to: [⏫](#contents) Profile-guided optimization

Answer:
Starting go 1.20 compiler supports Profile-guided optimization. You need to collect profiles and then supply in computation to compiler. You can get improvement in performance by around 4%. Official [guideline](https://go.dev/doc/pgo).

```
1. store a `pprof` CPU profile with filename default.pgo in the main package directory of the profiled binary
2. build with `go build -pgo=auto``, which will pick up `default.pgo` files automatically.
```


Question: How to: [⏫](#contents) Manually disable or enable `cgo`

Answer: Disable `cgo` with `CGO_ENABLED=0` and enable with `CGO_ENABLED=1`. If you don't, `cgo` may end-up being enabled or code dynamically linked if, for example, you use some `net` or `os` packages. You may want to disable `cgo` to improve performance, since compiler and runtime would have easier job optimizing code. This also should reduce your image size, as you can have alpine image with less shared libraries.


Question: How to: [⏫](#contents) Include metadata in binary during compilation with `ldflags`

Answer:
You can pass metadata through compiler to your binary. This is useful for including things like git commit, database schema version, integrity hashes. Variables can only be strings.

```
go build -v -ldflags="-X 'main.Version=v1.0.0'"
go build -v -ldflags="-X 'my/pkg/here.Variable=some-string'"
```

```go
package main

var Version string

func main() {
  // Version here has some value
  ...
}
```


Question: How to: [⏫](#contents) Check if symbol or package is included in binary

Answer:
This is useful for investigations during performance optimization, security, or compiler work. First spotted in [blog](https://rednafi.com/go/omit_dev_dependencies_in_binaries/).

```
go tool nm main | grep -Ei '
|
|...'
go tool nm main | grep -Ei 'golangci-lint|gofumpt'
```


Question: How to: [⏫](#contents) Build for Raspberry Pi, Virtual Machine, embedded or normal PC with [gokrazy](https://github.com/gokrazy/gokrazy)

Answer:
Turn your Go program(s) into an appliance running on the Raspberry Pi 3, Pi 4, Pi 5, Pi Zero 2 W, or amd64 PCs! [gokrazy.org](https://gokrazy.org/). The surface area for security vulnerabilities is drastically reduced. gokrazy uses its own minimal Go userland instead of a traditional Linux distribution base. The root filesystem is entirely read-only (making persistent malware installation hard) and new versions of the system are installed by overwriting the root file system with the new version. No default shell access: There is neither xz nor OpenSSH on a gokrazy system. Interactive access for debugging is possible, but needs to be explicitly started. — [@stapelberg](https://github.com/stapelberg)

```
follow instructions at: https://gokrazy.org/quickstart/
```

Requirements
```
go install github.com/gokrazy/tools/cmd/gok@main
```


Question: How to: [⏫](#contents) Visualise dependencies size in compiled binaries with [go-size-analyzer](https://github.com/Zxilly/go-size-analyzer)

Answer:
A tool for analyzing the dependencies in compiled Golang binaries, providing insight into their impact on the final build. WebAssembly demo: [https://gsa.zxilly.dev](https://gsa.zxilly.dev). — [@Zxilly](https://github.com/Zxilly)

```
gsa --web target_binary
```
Requirements
```
go install github.com/Zxilly/go-size-analyzer/cmd/gsa@latest
```


Question: How to: [⏫](#contents) Make treemap breakdown of Go executable binary with [go-binsize-treemap](https://github.com/nikolaydubina/go-binsize-treemap)

Answer:
Useful for studying Go compiler, large projects, projects with C/C++ and `cgo`, 3rd party dependencies, embedding. However, total size may not be something to worry about for your executable. — [@nikolaydubina](https://github.com/nikolaydubina)

```
go tool nm -size
| go-binsize-treemap > binsize.svg
```
Requirements
```
go install github.com/nikolaydubina/go-binsize-treemap@latest
```


Question: How to: [⏫](#contents) Custom import path

Answer:
Go can automatically fetch from custom http/https servers using `
` tag to discover how to fetch code. There are multiple tools that can help set this up. This can help for security and analytics. This is also known as vanity URLs. [documentation](https://pkg.go.dev/cmd/go#hdr-Remote_import_paths).

```


Question: How to: some notable examples

Answer:
golang.org/x/exp
go.uber.org/multierr
honnef.co/go/tools/cmd/staticcheck
```


Question: How to: [⏫](#contents) Custom import path with [govanityurls](https://github.com/GoogleCloudPlatform/govanityurls)

Answer:
Simple HTTP server that lets you host custom import paths for your Go packages. — Google

```
govanityurls
```

Requirements
```
go install github.com/GoogleCloudPlatform/govanityurls@latest
```


Question: How to: [⏫](#contents) Custom import path with [sally](https://github.com/uber-go/sally)

Answer:
Simple HTTP server that lets you host custom import paths for your Go packages. — Uber

```
sally
```

Requirements
```
go install go.uber.org/sally@latest
```


Question: How to: [⏫](#contents) Custom import path with [kkn.fi/vanity](https://kkn.fi/vanity)

Answer:
Simple HTTP server that lets you host custom import paths for your Go packages. — [@kare](https://github.com/kare)

```
vanity
```

Requirements
```
go get kkn.fi/vanity
```


Question: How to: [⏫](#contents) Custom import path enforcement

Answer:
When import path is using custom domain, it is possible to block code from compilation unless it is used. This can help ensure security and prevent breaking changes. [documentation](https://pkg.go.dev/cmd/go#hdr-Import_path_checking).

```go
package pdf // import "rsc.io/pdf"
```


Question: How to: [⏫](#contents) Manage multiple Go versions with [Goenv](https://github.com/Norwik/Goenv)

Answer: This tool makes it easier for managing multiple Go versions on same host. This works through intercepting Go commands and directing them to the right Go version bin and directory. Official Go [documentation](https://go.dev/doc/manage-install) on this topic. — [@clivern](https://github.com/clivern)


Question: How to: [⏫](#contents) Transpile C to Go with [cxgo](https://github.com/gotranspile/cxgo)

Answer:
CxGo is a tool for translating C source code to Go (aka transpiler, source-to-source compiler). It uses cc v3 for preprocessing and parsing C (no clang/gcc dependencies!) and a custom type-checker and AST translation layer to make the best output possible. — [@dennwc](https://github.com/dennwc)

```
cxgo file main.c
```

Requirements
```
go install github.com/gotranspile/cxgo/cmd/cxgo@latest
```


Question: How to: [⏫](#contents) Transpile Go to Javascript with [gopherjs](https://github.com/gopherjs/gopherjs)

Answer:
GopherJS compiles Go code (go.dev) to pure JavaScript code. Its main purpose is to give you the opportunity to write front-end code in Go which will still run in all browsers. — [@neelance](https://github.com/neelance)

```
gopherjs build
```

Requirements
```
go install github.com/gopherjs/gopherjs@v1.19.0-beta1
```


Question: How to: [⏫](#contents) Run compile-time function evaluation with [prep](https://github.com/pijng/prep)

Answer:
By using prep.Comptime, you can evaluate functions at compile time, replacing them with their computed results. — [@pijng](https://github.com/pijng)

```
go build -a -toolexec="prep" main.go
```

```go
package main

import (
  "fmt"
  "github.com/pijng/prep"
)

func main() {
  // This will be evaluated at compile-time
  result := prep.Comptime(fibonacci(300))

  fmt.Println("Result:", result)
}

func fibonacci(n int) int {
  fmt.Printf("calculating fibonacci for %d\n", n)

  if n <= 1 {
    return n
  }
  a, b := 0, 1
  for i := 2; i <= n; i++ {
    a, b = b, a+b
  }
  return b
}
```

Requirements
```
go install github.com/pijng/prep/cmd/prep@latest
```


Question: How to: [⏫](#contents) :gift: Containerize your builds with [brewkit](https://github.com/ispringtech/brewkit)

Answer:
BrewKit is a container-native build system focused on repeatable builds and caching.

```
brewkit build
```

```jsonnet
local app = "service";

local copy = std.native('copy');

{
    apiVersion: "brewkit/v1",
    targets: {
        all: ['gobuild'],

        gobuild: {
            from: "golang:1.24",
            workdir: "/app",
            copy: [
                copy('cmd', 'cmd'),
                copy('pkg', 'pkg'),
            ],
            command: std.format("go build -o ./bin/%s ./cmd/%s", [app])
        }
    }
}
```

Requirements
```
go install github.com/ispringtech/brewkit/cmd/brewkit@latest
```


Question: How to: [⏫](#contents) Get assembly of Go code snippets online

Answer: Use [godbolt.org](https://godbolt.org) to compile and see assembly of short Go code. You can check different platforms and compilers including `cgo`. This tool is commonly used by C++ community. — [@mattgodbolt](https://github.com/mattgodbolt)


Question: How to: [⏫](#contents) Get Go SSA intermediary representation with [ssaplayground](https://github.com/golang-design/ssaplayground)

Answer: Check what does Go compiler do. Might be useful if you trying to optimize some code or learn more about compiler. https://golang.design/gossa. — [@changkun](https://github.com/changkun)


Question: How to: [⏫](#contents) View Go assembly interactively with [lensm](https://github.com/loov/lensm)

Answer:
Understand how Go is compiled better. — [@egonelbre](https://github.com/egonelbre)
Requirements
```
go install loov.dev/lensm@main
```


Question: How to: [⏫](#contents) View Go assembly with color annotation with [pat/disfunc](https://github.com/maruel/pat)

Answer:
This tool shows assembly of functions and what lines mean by color. — [@maruel](https://github.com/maruel)

```
disfunc -f 'nin\.CanonicalizePath$' -pkg ./cmd/nin | less -R
```
Requirements
```
go install github.com/maruel/pat/cmd/...@latest
```


Question: How to: [⏫](#contents) Generate Go assembly in Go with [avo](https://github.com/mmcloughlin/avo)

Answer:
Write better quality Go assembly quicker in Go language itself. This tool conveniently generates stub for Go code to call your generated assembly. Used by Go core. — [@mmcloughlin](https://github.com/mmcloughlin)

```go
//go:build ignore
// +build ignore

package main

import . "github.com/mmcloughlin/avo/build"

func main() {
  TEXT("Add", NOSPLIT, "func(x, y uint64) uint64")
  Doc("Add adds x and y.")
  x := Load(Param("x"), GP64())
  y := Load(Param("y"), GP64())
  ADDQ(x, y)
  Store(y, ReturnIndex(0))
  RET()
  Generate()
}
```


Question: How to: [⏫](#contents) Generate AST for code snippets with `go/ast`

Answer:
Access Go core AST mechanism to generate AST.

```go
package main

import (
  "go/ast"
  "go/parser"
  "go/token"
)

func main() {
  fs := token.NewFileSet()
  tr, _ := parser.ParseExpr("(3-1) * 5")
  ast.Print(fs, tr)
}
```

Example
```
0  *ast.BinaryExpr {
1  .  X: *ast.ParenExpr {
2  .  .  Lparen: -
3  .  .  X: *ast.BinaryExpr {
4  .  .  .  X: *ast.BasicLit {
5  .  .  .  .  ValuePos: -
6  .  .  .  .  Kind: INT
7  .  .  .  .  Value: "3"
8  .  .  .  }
9  .  .  .  OpPos: -
10  .  .  .  Op: -
11  .  .  .  Y: *ast.BasicLit {
12  .  .  .  .  ValuePos: -
13  .  .  .  .  Kind: INT
14  .  .  .  .  Value: "1"
15  .  .  .  }
16  .  .  }
17  .  .  Rparen: -
18  .  }
19  .  OpPos: -
20  .  Op: *
21  .  Y: *ast.BasicLit {
22  .  .  ValuePos: -
23  .  .  Kind: INT
24  .  .  Value: "5"
25  .  }
26  }
```


Question: How to: [⏫](#contents) Generate AST for code snippets with [go2ast](https://github.com/reflog/go2ast)

Answer:
This is a wrapper around `go/ast` machinery that makes generating `AST` easier. — [@reflog](https://github.com/reflog)

```
echo "a := 1" | go2ast
```

Example
```
[]ast.Stmt {
  &ast.AssignStmt {
    Lhs: []ast.Expr {
      &ast.Ident {
        Name: "a",
      },
    },
    Tok: :=,
    Rhs: []ast.Expr {
      &ast.BasicLit {
        ValuePos: 32,
        Kind: INT,
        Value: "1",
      },
    },
  },
}
```

Requirements
```
go install github.com/reflog/go2ast@latest
```


Question: How to: [⏫](#contents) Visualize Go SSA function using Graphviz with [go-ssaviz](https://github.com/SilverRainZ/go-ssaviz)

Answer:
This tool provides a visual overview of Go SSA function using Graphviz. This is especially useful in SSA-based static analysis. This tool generates an HTML page that is easy to navigate. [demo](https://silverrainz.me/go-ssaviz/). — [@SilverRainZ](https://github.com/SilverRainZ)

```
go-ssaviz ./...
```
Requirements
```


Question: How to: get graphviz

Answer:
go install github.com/SilverRainZ/go-ssaviz@latest
```


Question: How to: [⏫](#contents) Make graph of AST with [astgraph](https://github.com/xiazemin/ast_graph)

Answer:
This tool visualizes AST as graph, which may be useful to navigate and understand Go AST. This tool has not been maintained for a while. — [@xiazemin](https://github.com/xiazemin)
Requirements
```
graphviz
```


Question: How to: [⏫](#contents) Convert C assembly to Go assembly with [c2goasm](https://github.com/minio/c2goasm)

Answer:
This tool can convert C assembly `.s` into Go assbmely `.s` files. This is useful for reusing compiler optimizations such as SIMD or loop unrolling in C, which can lead to 10x speedups. However, project has been archived 4+ years ago. — [@fwessels](https://github.com/fwessels)

```
gcc -O3 -march=native -S -o c_code.s c_code.c
c2goasm -a c_code.s go_c_code.s
go build -o go_c_code.o -gcflags="-S" go_c_code.s
```

Requirements
```
go install github.com/minio/c2goasm@latest
```


Question: How to: [⏫](#contents) :gift: Automatically set memory and cpu limits in K8S

Answer:
Go can automatically detect container environment cpu and memory limits. This ensures better utilization. Starting Go 1.25 `GOMAXPROCS` is K8S aware and sets it from `limits.cpu` automatically.

```yaml
- name: GOMEMLIMIT
  valueFrom:
    resourceFieldRef:
      resource: limits.memory
```

Requirements
```
go 1.25+
```


Question: How to: [⏫](#contents) Embed Go Playground to your blog with [codapi](https://github.com/nalgeon/codapi)

Answer:
Codapi is a platform for embedding interactive code snippets directly into your product documentation, online course or blog post. [example](https://antonz.org/go-1-22/). — [@nalgeon](https://github.com/nalgeon)

```
'''go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
'''
```
Requirements
```
deploy sandbox
embed javascript in your blog
markdown go code blocks will turn into runnable snippets
```


Question: How to: [⏫](#contents) Embed Go Playground to your blog with [goplay](https://github.com/ggicci/goplay)

Answer:
Embed interactive Go Playground component into your blog. [Hugo](https://gohugo.io), [Docusaurus](https://docusaurus.io), [Ghost](https://ghost.org) are supported. There is also another tool [soksan](https://github.com/bbalet/soksan), however it is discontinued. Live [demo](https://ggicci.me/goplay-embed-go-playground-on-your-website/) with guideline. Other resources — GitLab considering to add it in [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/212769); alternative implementation [guideline](https://hrishikeshpathak.com/blog/golang-code-playground/). — [@ggicci](https://github.com/ggicci)

```


Question: How to: Sample Code

Answer:
{{% goplay %}}
'''go
package main

func main() {
  println("hello world")
}
'''
{{% /goplay %}}
```

Requirements
```
reverse proxy server to https://play.golang.org
bloging platform with support for embedding javascript
```


Question: How to: [⏫](#contents) Run alternative Go Playground with [goplay.tools](https://github.com/x1unix/go-playground)

Answer: Improved Go Playground featuring dark theme, code autocomplete, vim mode, WebAssembly. Available at [https://goplay.tools/](https://goplay.tools/). — [@x1unix](https://github.com/x1unix)


Question: How to: [⏫](#contents) Use TinyGo Playground with [tinygo](https://play.tinygo.org)

Answer: TinyGo is an alternative Go compiler that focuses on embedded devices, and WASM. There are some Go constructs and packages that not supported. In this online playground you can verify your code.


Question: How to: [⏫](#contents) Run interactive Go kernels in Jupyter Notebook with [gophernotes](https://github.com/gopherdata/gophernotes)

Answer:
Run interactive Go interpreter in Jupyter Notebook browser. As of `2023-06-04`, it is using `gomacro` interpreter and can have issues with loading 3rd party packages. — [@gopherdata](https://github.com/gopherdata)
Requirements
```


Question: How to: jupyter notebook

Answer: go install github.com/gopherdata/gophernotes@v0.7.5


Question: How to: [⏫](#contents) Run interactive Go interpreter with [yaegi](https://github.com/traefik/yaegi)

Answer:
This interpreter works with 3rd party packages located in `$GOPATH/src`. It can also be triggered within Go programmatically via `Eval()`. Works everywhere Go works. — [@traefik](https://github.com/traefik)

```
yaegi
```

Example
```
$ yaegi
> import "github.com/nikolaydubina/fpdecimal"
: 0x140000faaf0
> a, _ := fpdecimal.FromString("10.12")
: {0}
> b, _ := fpdecimal.FromString("5.38")
: {0}
> c := a.Add(b)
: {15500}
> c.String()
: 15.500
>
```

Requirements
```
go install github.com/traefik/yaegi@latest
```


Question: How to: [⏫](#contents) Run interactive Go interpreter with [gomacro](https://github.com/cosmos72/gomacro)

Answer:
This is interactive Go interpreter and debugger with REPL, Eval, generics and Lisp-like macros. You can run functions, import 3rd patry packages. Can be useful for learning and experimentation. Some nice features: autocomplete; constant expressions arithmetics. As of `2023-06-02`, issues with importing 3rd paty package are possible. — [@cosmos72](https://github.com/cosmos72)

```
gomacro
```

Example
```
$ gomacro
gomacro> import "fmt"
gomacro> fmt.Println("hello, world!")
hello, world!
14      // int
// error
gomacro>
```

Requirements
```
go install github.com/cosmos72/gomacro@latest
```


Question: How to: [⏫](#contents) Run Go function in shell with [gorram](https://github.com/natefinch/gorram)

Answer:
Run Go one-liners. This tool will print to STDOUT the return of a function call. — [@natefinch](https://github.com/natefinch)

```
cat README.md | gorram crypto/sha1 Sum
echo 12345 | gorram encoding/base64 StdEncoding.EncodeToString
gorram net/http Get https://google.com
```

Requirements
```
go install github.com/natefinch/gorram@latest
```


Question: How to: [⏫](#contents) Run simple fileserver with `net/http`

Answer:
It takes one line to run HTTP file server in Go. Akin to famous oneliner in Python `python3 -m http.server` and `python -m SimpleHTTPServer`. Run this file as usually `go run
`.

```go
package main

import "net/http"

func main() { http.ListenAndServe(":9000", http.FileServer(http.Dir("."))) }
```


Question: How to: [⏫](#contents) Create 3D visualization of concurrency traces with [gotrace](https://github.com/divan/gotrace)

Answer:
Fresh artistic perspective on coroutines execution. There is no advanced functions and it is hard to analyze production systems. However, it could be interesting for educational purposes. — [@divan](https://github.com/divan)
Requirements
```
go install github.com/divan/gotrace@latest
patch Go compiler, available via Docker
more instructions in original repo
```


Question: How to: [⏫](#contents) Wrap command with `os/exec`

Answer:
Originally posted in [blog](https://www.dolthub.com/blog/2022-11-28-go-os-exec-patterns/).

```go
cmd := exec.Command("ls", "/usr/local/bin")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
```


Question: How to: [⏫](#contents) Capture output of command to file with `os/exec`

Answer:
Originally posted in [blog](https://www.dolthub.com/blog/2022-11-28-go-os-exec-patterns/). — Aaron Son

```go
log, err := os.Create("output.log")
if err != nil {
  return err
}
defer log.Close()
cmd := exec.Command("ls", "/usr/local/bin")
cmd.Stdout = log
cmd.Stderr = log
return cmd.Run()
```


Question: How to: [⏫](#contents) Piping between processes with `os/exec`

Answer:
`ls /usr/local/bin | grep pip`. Originally posted in [blog](https://www.dolthub.com/blog/2022-11-28-go-os-exec-patterns/). — Aaron Son

```go
r, w, err := os.Pipe()
if err != nil {
  return err
}
defer r.Close()

ls := exec.Command("ls", "/usr/local/bin")
ls.Stdout = w
err = ls.Start()
if err != nil {
  return err
}
defer ls.Wait()
w.Close()

grep := exec.Command("grep", "pip")
grep.Stdin = r
grep.Stdout = os.Stdout
return grep.Run()
```


Question: How to: [⏫](#contents) `errgroup` and CommandContext with `os/exec`

Answer:
Originally posted in [blog](https://www.dolthub.com/blog/2022-11-28-go-os-exec-patterns/). — Aaron Son

```go
eg, ctx := errgroup.WithContext(context.Background())
sleeps := make([]*exec.Cmd, 3)
sleeps[0] = exec.CommandContext(ctx, "sleep", "100")
sleeps[1] = exec.CommandContext(ctx, "sleep", "100")
sleeps[2] = exec.CommandContext(ctx, "sleep", "notanumber")
for _, s := range sleeps {
  s := s
  eg.Do(func() error {
    return s.Run()
  })
}
return eg.Wait()
```


Question: How to: [⏫](#contents) Monitor Go Runtime metrics with [opentelemetry](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/runtime)

Answer:
These are standard metrics for Go runtime exposed in OpenTelemetry format. Grafana [dashboard](https://github.com/nikolaydubina/grafana-otel-go-runtime). — Google, (dashboard by @nikolaydubina)

```go
import "go.opentelemetry.io/contrib/instrumentation/runtime"
...
runtime.Start()
```
Requirements
```
opentelemetry collector
metrics backend (e.g. prometheus)
dashboard (e.g. grafana)
```


Question: How to: [⏫](#contents) Monitor goroutines with [grmon](https://github.com/bcicen/grmon)

Answer:
Command line monitoring for goroutines. — [@bcicen](https://github.com/bcicen)

```
grmon
```
Requirements
```


Question: How to: [⏫](#contents) Monitor Go processes with [gops](https://github.com/google/gops)

Answer:
Monitoring memory of Go processes, forcing GC, getting version of Go of processes. — Google

```
gops
```

Example
```
983   980    uplink-soecks  go1.9   /usr/local/bin/uplink-soecks
52697 52695  gops           go1.10  /Users/jbd/bin/gops
4132  4130   foops        * go1.9   /Users/jbd/bin/foops
51130 51128  gocode         go1.9.2 /Users/jbd/bin/gocode
```

Requirements
```
go install github.com/google/gops@latest
```


Question: How to: [⏫](#contents) Monitor Go runtime metrics in browser with [live-pprof](https://github.com/moderato-app/live-pprof)

Answer:
This is minimal single binary tool that lets you monitor Go app performance. This can be an attractive alternative for local development to avoid operations overhead of full monitoring setup (e.g. Prometheus, Grafana). — [@clement2026](https://github.com/clement2026)

```
live-pprof 6060
```
Requirements
```
go install github.com/moderato-app/live-pprof@v1
```


Question: How to: [⏫](#contents) Monitor Go runtime metrics in browser with [statsviz](https://github.com/arl/statsviz)

Answer:
This tool exposes HTTP endpoint with charts for Go runtime such as heap, objects, goroutines, GC pauses, scheduler. This is useful drop-in solution for visualization of Go runtime. — [@arl](https://github.com/arl)
Requirements
```
go get github.com/arl/statsviz@latest
```


Question: How to: [⏫](#contents) Auto-Instrument all functions with [go-instrument](https://github.com/nikolaydubina/go-instrument)

Answer:
Automatically instrument all functions with Open Telemetry Spans by code generation. Inserts errors into Spans. — [@nikolaydubina](https://github.com/nikolaydubina)

```
find . -name "*.go" | xargs -I{} go-instrument -app my-service -w -filename {}
```
Requirements
```
go install github.com/nikolaydubina/go-instrument@latest
```


Question: How to: [⏫](#contents) Auto-Instrument all functions with [otelinji](https://github.com/hedhyw/otelinji)

Answer:
Automatically instrument all functions with Open Telemetry Spans by code generation. Inserts errors into Spans. Supports custom templates and can be used for Open Tracing or any custom insertions. — [@hedhyw](https://github.com/hedhyw)

```
otelinji -w -filename input_file.go
otelinji -filename input_file.go > input_file.go
find . -name "*.go" | grep -v "vendor/\|.git/\|_test.go" | xargs -n 1 -t otelinji -w -filename
```
Requirements
```
go install github.com/hedhyw/otelinji/cmd/otelinji@latest
```


Question: How to: [⏫](#contents) Auto-Instrument functions for DataDog with [orchestrion](https://github.com/DataDog/orchestrion)

Answer:
This is official Datadog tool for automatic instrumentation of code. It has very convenient compiler directives for instrumentation. — [@DataDog](https://github.com/DataDog)

```
orchestrion -w ./
```

```go
//dd:span my:tag
func GetSomeData(ctx context.Context) ([]byte, error) {
  ...
```

Requirements
```
go install github.com/datadog/orchestrion@latest
```


Question: How to: [⏫](#contents) Continuous Profiling with [Pyroscope](https://github.com/grafana/pyroscope)

Answer: This tool allows to ingest profiling data from your application. You would need to add integration in your main file that will sample in-process data and send it to Pyroscope. Here are useful resources [blog-go-memory-leaks](https://grafana.com/blog/2023/04/19/how-to-troubleshoot-memory-leaks-in-go-with-grafana-pyroscope/). — Grafana Labs


Question: How to: [⏫](#contents) Run benchmarks

Answer:
Start here. This is the standard tool for benchmarking. It can also do advanced features like mutex profiles. More flags are in Go [documentation](https://pkg.go.dev/cmd/go#hdr-Testing_flags) and `go help testflag`.

```
go test -bench=. -benchmem -benchtime=10s ./...
```

Example
```
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/fpmoney
BenchmarkArithmetic/add_x1-10                     1000000000             0.5 ns/op           0 B/op           0 allocs/op
BenchmarkArithmetic/add_x100-10                     18430124            64.6 ns/op           0 B/op           0 allocs/op
BenchmarkJSONUnmarshal/small-10                      3531835           340.7 ns/op         198 B/op           3 allocs/op
BenchmarkJSONUnmarshal/large-10                      2791712           426.9 ns/op         216 B/op           3 allocs/op
BenchmarkJSONMarshal/small-10                        4379685           274.4 ns/op         144 B/op           4 allocs/op
BenchmarkJSONMarshal/large-10                        3321205           345.8 ns/op         192 B/op           5 allocs/op
PASS
ok      github.com/nikolaydubina/fpmoney    62.744s
```


Question: How to: [⏫](#contents) Table-driven benchmarks

Answer:
Similar to tests, Go supports table-driven benchmarks, which is very helpful for fine gradation of meta-parameters. More details in the Go [blog](https://go.dev/blog/subtests).

```
func benchIteratorSelector(b *testing.B, n int) {
  // ... setup here
  b.ResetTimer()
  for n := 0; n < b.N; n++ {
    err := myExpensiveFunc()
    if err != nil {
      b.Error(err)
    }
  }
}

func BenchmarkIteratorSelector(b *testing.B) {
  for _, q := range []int{100, 1000, 10000, 100000} {
    b.Run(fmt.Sprintf("n=%d", q), func(b *testing.B) {
      benchIteratorSelector(b, q)
    })
  }
}
```

Example
```
BenchmarkIteratorSelector/n=100-10    	  297792	      4265 ns/op	    5400 B/op	      13 allocs/op
BenchmarkIteratorSelector/n=1000-10   	   31400	     38182 ns/op	    9752 B/op	      16 allocs/op
BenchmarkIteratorSelector/n=10000-10  	    3134	    380777 ns/op	   89112 B/op	      24 allocs/op
BenchmarkIteratorSelector/n=100000-10 	     310	   3827292 ns/op	  912410 B/op	      32 allocs/op
```


Question: How to: [⏫](#contents) Align benchmark output

Answer:
Go aligns benchmarks names to longest seen so far. Create file with name that is lexicographically first and has noop benchmark like following.

```go
func BenchmarkNoop(b *testing.B) { b.Run("--------------------------------", func(b *testing.B) {}) }
```

Example
```
$ go test -bench .
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/go-hackers-delight
BenchmarkNoop/---------------------------------16         	1000000000	         0.0000001 ns/op
BenchmarkAbs/basic-16                                     	1000000000	         0.9826 ns/op
BenchmarkAbs/Abs-16                                       	1000000000	         0.9647 ns/op
BenchmarkAbs/Abs2-16                                      	1000000000	         0.9943 ns/op
BenchmarkAbs/Abs3-16                                      	1000000000	         0.9819 ns/op
BenchmarkAbs/Abs4-16                                      	1000000000	         1.003 ns/op
BenchmarkAbs/AbsFastMul-16                                	1000000000	         0.9598 ns/op
BenchmarkAvg/basic-16                                     	973716225	         2.045 ns/op
BenchmarkAvg/AvgFloor-16                                  	602586224	         2.050 ns/op
BenchmarkAvg/AvgCeil-16                                   	582029594	         2.054 ns/op
BenchmarkCycleThree/basic-16                              	767160418	         1.560 ns/op
BenchmarkCycleThree/CycleThreeValues-16                   	438818894	         2.729 ns/op
BenchmarkLeadingZeros/uint32/basic-16                     	1000000000	         0.9419 ns/op
```


Question: How to: [⏫](#contents) Generate benchmark CPU and Memory profiles with `go test`

Answer:
This is useful for identifying most time or memory consuming parts. Recommended to run for single benchmark at a time and with `-count` or `-benchtime` for better accuracy.

```
go test -bench=
-cpuprofile cpu.out -memprofile mem.out ./...
```


Question: How to: [⏫](#contents) Visualize callgraph of profiles with `pprof`

Answer:
Once you generate profiles, visualize them with `pprof`. Both memory and CPU profiles are supported. Many options are available. Refer to the link you get in SVG to how to interpret this graph. More official documentation [blog](https://go.dev/blog/pprof), [pkg-doc](https://pkg.go.dev/net/http/pprof). — official Go team

```
go tool pprof -svg cpu.out > cpu.svg
go tool pprof -svg mem.out > mem.svg
```


Question: How to: [⏫](#contents) Visualize flamegraphs of profiles with `pprof`

Answer:
Latest versions of `pprof` can also render [Flamegraphs](https://www.brendangregg.com/flamegraphs.html) for profiles. Make sure you set `-http` to start webserver. Then it is available in "View > Graph" in at http://0.0.0.0:80. — Google

```
pprof -http=0.0.0.0:80 cpu.out
```
Requirements
```
go install github.com/google/pprof@latest
```


Question: How to: [⏫](#contents) Visualize profiles online

Answer: You can also visualize profiles with online tools are aloso available https://www.speedscope.app (cpu).


Question: How to: [⏫](#contents) :gift: Profile and visualizse (with video) Go profiles through eBPF with [go-profile](https://github.com/benbaker76/go-profile)

Answer:
You can generate profiles throubh eBPF for Go programs. There is a frame export mode that you can use to generate videos. — [@benbaker76](https://github.com/benbaker76)

```
BPF_CFLAGS='-D__TARGET_ARCH_x86' go generate ./cmd/profile/
go run ./cmd/profile -p 2197 100
ffmpeg -framerate 30 -i ./frames/flamegraph%04d.png flamegraph.mp4
```

Example
```
Waiting for stack traces for 1m40s...

    [U] 7f4d99a0112d [unknown]
    [U] 7f4d99a0021d __isoc99_fscanf
    -                htop (2197)
        1
    [K] ffffffff853bd36e do_task_stat
    [K] ffffffff853bd36e do_task_stat
    [K] ffffffff853b70ed proc_single_show
    [K] ffffffff853574a0 seq_read_iter
    [K] ffffffff8535792a seq_read
    [K] ffffffff85326855 vfs_read
    [K] ffffffff85326c2f ksys_read
    [K] ffffffff85f22e55 do_syscall_64
    [K] ffffffff86000124 entry_SYSCALL_64_after_hwframe
    [U] 7f4d99ab27e2 read
    [U] 00000040 [unknown]
```
Requirements
```
follow instructions how to get required headers
```


Question: How to: [⏫](#contents) Get delta between two benchmarks with [benchstat](https://golang.org/x/perf/cmd/benchstat)

Answer:
This is standard way to compare two benchmark outputs. Names of benchmarks should be the same. Generate benchmarks as per usual. You would get multiple tables per dimension. If no output, then pass `-split="XYZ"`. If you do not see `delta`, then pass `-count=2` or more in benchmark generation. It is recommended to have alternative implementations in different packages, to keep benchmark names the same. — official Go team

```
benchstat -split="XYZ" old.txt new.txt
```

Example
```
name                    old time/op    new time/op    delta
JSONUnmarshal/small-10     502ns ± 0%     331ns ± 0%   -33.99%  (p=0.008 n=5+5)
JSONUnmarshal/large-10     572ns ± 0%     414ns ± 0%   -27.64%  (p=0.008 n=5+5)
JSONMarshal/small-10       189ns ± 0%     273ns ± 0%   +44.20%  (p=0.008 n=5+5)
JSONMarshal/large-10       176ns ± 0%     340ns ± 0%   +93.29%  (p=0.008 n=5+5)

name                    old alloc/op   new alloc/op   delta
JSONUnmarshal/small-10      271B ± 0%      198B ± 0%   -26.94%  (p=0.008 n=5+5)
JSONUnmarshal/large-10      312B ± 0%      216B ± 0%   -30.77%  (p=0.008 n=5+5)
JSONMarshal/small-10       66.0B ± 0%    144.0B ± 0%  +118.18%  (p=0.008 n=5+5)
JSONMarshal/large-10       72.0B ± 0%    192.0B ± 0%  +166.67%  (p=0.008 n=5+5)

name                    old allocs/op  new allocs/op  delta
JSONUnmarshal/small-10      6.00 ± 0%      3.00 ± 0%   -50.00%  (p=0.008 n=5+5)
JSONUnmarshal/large-10      7.00 ± 0%      3.00 ± 0%   -57.14%  (p=0.008 n=5+5)
JSONMarshal/small-10        2.00 ± 0%      4.00 ± 0%  +100.00%  (p=0.008 n=5+5)
JSONMarshal/large-10        2.00 ± 0%      5.00 ± 0%  +150.00%  (p=0.008 n=5+5)
```

Requirements
```
go install golang.org/x/perf/cmd/benchstat@latest
```


Question: How to: [⏫](#contents) Benchmark against git commit with [pat/ba](https://github.com/maruel/pat)

Answer:
This tool runs benchmarks and shows delta between git commits. It can also be useful in GitHub Actions. — [@maruel](https://github.com/maruel)

Example
```
$ ba -against HEAD~1
warming up
go test -bench . -benchtime 100ms -count 1 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 1 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
02152d698f7d548c...HEAD~1 (1 commits), 100ms x 2 times/batch, batch repeated 3 times.
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout HEAD~1
go test -bench . -benchtime 100ms -count 2 -run ^$ -cpu 1 ./...
git checkout 02152d698f7d548c
name                  old time/op    new time/op    delta
HashCommand             69.0ns ± 2%    67.7ns ± 2%  -1.91%  (p=0.041 n=6+6)
CLParser                 281µs ± 1%     281µs ± 1%    ~     (p=0.699 n=6+6)
LoadManifest             437ms ± 7%     430ms ± 3%    ~     (p=0.937 n=6+6)
CanonicalizePathBits    85.9ns ± 1%    86.2ns ± 0%    ~     (p=1.000 n=6+6)
CanonicalizePath        83.9ns ± 1%    84.6ns ± 0%    ~     (p=0.058 n=6+6)

name                  old alloc/op   new alloc/op   delta
HashCommand              0.00B          0.00B         ~     (all equal)
CLParser                 164kB ± 0%     164kB ± 0%    ~     (all equal)
LoadManifest             298MB ± 0%     295MB ± 0%  -0.78%  (p=0.002 n=6+6)
CanonicalizePathBits     80.0B ± 0%     80.0B ± 0%    ~     (all equal)
CanonicalizePath         80.0B ± 0%     80.0B ± 0%    ~     (all equal)

name                  old allocs/op  new allocs/op  delta
HashCommand               0.00           0.00         ~     (all equal)
CLParser                 1.64k ± 0%     1.64k ± 0%    ~     (all equal)
LoadManifest             2.61M ± 0%     2.57M ± 0%  -1.71%  (p=0.002 n=6+6)
CanonicalizePathBits      1.00 ± 0%      1.00 ± 0%    ~     (all equal)
CanonicalizePath          1.00 ± 0%      1.00 ± 0%    ~     (all equal)
```

Requirements
```
go install github.com/maruel/pat/cmd/...@latest
```


Question: How to: [⏫](#contents) Continuous benchmarking

Answer: Track how benchmarks change in codebase over time. This is accomplished by running benchmarks for git commits, storing results, and visualizing difference. Running benchmarks can be in GitHub Actions or locally, storage can be in same repository `master` or dedicated branch, or standalone servers. It should be straightforward to setup this manually. Example of GitHub Action [spec](https://github.com/swaggest/rest/blob/master/.github/workflows/bench.yml) and [blog](https://dev.to/vearutop/continuous-benchmarking-with-go-and-github-actions-41ok) from [@vearutop](https://github.com/vearutop), and an example on how it produces a PR [comment](https://github.com/swaggest/rest/pull/88#issuecomment-1271540878).


Question: How to: [⏫](#contents) Continuous benchmarking with [gobenchdata](https://github.com/bobheadxi/gobenchdata)

Answer:
This tool uses `go test -bench` data in GitHub. It runs benchmarks, and uploads it as GitHub Pages for visualization. It is available as GitHub Action [gobenchdata](https://github.com/marketplace/actions/continuous-benchmarking-for-go). This is useful to see benchmark trends. — [@bobheadxi](https://github.com/bobheadxi)
Requirements
```
go install go.bobheadxi.dev/gobenchdata@latest
```


Question: How to: [⏫](#contents) Continuous benchmarking with [benchdiff](https://github.com/willabides/benchdiff)

Answer:
Automates comparing benchmarks with `benchstat` of two git references. It is available as GitHub Action [benchdiff](https://github.com/marketplace/actions/benchdiff) which runs `benchstat` of HEAD vs base branch. This is useful to see how benchmarks change with PRs in CI. — [@WillAbides](https://github.com/WillAbides)
Requirements
```
go install github.com/willabides/benchdiff/cmd/benchdiff
```


Question: How to: [⏫](#contents) Continuous benchmarking with [cob](https://github.com/knqyf263/cob)

Answer:
Automate comparing benchmarks with `benchstat` between `HEAD` and `HEAD^1`. It can be used to block CI pipelines if benchmarks deteriorate. It reports output as text in CLI. This cane be useful in CI or in local development. — [@knqyf263](https://github.com/knqyf263)
Requirements
```
go install github.com/knqyf263/cob@latest
```


Question: How to: [⏫](#contents) Generate live traces with `net/http/trace`

Answer:
This will add endpoints to your your server. If you don't have server running already in your process, you can start one. Then you can point `pprof` tool to this data. For production, hide this endpoint in separate port and path. More details in documentation [trace](https://pkg.go.dev/cmd/trace), [net/http/pprof](https://pkg.go.dev/net/http/pprof).

```
package main

import (
  "log"
  "net/http"
  "net/http/pprof"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
  log.Fatal(http.ListenAndServe(":7777", mux))
}
```

Example
```
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
```


Question: How to: [⏫](#contents) Generate traces with `go test`

Answer:
Produce a trace of execution of tests in package.

```
go test -trace trace.out .
```


Question: How to: [⏫](#contents) View traces with `go tool trace`

Answer:
You can view traces interactively in browser with standard Go tooling. This web tool also shows network blocking profile, synchronization blocking profile, syscall blocking profile, scheduler latency profile.

```
go tool trace trace.out
```


Question: How to: [⏫](#contents) View traces with [gotraceui](https://github.com/dominikh/gotraceui)

Answer:
Gotraceui is a tool for visualizing and analyzing Go execution traces. It is meant to be a faster, more accessible, and more powerful alternative to go tool trace. Unlike go tool trace, Gotraceui doesn't use deprecated browser APIs (or a browser at all), and its UI is tuned specifically to the unique characteristics of Go traces. This tool also recommend by official Go team from Google in their [blog](https://go.dev/blog/execution-traces-2024). — [@dominikh](https://github.com/dominikh)

```
go tool trace trace.out
```
Requirements
```
refer to guideline for requirements for GUI
go install honnef.co/go/gotraceui/cmd/gotraceui@latest
```


Question: How to: [⏫](#contents) View in-process traces with [trc](https://github.com/peterbourgon/trc)

Answer:
This experimental approach illustrates collection of traces, intsrumentation, and visualization. It does not handle distributed traces. Likely useful for special cases or educational or research purposes. — [@peterbourgon](https://github.com/peterbourgon)
Requirements
```
instrument your code with `trc` package
start UI server at port within same process
```


Question: How to: [⏫](#contents) View wallclock traces with [fgtrace](https://github.com/felixge/fgtrace)

Answer:
This tool can be more illustrative of Go traces than standard Go traces. — [@felixge](https://github.com/felixge)

```go
package main

import (
  "net/http"

  "github.com/felixge/fgtrace"
)

func main() {
  http.DefaultServeMux.Handle("/debug/fgtrace", fgtrace.Config{})
  http.ListenAndServe(":1234", nil)
}
```