<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Azhar Momin</title>
    <description>The latest articles on DEV Community by Azhar Momin (@amazingakai).</description>
    <link>https://dev.to/amazingakai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4057790%2F4186a30c-45f2-47e9-a350-38000aaaf472.jpg</url>
      <title>DEV Community: Azhar Momin</title>
      <link>https://dev.to/amazingakai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amazingakai"/>
    <language>en</language>
    <item>
      <title>My LFX Mentorship at OpenTelemetry Has Come to an End</title>
      <dc:creator>Azhar Momin</dc:creator>
      <pubDate>Sun, 06 Sep 2026 18:30:00 +0000</pubDate>
      <link>https://dev.to/amazingakai/my-lfx-mentorship-at-opentelemetry-has-come-to-an-end-267g</link>
      <guid>https://dev.to/amazingakai/my-lfx-mentorship-at-opentelemetry-has-come-to-an-end-267g</guid>
      <description>&lt;p&gt;My LFX Mentorship at OpenTelemetry Go Compile Instrumentation (otelc) has ended. I’ve already written about &lt;a href="https://amazingakai.github.io/posts/my-lfx-mentorship-so-far-and-what-id-tell-future-mentees/" rel="noopener noreferrer"&gt;how I got here and why I applied&lt;/a&gt; and about &lt;a href="https://amazingakai.github.io/posts/building-import-driven-instrumentation-for-otelc/" rel="noopener noreferrer"&gt;the technical work&lt;/a&gt;, so this one’s just a short summary and reflection.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shipped
&lt;/h2&gt;

&lt;p&gt;The biggest piece of work was import-driven instrumentation selection, covered in &lt;a href="https://amazingakai.github.io/posts/building-import-driven-instrumentation-for-otelc/" rel="noopener noreferrer"&gt;my last post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The other piece, registry-backed integration search through the &lt;a href="https://github.com/open-telemetry/opentelemetry-ecosystem-explorer" rel="noopener noreferrer"&gt;OpenTelemetry Ecosystem Explorer&lt;/a&gt;, is still in progress. We’re also migrating otelc’s instrumentations into a separate contrib repo, which should make this kind of work easier to build on. I’ll write about these in a future post.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I gained
&lt;/h2&gt;

&lt;p&gt;Getting better at communication was one of the reasons I applied. I was always fine talking async over GitHub, comments, reviews, PR descriptions, but I didn’t have much confidence in live SIG meetings or calls. Weekly SIG meetings and regular syncs with my mentors fixed that.&lt;/p&gt;

&lt;p&gt;I’m also a lot more interested in observability than when I started. I want to keep exploring the OpenTelemetry ecosystem, mainly around Rust and eBPF. I’m graduating in about a year, and this mentorship is a big part of why I’m now seriously looking at observability as a career direction.&lt;/p&gt;

&lt;p&gt;The project got a lot of traction during my mentorship, we submitted two project proposals for the next LFX term, so alongside my own contributions I reviewed many PRs. Reading other people’s approaches and review discussions taught me things faster than writing my own code ever did.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;I’m mentoring a project myself next term, co-mentoring with &lt;a href="https://github.com/txabman42" rel="noopener noreferrer"&gt;Xabier Martinez&lt;/a&gt;. I’m also planning to stay in touch with my mentors and everyone else I’ve gotten to know through this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you
&lt;/h2&gt;

&lt;p&gt;Thanks to my mentors, and to the OpenTelemetry and CNCF community, for everything over the past few months. ❤️&lt;/p&gt;

</description>
      <category>lfx</category>
      <category>opentelemetry</category>
      <category>opensource</category>
      <category>mentorship</category>
    </item>
    <item>
      <title>Building Import-Driven Instrumentation for otelc</title>
      <dc:creator>Azhar Momin</dc:creator>
      <pubDate>Wed, 12 Aug 2026 06:30:00 +0000</pubDate>
      <link>https://dev.to/amazingakai/building-import-driven-instrumentation-for-otelc-3j1</link>
      <guid>https://dev.to/amazingakai/building-import-driven-instrumentation-for-otelc-3j1</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/amazingakai/my-path-to-lfx-mentorship-and-some-advice-for-future-mentees-2l0k"&gt;my last post&lt;/a&gt;, I wrote about how I got into OpenTelemetry Go Compile Instrumentation and applied to LFX Mentorship. This one is about the actual work, what I built, the bugs I ran into, and how I fixed them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why otelc specifically?
