$ show nikolaydubina/go-instrument
go-instrument is a CLI tool that automatically instruments Go source files with OpenTelemetry trace spans. It parses Go AST, identifies functions that accept a `context.Context` parameter, and inserts span creation, defer, and optional error recording statements. It handles various edge cases: anonymous functions, build constraints (ignore/exclude), generated files, custom context/error parameter names, already-instrumented functions, and preserves original line numbers for panic stack traces via compiler directives. The tool is implemented as a reusable library with a clear separation between the generic AST processing engine (`processor` package) and the specific instrumentation strategy (`instrument` package), allowing custom instrumenters. The CLI frontend is minimal; the core logic is in the `processor` and `instrument` packages and is cleanly abstracted via an `Instrumenter` interface. The codebase is well-tested, includes fuzz testing, and uses current Go tooling.
The LLM identified 4 files worth highlighting for reuse:
Core AST processor that walks a parsed Go file, identifies functions and methods with context.Context parameters, delegates instrument statement generation to an `Instrumenter` interface, and collects patches. Demonstrates clean separation of concerns: the processor knows nothing about OpenTelemetry, only about Go AST structure. It handles build constraints, detects already-instrumented functions, and correctly identifies context and error parameters (including custom names and anonymous contexts). The `Instrumenter` interface and `BasicSpanName` function are reusable patterns for any code instrumentation tool.
Generic AST patching mechanism that inserts statement blocks at specific positions in a parsed file and rewrites the source. It handles sorting patches by position to avoid corruption, and optionally inserts `/*line*/` directives to preserve original line numbers in panics. The `cleanupLineDirectives` function demonstrates careful whitespace handling. This component is self-contained and could be extracted into a standalone library for any Go source code transformation that requires surgical AST modifications with line number preservation.
Parses Go build constraint comments (//go:build and // +build) to detect ignore/exclude directives. Used by the processor to skip files that should not be instrumented. Well-encapsulated with its own type and tests. Demonstrates proper use of the `go/build/constraint` standard library. Could be reused in any tool that needs to respect build constraints when processing Go files.
Concrete implementation of the `Instrumenter` interface that generates OpenTelemetry-specific AST nodes: span start, defer span.End, and optional error status/recording. It constructs AST expressions and statements manually (not using code generation from strings). Handles both error and non-error cases, correctly flags required imports. Shows craft in working with Go AST to produce correct, idiomatic instrumentation code. Can be used as a reference or modified for other OpenTelemetry configurations.