&lt;/h2&gt;

&lt;p&gt;I’m interested in both low-level tooling and observability, and otelc sits right at the intersection of the two. That’s really what pulled me toward this project instead of OpenTelemetry in general.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is otelc, briefly?
&lt;/h2&gt;

&lt;p&gt;otelc instruments Go code at compile time. Instead of requiring developers to manually instrument their code, otelc rewrites the program during compilation so that instrumentation is inserted automatically. The rest of this post assumes a little bit of that context, so here’s the short version before I get into what I actually worked on.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I worked on
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Import-driven instrumentation selection
&lt;/h3&gt;

&lt;p&gt;otelc ships with a built-in set of instrumentations, each made up of modules and rule files. But there was no good way to bring in third-party instrumentations easily, and no way to disable a built-in instrumentation at compile time (you could only toggle them at runtime).&lt;/p&gt;

&lt;p&gt;This came up in a SIG meeting, and was tracked in &lt;a href="https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/issues/567" rel="noopener noreferrer"&gt;this issue&lt;/a&gt;. Orchestrion, Datadog’s own compile-time instrumentation tool for Go, already had a solution: an &lt;code&gt;orchestrion.tool.go&lt;/code&gt; file that developers could use to declare instrumentation explicitly. We used that as a starting point and built something similar for otelc.&lt;/p&gt;

&lt;p&gt;The mechanism works like this: otelc looks for a file (&lt;code&gt;otel.instrumentation.go&lt;/code&gt;, or &lt;code&gt;otelc.tool.go&lt;/code&gt; as an alias) containing a list of blank imports. This file isn’t included in the actual build (it’s marked with a &lt;code&gt;tools&lt;/code&gt; build tag, following the standard &lt;code&gt;tools.go&lt;/code&gt; convention), but Go still tracks its imports in &lt;code&gt;go.mod&lt;/code&gt;. otelc reads this file before building, loads the imported packages using &lt;code&gt;golang.org/x/tools/go/packages&lt;/code&gt;, and scans each package’s directory for rule files (&lt;code&gt;otelc.yaml&lt;/code&gt;, &lt;code&gt;*.otelc.yaml&lt;/code&gt;) or another &lt;code&gt;otel.instrumentation.go&lt;/code&gt;, allowing instrumentation packages to bundle together other instrumentation packages. Those rule files define how to instrument that package.&lt;/p&gt;

&lt;p&gt;Here’s roughly what one of these files looks like in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build tools&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"go.opentelemetry.io/otelc/instrumentation/net/http/client"&lt;/span&gt;
 &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"..."&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbml0k2fblc1uxd4pmlaf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbml0k2fblc1uxd4pmlaf.webp" alt="OpenTelemetry Go Compile Instrumentation Import-Driven Instrumentation Flow" width="800" height="943"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The naming itself was already decided in a UX design document from before I joined the project, so that part was settled. I’d originally written this as a single PR, but it ended up being around 5,000 lines, which was far too large to review properly. Reviewers asked me to split it into smaller PRs, so I did. During that process, one review comment asked for an integration test covering a recursive instrumentation path, where one &lt;code&gt;otel.instrumentation.go&lt;/code&gt; file references another. Writing that test surfaced a real bug: otelc was only looking for hook code files inside its own embedded bundle, not in packages loaded from external import paths. If that comment hadn’t come up, this bug might have gone unnoticed for a while. I fixed it by updating otelc to load hook code through &lt;code&gt;golang.org/x/tools/go/packages&lt;/code&gt; as well. The implementation landed across a couple of PRs: the hook loading fix in &lt;a href="https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pull/617" rel="noopener noreferrer"&gt;#617&lt;/a&gt;, followed by the core import-driven instrumentation support in &lt;a href="https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pull/612" rel="noopener noreferrer"&gt;#612&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The initInstrumentation deadlock
&lt;/h3&gt;

&lt;p&gt;Every instrumentation in otelc followed the same rough pattern: lazily set up the OTel SDK (if it wasn’t already running) and start runtime metrics, guarded by a &lt;code&gt;sync.Once&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This caused a deadlock. Here’s what happened: when a user’s code called &lt;code&gt;grpc.NewClient&lt;/code&gt;, the gRPC instrumentation hook would call &lt;code&gt;initInstrumentation&lt;/code&gt;, which runs inside a &lt;code&gt;sync.Once.Do&lt;/code&gt;. If the user had their OTLP exporter configured to use gRPC, the SDK setup inside that same &lt;code&gt;Once.Do&lt;/code&gt; would itself call &lt;code&gt;grpc.NewClient&lt;/code&gt;, which tried to call &lt;code&gt;initInstrumentation&lt;/code&gt; again, re-entering the same &lt;code&gt;Once.Do&lt;/code&gt; block that hadn’t finished running yet. That’s a deadlock.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Famazingakai.github.io%2Fimages%2Fbuilding-import-driven-instrumentation-for-otelc%2Fotelc-initinstrumentation-deadlock-sequence-dark.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Famazingakai.github.io%2Fimages%2Fbuilding-import-driven-instrumentation-for-otelc%2Fotelc-initinstrumentation-deadlock-sequence-dark.webp" alt="OpenTelemetry Go Compile Instrumentation initInstrumentation Deadlock Sequence" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first fix was simpler than it should have been: check the value of &lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt; and skip instrumentation for any &lt;code&gt;grpc.NewClient&lt;/code&gt; call pointed at that endpoint. That worked for the obvious case, but it broke down as soon as the two values didn’t match exactly, since the values could point at the same collector without matching as strings at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;endpoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://collector-localhost:4317"&lt;/span&gt;
&lt;span class="py"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"localhost:4317"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This kept happening because I was relying on dumb string comparison to detect whether the two calls pointed at the same target. Instead of trying to make that comparison smarter, I took a different approach.&lt;/p&gt;

&lt;p&gt;The fix was to stop having every instrumentation independently lazy-init the SDK. Instead, I moved that startup logic out into a single injected rule that runs once in the user’s main package, before any instrumentation hook runs. Every hook can now assume the SDK is already set up by the time it runs, so there’s no endpoint comparison to get wrong in the first place. It also meant third-party rules don’t need to follow the old init pattern at all, they can simply assume the SDK is already available, which fit nicely with the import-driven instrumentation work happening around the same time. Users who want to bring their own tracer or meter provider can also remove this rule and wire up their own. The implementation landed in &lt;a href="https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pull/625" rel="noopener noreferrer"&gt;#625&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  otelc pin and auto-pinning
&lt;/h3&gt;

&lt;p&gt;The second thing I worked on was the &lt;code&gt;otelc pin&lt;/code&gt; command, which generates an &lt;code&gt;otel.instrumentation.go&lt;/code&gt; file based on a user’s dependency graph, inspired by Orchestrion’s own &lt;code&gt;pin&lt;/code&gt; command. Orchestrion’s version points to a single package that bundles every integration together. I changed this so &lt;code&gt;otelc pin&lt;/code&gt; looks at the user’s actual dependencies and infers which instrumentations are relevant, rather than pulling in everything.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;otelc pin&lt;/code&gt; also keeps the generated file clean by automatically removing imports that don’t resolve to any rule files (or other &lt;code&gt;otel.instrumentation.go&lt;/code&gt; files). The result is an explicit list of the instrumentations that are actually relevant to the project.&lt;/p&gt;

&lt;p&gt;Auto-pinning was also mentioned in the original issue, but initially I wasn’t convinced it was necessary. If a project didn’t have an &lt;code&gt;otel.instrumentation.go&lt;/code&gt; file, otelc could simply fall back to its default instrumentations. Generating a temporary file just to represent that default set seemed like an unnecessary extra step.&lt;/p&gt;

&lt;p&gt;While testing otelc against a project using an older version of gRPC, I ran into another problem. I already had a fix open for that problem, but auto-pinning addressed its underlying cause in a much cleaner way.&lt;/p&gt;

&lt;p&gt;At the time, otelc’s build process matched instrumentation rules first, then added the matched instrumentation modules to &lt;code&gt;go.mod&lt;/code&gt; and ran &lt;code&gt;go mod tidy&lt;/code&gt;. That dependency resolution could bump the project’s gRPC version. The instrumentation rules had already been selected against the old version, though, so otelc could end up building against a dependency graph different from the one it had used to decide which rules to apply which resulted in the build failing.&lt;/p&gt;

&lt;p&gt;My original fix was to run the setup process in multiple passes until the dependency graph stopped changing. It worked, but auto-pinning turned out to solve the same problem much more cleanly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;otelc go build&lt;/code&gt; now generates a temporary &lt;code&gt;otel.instrumentation.go&lt;/code&gt; early when the user hasn’t provided one. Dependencies are resolved and added to &lt;code&gt;go.mod&lt;/code&gt; as part of that pinning phase, before rule matching happens. By the time otelc selects instrumentation rules, it’s looking at the dependency versions that will actually be used for the build. The setup phase that follows no longer needs to modify the dependency graph, so the selected rules stay valid.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpzm14mw9c0fxf99ihslt.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpzm14mw9c0fxf99ihslt.webp" alt="OpenTelemetry Go Compile Instrumentation Auto-Pinning Before/After" width="799" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This also gives us a cleaner path toward registry-backed integration search. If otelc eventually discovers compatible instrumentations from the &lt;a href="https://github.com/open-telemetry/opentelemetry-ecosystem-explorer" rel="noopener noreferrer"&gt;OpenTelemetry Ecosystem Explorer&lt;/a&gt; registry, the same pinning step can resolve those integrations and their dependencies before rule matching, rather than requiring the rest of the build pipeline to care where an instrumentation came from. I talk more about that idea in the registry-backed integration section below.&lt;/p&gt;

&lt;p&gt;One rough edge that’s still open is that &lt;code&gt;otelc pin&lt;/code&gt; currently adds &lt;code&gt;replace&lt;/code&gt; directives pointing to local paths in &lt;code&gt;go.mod&lt;/code&gt;, which makes checking the generated file into version control awkward. Decoupling instrumentations from the tool itself, also described below, should fix that. The initial implementation landed in &lt;a href="https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pull/655" rel="noopener noreferrer"&gt;#655&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;A few things I’m looking at for the rest of the mentorship:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Decoupling instrumentations from otelc’s embedded bundle.&lt;/strong&gt; Right now, instrumentation packages are embedded directly into the otelc binary. That means adding a new instrumentation requires a new release of the tool, even if it’s otherwise fully compatible. Decoupling this would also let us build a proper dependency graph between instrumentations (for example, automatically pulling in a runtime/GLS instrumentation whenever the OTel SDK instrumentation is used), and would let users check reproducible &lt;code&gt;otel.instrumentation.go&lt;/code&gt; files into their own repos without local path replaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Registry-backed integration search.&lt;/strong&gt; Instead of only looking at the embedded bundle, otelc could look up compatible instrumentations through the &lt;a href="https://github.com/open-telemetry/opentelemetry-ecosystem-explorer" rel="noopener noreferrer"&gt;OpenTelemetry Ecosystem Explorer&lt;/a&gt; registry, which would let third-party instrumentations get picked up automatically once published there. This is currently being researched, see &lt;a href="https://github.com/open-telemetry/opentelemetry-ecosystem-explorer/issues/916" rel="noopener noreferrer"&gt;this issue&lt;/a&gt; for the open questions around how Go compile-time instrumentations should be represented there and how otelc would consume that data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supporting &lt;code&gt;.otel.yml&lt;/code&gt; files.&lt;/strong&gt; Similar in spirit to &lt;code&gt;otel.instrumentation.go&lt;/code&gt;, but without tracking dependencies in &lt;code&gt;go.mod&lt;/code&gt;. Useful for customizing instrumentations without wanting them tracked in version control, though it won’t produce fully reproducible builds.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;The work described here went through a lot of review. Thanks to &lt;a href="https://github.com/kakkoyun" rel="noopener noreferrer"&gt;Kemal Akkoyun&lt;/a&gt; for raising the original issue that led to import-driven instrumentation selection, and to both &lt;a href="https://github.com/kakkoyun" rel="noopener noreferrer"&gt;Kemal&lt;/a&gt; and &lt;a href="https://github.com/darccio" rel="noopener noreferrer"&gt;Dario Castañé&lt;/a&gt; for reviewing the PRs linked throughout this post, including the review comment that led me to the recursive-instrumentation bug. Thanks also to everyone else in the OpenTelemetry Go Compile Instrumentation community who reviewed and discussed this work along the way.&lt;/p&gt;

</description>
      <category>lfx</category>
      <category>opentelemetry</category>
      <category>go</category>
      <category>observability</category>
    </item>
    <item>
      <title>My Path to LFX Mentorship, and Some Advice for Future Mentees</title>
      <dc:creator>Azhar Momin</dc:creator>
      <pubDate>Fri, 24 Jul 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/amazingakai/my-path-to-lfx-mentorship-and-some-advice-for-future-mentees-2l0k</link>
      <guid>https://dev.to/amazingakai/my-path-to-lfx-mentorship-and-some-advice-for-future-mentees-2l0k</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl25qquexx12jahwlvwez.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl25qquexx12jahwlvwez.webp" alt="OpenTelemetry Go Compile Instrumentation Hero" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I got here
&lt;/h2&gt;

&lt;p&gt;I was building a Discord minigame as a side project in Python. It grew bigger than I expected, and it started slowing down, partly due to code I could’ve written better. Eventually I decided to rewrite it in Go, mostly to see how much its concurrency model would help.&lt;/p&gt;

&lt;p&gt;Separately, I realized that whatever language I ended up in, I wanted real visibility into what the bot was actually doing, not just something that told me when it crashed. So I tried instrumenting things manually, and ran into two problems almost immediately. First, I didn’t really know what to instrument. Second, even following the docs, there was so much boilerplate involved that I nearly gave up on the whole idea.&lt;/p&gt;

&lt;p&gt;That’s what pushed me toward auto-instrumentation, mostly as a way to avoid the boilerplate. At the time, though, I was more interested in learning how to instrument things properly than in auto-instrumentation itself, that appreciation came later.&lt;/p&gt;

&lt;p&gt;While looking into zero-code instrumentation solutions, I came across &lt;a href="https://www.cncf.io/blog/2025/02/27/alibaba-datadog-and-quesma-join-forces-on-go-compile-time-instrumentation/" rel="noopener noreferrer"&gt;this old blog post&lt;/a&gt; announcing the new &lt;a href="https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation" rel="noopener noreferrer"&gt;OpenTelemetry Go Compile Instrumentation&lt;/a&gt; project. One of the most appealing reasons for me to contribute was that there was scope for adding new instrumentations, a learning chance for me since I didn’t know much about observability yet. The compiler-level part also mattered to me, I already liked that kind of low-level work. On top of that, I’d separately been looking for a CNCF project to contribute to. I introduced myself in the project’s Slack, asked some questions, and my first real contribution was auto-instrumentation for &lt;code&gt;k8s.io/client-go&lt;/code&gt;, though there were a couple of smaller ones before that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before this: GSoC @ KDE
&lt;/h2&gt;

&lt;p&gt;This wasn’t my first mentorship. In 2025, I was a GSoC mentee at KDE, working on integrating KDE libraries into OSS-Fuzz under the guidance of &lt;a href="https://invent.kde.org/aacid" rel="noopener noreferrer"&gt;Albert Astals Cid&lt;/a&gt;. At the time, I was a total newbie to open source. That period taught me the ropes, both technically and in terms of how contributing to a real project actually works. I’ve written about that in more detail separately (&lt;a href="https://amazingakai.github.io/posts/gsoc-2025-expanding-oss-fuzz-integration-across-kde-libraries" rel="noopener noreferrer"&gt;link&lt;/a&gt;), and it’s worth mentioning here because it’s a big part of why I felt ready to jump into OTel later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Mentorship again?
&lt;/h2&gt;

&lt;p&gt;Two reasons, really.&lt;/p&gt;

&lt;p&gt;The first was that I wanted to get better at communicating. LFX comes with weekly SIG meetings and regular meetings with my mentors, &lt;a href="https://github.com/kakkoyun" rel="noopener noreferrer"&gt;Kemal Akkoyun&lt;/a&gt; and &lt;a href="https://github.com/darccio" rel="noopener noreferrer"&gt;Dario Castañé&lt;/a&gt;. Having to regularly explain what I’ve been working on to people who know the project well has been good practice, especially since it isn’t something that comes naturally to me.&lt;/p&gt;

&lt;p&gt;The second was that I wanted to go deeper into observability and OpenTelemetry specifically, and get better at Go along the way. We’re still in the middle of the mentorship, but so far it’s been exactly what I was hoping for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advice for future mentees
&lt;/h2&gt;

&lt;p&gt;A few things that I think mattered, based on my own experience going through this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contributing is more than opening PRs.&lt;/strong&gt; Looking back at what actually helped my application, joining community discussions, opening issues when I found something worth raising, reviewing other people’s PRs, and sharing ideas even when I wasn’t sure they’d go anywhere all mattered just as much as the code I wrote. Mentors and maintainers see all of that, not just your commit history.&lt;/p&gt;

&lt;p&gt;Reviewing other people’s PRs ended up helping me far more than I expected. Reading different approaches, following review discussions, and seeing why maintainers asked for certain changes taught me things I wouldn’t have learned nearly as quickly by only writing my own code.&lt;/p&gt;

&lt;p&gt;Consistency also matters more than volume. You don’t need dozens of PRs to stand out. Showing up regularly, staying involved in discussions, attending meetings when you can, and gradually becoming part of the community leaves a much stronger impression than trying to maximize your contribution count over a few weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be genuine about why you’re there.&lt;/strong&gt; From what I’ve seen, it’s fairly easy for mentors and maintainers to tell the difference between someone who’s actually excited about a project and someone who’s mainly interested in the resume line. You can want both, a career boost and genuine interest at the same time, but if the interest isn’t real, it tends to show once the work gets less glamorous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t disappear if you’re not selected.&lt;/strong&gt; LFX mentorship slots are limited, not getting selected doesn’t say anything about your ability. If you were seriously contributing during the application period, you already learned something real, keep using it. That doesn’t stop mattering just because one specific mentorship round didn’t go your way. You can keep contributing to the project on your own, and there’s always a next round.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t hesitate to ask.&lt;/strong&gt; Whether it’s a basic question about the codebase, something you think might be obvious, or just wanting to double check you’re on the right track, ask. I did this myself when I first joined the project’s Slack, and no one made me feel bad about it. Most maintainers would rather answer a simple question early than review a PR that went in the wrong direction because you guessed instead of asking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On using AI tools.&lt;/strong&gt; I do use AI tools regularly, but where and how varies. For code, I use it sometimes, mostly for parts I already understand well, where I’m confident I could write it myself but don’t need to grind through it by hand to learn something new. Where I use it a lot more is research and understanding things, I reach for an LLM over Google search these days because it explains things faster than digging through search results and docs myself.&lt;/p&gt;

&lt;p&gt;Wherever I use it, I double check everything it gives me. I review answers against the actual source, and I review AI-assisted code multiple times before submitting it.&lt;/p&gt;

&lt;p&gt;Reviewers are volunteering their time, so submitting unreviewed AI-generated code doesn’t just leave a bad impression, it’s disrespectful. Make sure you’re following whatever AI usage guidelines the project you’re contributing to has. Also question AI-generated code critically: ask why something was done a certain way, whether it’s actually needed, read through the surrounding code, and check if there’s a simpler solution.&lt;/p&gt;

&lt;p&gt;More generally, whether code comes from AI, Stack Overflow, or another contributor, you’re the one submitting it. Make sure you understand it well enough to explain every part of it during review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;This mentorship also convinced me I want to be on the other side of it. I’ll be mentoring a project myself in the next LFX term, co-mentoring with &lt;a href="https://github.com/txabman42" rel="noopener noreferrer"&gt;Xabier Martinez&lt;/a&gt;. You can check out the project &lt;a href="https://mentorship.lfx.linuxfoundation.org/project/3db981bf-404b-4c8e-96f8-b0433688e8cf" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I’m looking forward to it, partly because I want to try being the kind of mentor Kemal, Dario, and Albert have been for me. I’ll write more about the mentorship itself once it wraps up, and separately about the actual technical work I did on otelc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;Thanks to my mentors, &lt;a href="https://github.com/kakkoyun" rel="noopener noreferrer"&gt;Kemal Akkoyun&lt;/a&gt; and &lt;a href="https://github.com/darccio" rel="noopener noreferrer"&gt;Dario Castañé&lt;/a&gt;, for their guidance so far during the mentorship. I’d also like to thank &lt;a href="https://github.com/txabman42" rel="noopener noreferrer"&gt;Xabier Martinez&lt;/a&gt;, who was one of the first maintainers I interacted with on the project, along with everyone else in the OpenTelemetry Go Compile Instrumentation community for the reviews, discussions, and feedback along the way.&lt;/p&gt;

</description>
      <category>lfx</category>
      <category>opentelemetry</category>
      <category>opensource</category>
      <category>mentorship</category>
    </item>
  </channel>
</rss>
