The OpenTelemetry Collector Builder (OCB) in OpenTelemetry

The OpenTelemetry Collector Builder (OCB) in OpenTelemetry

A complete, plain-English guide to the tool that lets you assemble your very own OpenTelemetry Collector, with exactly the pieces you need and nothing more, and to the habits that keep a custom Collector safe, small and maintainable.

Imagine you are packing for a trip. The shop sells a huge ready-made suitcase that already contains clothes for every climate, a tent, a snorkel, three kinds of shoes and a winter coat. It is convenient, because you never have to think, but it is heavy, expensive to carry, and most of what is inside you will never use. Or you could pick a small bag and pack only what your trip needs. You spend a little time choosing, and in return you travel light, you know exactly what you are carrying, and nothing surprising is hiding in the corners.

The OpenTelemetry Collector offers the same choice. You can take a ready-made version that includes a large collection of components, or you can build a version that contains only the receivers, processors and exporters your system really uses. The tool that makes the second option possible is called the OpenTelemetry Collector Builder, usually shortened to OCB. In this tutorial we will explain what OCB is, how it works, how to use it well, and how to avoid the traps that catch teams who build their own Collector for the first time.

1Why Would Anyone Build Their Own Collector?

Before learning the tool, it helps to understand the problem it solves.

The OpenTelemetry Collector is a program that receives telemetry such as traces, metrics and logs, optionally changes it, and sends it onward to storage and analysis systems. It does this through small building blocks called components. A receiver accepts data, a processor transforms it, and an exporter sends it away. The project offers hundreds of such components, covering an enormous range of technologies, from popular databases and cloud services to message systems and monitoring formats.

No single organisation uses all of them. A typical company needs perhaps a handful of receivers, a few processors and one or two exporters. If every Collector in the company carries hundreds of unused components, several things happen quietly. The program file is larger than it needs to be, which slows downloads and container startups. More code means more places where a security flaw can hide. More dependencies mean more updates to track. And when something goes wrong, there is more to search through.

100s
of components exist in the wider Collector ecosystem
~10
components a typical team actually needs
1 tool
OCB turns a short list into a custom Collector
Simple Analogy

Think of a restaurant that offers a thousand dishes versus a small café with a menu of ten. The big restaurant needs a giant kitchen, a large staff and a huge stock of ingredients, and some of those ingredients go stale unnoticed. The small café keeps a short list of fresh ingredients and knows every one by heart. OCB lets you run the small café version of the Collector.

i
Good to know

Building your own Collector is optional. Many teams happily run an official ready-made version. OCB becomes valuable when you need a smaller binary, a tighter security footprint, a component that is not in any official version, or full control over exactly what runs in production.

2The Vocabulary You Need First

Each term below comes with what it is, why it exists, and a picture to hold in your head.

Term 1

Collector

The program that receives, processes and forwards telemetry. Think of a sorting centre for observability data.

Term 2

Component

One building block inside the Collector, such as a receiver or exporter. Each does one specific job.

Term 3

Distribution

A particular bundle of components packaged as one runnable Collector. Like an edition of a book with certain chapters included.

Term 4

OCB

The OpenTelemetry Collector Builder, a tool that creates a distribution from a list you provide.

Term 5

Manifest

The short text file in which you describe your distribution: its name and the components you want. It is OCB’s shopping list.

Term 6

Module

A packaged unit of Go code with an address and a version. Every component lives in a module that OCB downloads.

Term 7

Go

The programming language the Collector is written in. OCB uses the Go toolchain to compile your distribution.

Term 8

Binary

The final single executable file you run. It contains every component you chose, ready to start.

Term 9

Core and contrib

Core holds the essential components. Contrib is a large community-maintained collection of additional ones.

Term 10

Connector

A special component that acts as an exporter at the end of one pipeline and a receiver at the start of another.

Term 11

Extension

A helper that adds capabilities beyond data handling, such as health checks, authentication or storage.

Term 12

Provider

A component that tells the Collector where to read its configuration from, such as a file or an environment variable.

!
Common confusion

OCB is not the Collector. OCB is a factory that builds Collectors. The Collector you produce is a separate program that runs on its own, and OCB is no longer needed while it runs.

3The Ready-Made Distributions You Can Choose Instead

OCB is one of several ways to get a Collector, so let us see where it sits among the options.

The OpenTelemetry project publishes several official distributions. The core distribution contains the essential components and is deliberately small. The contrib distribution adds a very large set of extra receivers, processors, exporters and extensions, contributed by the wider community. There is also a variant tuned for Kubernetes environments, one focused on the OpenTelemetry protocol, and a specialised variant for profiling with eBPF technology. Each distribution lists its components in a manifest file in the project’s repositories.

Beyond the official ones, many vendors publish their own distributions. Cloud providers and observability companies package the Collector with the components that work best with their platforms. The OpenTelemetry project lists these as community resources but does not validate or endorse them, so teams choosing a vendor distribution should read the vendor’s own support and security statements.

OptionWhat you getStrengthWeakness
Official core distributionA small set of essential componentsSmall and focusedMissing many integrations
Official contrib distributionA very large set of community componentsAlmost everything is available at onceLarge, with many components you will never use
Other official variantsSets tuned for Kubernetes, the OpenTelemetry protocol, or eBPF profilingGood starting points for those environmentsFixed choices that may not match your needs exactly
Vendor distributionA bundle tuned to one vendor’s platformSupport and convenience from the vendorNot endorsed by the project, tied to the vendor’s choices
Custom distribution built with OCBExactly the components you listSmallest, most controlled, fully yoursYou own the build, updates and security patching
Simple Analogy

This is like buying a computer. You can buy a ready-made model, a model sold by a particular brand with its own extras, or you can assemble one yourself from chosen parts. Self-assembly gives the best fit and the tightest control, but you are also the one who repairs it.

4The Core Idea in One Page

The whole workflow is a short chain with five links.

1

Decide what you need

List which receivers, processors, exporters, extensions and connectors your Collector must contain, based on your real pipelines.

2

Describe it in a manifest

Write a short text file that names your distribution and lists each chosen component with its location and version.

3

Let OCB generate the code

OCB reads the manifest and produces a small Go project that wires every chosen component together.

4

Compile it

OCB runs the Go toolchain to download the components and compile everything into one executable file.

5

Run and deliver it

You run the binary like any other Collector, or package it into a container image for your platform.

“Pick the parts, write them down, and let the builder do the assembly.”

Notice how little you must write. You do not write Go code for the standard case. You write a list, and OCB turns the list into a working program. That is the whole promise of the tool: turn a short, readable description into a repeatable build.

5What OCB Actually Does Behind the Scenes

Understanding the machinery removes the mystery and helps when something goes wrong.

OCB is a command-line program. When you run it with your manifest, it performs two broad jobs. First it generates source code: a small Go project containing a main program, a file that registers each component you listed, and the module files that record which versions of everything are needed. Second it compiles that project by calling the Go toolchain, which downloads the listed components from their module addresses and links everything into a single executable.

Because the output includes both the generated source and the finished binary, you can inspect exactly what was assembled. This is useful for debugging, for security reviews, and for developers who want to build their own components and test them inside a real Collector.

flowchart LR
    M["Manifest file: your component list"] --> O["OCB reads and validates it"]
    O --> G["Generate Go project: main, components, module files"]
    G --> D["Go toolchain downloads component modules"]
    D --> C["Compile and link"]
    C --> B["Single custom Collector binary"]
        
FIG 1 — From manifest to binary: what OCB does when you run it
Simple Analogy

Think of a build-your-own-furniture shop. You choose the pieces from a catalogue and fill out an order form. The shop cuts the parts, drills the holes and assembles the item for you. You never touch a saw, but you can still open it up to see how it was put together. The manifest is the order form and OCB is the workshop.

i
Two useful switches

OCB can be told to generate the code without compiling it, or to compile code that already exists. Teams use the first to inspect or modify generated code, and the second to repeat builds from reviewed source.

6Getting OCB onto Your Machine

Installation is simple, but there is one prerequisite that surprises beginners.

OCB is distributed as a ready-to-run executable for the common platforms: Linux on both Intel-style and ARM processors, macOS, and Windows. On macOS it can also be installed through the popular package manager Homebrew. For other platforms you download the correct file from the project’s releases page, make it executable, and run the help command to confirm that it works.

The surprise is that OCB itself does not contain a compiler. To compile your distribution, OCB calls the Go toolchain, so Go must be installed on the machine that runs OCB. The project’s repository states which Go versions are compatible, and it is wise to check this before your first build, since a mismatch can produce confusing errors.

1

Install a compatible Go toolchain

Check the repository for the supported version range, then install Go using your platform’s usual method.

2

Download the OCB release

Choose the file that matches your operating system and processor type, and prefer a release whose version matches the Collector version you plan to build.

3

Make it executable and check it

Give the file permission to run, then ask it for its help text. If the help appears, installation worked.

!
Common mistake

Downloading whichever OCB release is newest without checking that it matches the component versions in your manifest. The builder version and the component versions are meant to move together, and we will see why in a later chapter.

7The Manifest: Your Shopping List

Everything OCB does is driven by one small text file, so it pays to understand its parts.

The manifest is a plain text file in a simple, human-readable format. It has a handful of sections. One section, called dist, describes the distribution itself. Several sections list components, one per kind. Two further sections cover where configuration is read from and how modules may be substituted. You only include the sections you need.

Section

dist

Describes the distribution as a whole: its name, version, description and where the output goes. It controls how generation and compilation behave.

Section

receivers

The doors through which telemetry enters. List only the protocols and sources you will actually accept.

Section

processors

The steps that change data in flight, such as batching, filtering and memory protection.

Section

exporters

The doors through which telemetry leaves, towards backends or other Collectors.

Section

extensions

Helpers like health checks, authentication and persistent storage that sit beside the data path.

Section

connectors

Components that link one pipeline to another, for example turning traces into metrics.

Section

providers

Define where configuration can be read from, such as files or environment variables.

Section

replaces

Lets you substitute one module for another, which is useful when developing or patching components.

i
Manifest versus runtime configuration

The manifest decides which components exist in the binary. A separate runtime configuration file decides which of them are used, and how, when the Collector starts. A component that is not in the manifest cannot be used, no matter what the runtime configuration says.

8The dist Section in Detail

A few short fields in this section control how your distribution is named, versioned and written to disk.

FieldWhat it controlsPractical advice
nameThe name of the produced binary. Defaults to a generic custom name.Choose a meaningful name such as your company and role, so that people can recognise it in process lists.
moduleThe Go module path of the generated project.Use a path you control, following your organisation’s convention.
descriptionA human-readable summary shown in help output.Write one clear sentence saying who owns the distribution and why it exists.
versionThe version number of your distribution.Version your distribution deliberately so you can tell which build is in production.
output_pathThe folder where generated source and the binary are written.Keep it consistent, and remember to update any container build steps that refer to it.
goWhich Go executable to use for compilation.Set it when several Go versions are installed and you need a specific one.
debug_compilationWhether to keep extra debugging information in the binary.Turn it on for development and off for production, since it makes the file larger.
Simple Analogy

The dist section is like the label on a jar of homemade jam. It says what the jam is called, which batch it came from, and what is written on the lid. You can make jam without a label, but when you have twenty jars in the cupboard, you will be very glad you wrote one.

!
Keep references in sync

If you change the binary name or the output folder, anything else that refers to them, such as container build files and deployment scripts, must change too. Forgetting this is a very common cause of builds that succeed but deployments that fail.

9Listing Components: Addresses and Versions

Each component in the manifest is identified by where it lives and which version you want.

Every entry under a component section points to a Go module. The entry gives the module’s address, which says where to find it, and a version, which says exactly which release to use. OCB uses these two pieces of information to download the right code. The versions are normally pinned precisely, which means every build with the same manifest produces the same result.

To find the correct address and the available versions, teams use the OpenTelemetry Registry, a searchable catalogue of components. It lists receivers, processors, exporters, extensions and connectors across the ecosystem, with links to their documentation, so you can confirm what a component does and which release matches your Collector version.

Kind of componentJobTypical examples in a gateway-style Collector
ReceiverAccept telemetry from outsideThe standard OpenTelemetry protocol receiver
ProcessorChange data in flightMemory protection, batching, resource labelling
ExporterSend data onwardThe standard protocol exporter, a debugging exporter
ExtensionAdd supporting capabilitiesHealth checking, authentication, file-based storage
ConnectorJoin two pipelinesSpan-to-metrics conversion, routing

Rule of thumb for choosing

Every component you include is code you must build, update and trust. Include a component only if you can point to a specific pipeline that uses it. If nobody can name the pipeline, remove it from the manifest.

i
Do not forget the supporting actors

A pipeline that works in a test often fails in production because a small helper was left out of the manifest, such as the memory protection processor or the health check extension. Review your runtime configuration against the manifest before you build.

10Versions and Compatibility: Keep the Family Together

The most frequent source of build trouble is mixing pieces that were not designed to work together.

The Collector’s components are released on a regular schedule, and releases of the core program, the builder and the community components are numbered together as a family. A component built against one family of releases expects the core program to behave in a particular way. If you mix releases from distant families, for example a very old component inside a very new core, the pieces may disagree about how they talk to each other. The result can be a build that fails with confusing messages, or worse, a build that succeeds but misbehaves at runtime.

The sensible rule is to keep every version in the manifest, and the builder itself, within the same release family. The builder even performs a check on this by default, and it complains when versions are too far apart. Switching that check off is possible, but it removes a safety net, so it should be done only for a short-lived experiment and never for production.

Simple Analogy

Think of building a model railway. Track pieces from the same maker fit together perfectly. Track from a different era or brand may look similar but the connectors do not quite match, and trains derail at the joints. Component versions are the track pieces, and the release family is the maker.

1

Pick one release family

Decide which Collector release your distribution targets, and use the matching builder version.

2

Pin every component to that family

Use the registry to find the component release that corresponds to your chosen family, and write it down exactly.

3

Upgrade everything together

When you move to a newer family, change the builder, the core and all components in one deliberate step, then test.

!
A trap with partial upgrades

Upgrading a single component to get a new feature, while leaving everything else behind, is the classic way to create a mismatch. If you need one newer component, plan to upgrade the whole family.

11Your First Build, Step by Step

Let us walk through the complete first build in plain language.

1

Sketch your pipelines on paper

Write down where telemetry comes from, what must be done to it, and where it must go. Each noun in that sentence becomes a component.

2

Look up each component in the registry

Find its module address and the release that matches your chosen family.

3

Write the manifest

Fill in the dist section, then add one entry per component. Keep the file short and commented where the reason is not obvious.

4

Run OCB with the manifest

Point OCB at the file. It generates the project and compiles it. The first run takes longer because many modules must be downloaded.

5

Look at the output folder

You will find the generated source files and your binary. Notice the binary’s name matches the one you chose.

6

Run it with a runtime configuration

Write the usual Collector configuration, start the binary, and send it some test telemetry to prove that the pipeline works.

i
Start small

For your very first build, choose just one receiver, one or two processors and one exporter. Once that works, add components one at a time. Small steps make it easy to see which addition caused a problem.

Simple Analogy

Learning to cook a new dish, you do not buy every spice on the shelf. You make the plain version first, taste it, and then add one flavour at a time. Building a Collector works best the same way.

12What OCB Leaves Behind: The Generated Project

The output folder is not a black box; each file has a clear purpose.

File

The main program file

The entry point that starts the Collector. It is generated and rarely edited by hand.

File

The components file

Registers every receiver, processor, exporter, extension and connector you listed so the Collector knows they exist.

File

The module files

Record which exact versions of every dependency are used. They are what makes builds repeatable.

File

The binary

The finished executable that you run and deploy.

Why the generated source matters

The generated project is useful in three ways. For auditing, a reviewer can read exactly which components and which versions went into a build. For development, an engineer can open the project in a normal Go editor, step through the Collector’s code with a debugger, and see how a component behaves in context. For reproducibility, keeping the manifest and the module files in version control means anyone can rebuild the same distribution later.

Treat as source of truth

  • The manifest, kept in version control.
  • The pinned versions recorded in the manifest.
  • The build script or pipeline that runs OCB.

Treat as disposable output

  • The generated source files, which can be recreated at any time.
  • The binary on a developer’s laptop.
  • Hand edits made directly to generated files, which will be overwritten on the next generation.
!
Do not hand-edit generated files

Changes made directly inside generated files are lost the next time you generate. If you need different behaviour, change the manifest, or write a proper custom component, rather than patching the output.

13Running and Verifying Your Custom Collector

A build that compiles is not yet a build that works, so verify before you trust it.

Your custom binary behaves like any other Collector, with a few built-in commands that are very helpful for verification. It can list the components that are compiled into it, which lets you confirm that everything in your manifest made it into the binary and nothing unexpected did. It can also validate a runtime configuration file without starting the pipelines, which catches typing errors and references to components that are not present.

1

List the compiled-in components

Compare the list with your manifest. Missing items mean the build did not include them; extra items are a surprise worth understanding.

2

Validate your runtime configuration

Ask the binary to check the configuration file against the components it contains. Fix any complaints before starting it for real.

3

Run a smoke test

Start the Collector, send a small amount of test telemetry and confirm that it appears at the destination.

4

Check its own health

Confirm that the health check endpoint reports a ready state and that its own internal metrics look sensible.

i
Make it a gate

Turn these checks into an automatic step that must pass before a new build is allowed into production. Verification that depends on someone remembering to do it will eventually be skipped.

14Providers: Where the Configuration Comes From

A small manifest section decides how your Collector can read its runtime settings.

When a Collector starts, it needs to find its runtime configuration. Providers are the pieces that know how to fetch it from different places. One provider may read from a file on disk, another from an environment variable, another from a web address, and another from inline text on the command line. In the standard distributions a sensible set of providers is already included, but in a custom distribution you choose which ones to carry.

Kind of sourceWhen it is usefulCaution
FileSimple deployments and mounted configuration filesMake sure the file is protected and version controlled
Environment variableInjecting secrets and small settings at start timeAvoid leaking values in logs or process listings
Web addressCentral configuration that many Collectors fetchThe server becomes a dependency, and the connection should be secured
Inline textQuick tests and small overridesHard to review and easy to mistype
Simple Analogy

Providers are like the different ways a chef can receive an order: handwritten on a slip, spoken by a waiter, read from a screen or fetched from a central system. A kitchen only needs to support the methods it actually uses, and each additional method is one more thing that can go wrong.

!
A runtime surprise

If you remove a provider from your manifest and your deployment still tries to use it, the Collector will refuse to start. Review how your environment delivers configuration before choosing the providers to include.

15The Replaces Section and Local Components

Sometimes you need to use a component that is not the exact published version, and the replaces section is the escape hatch.

The replaces section lets you tell the build to use a different module, or a different version of a module, than the one that would otherwise be chosen. This is a standard feature of the Go ecosystem, and OCB passes it through. It is useful in a few situations, and risky in all of them if used carelessly.

Developing your own component

While building a new component on your laptop, you can point the build at the folder where you are working, so that every build uses your latest edits without publishing anything.

Applying a temporary fix

If an upstream component has a bug that you have already fixed in your own copy, you can use your copy until the official fix is released.

Resolving a dependency conflict

When two components require incompatible versions of the same supporting library, a replacement can force a single agreed version, though you must test carefully afterwards.

!
Treat replacements as debt

Every replacement is a quiet fork that you now own. It will not receive upstream fixes automatically, and it can hide incompatibilities. Record why each one exists, who owns it, and when it can be removed, and review the list at every upgrade.

Simple Analogy

A replacement is like fixing a car with a part from a different model. It may fit well enough to drive, and sometimes it is the only way to get on the road quickly, but you must remember it is there, because the next mechanic will not expect it.

16Building Your Own Components with OCB as a Launchpad

OCB is not only for assembling existing parts; it is also the fastest way to start writing new ones.

Sometimes the component you need does not exist, perhaps because it talks to an internal system, applies a rule that is specific to your company, or implements an unusual authentication method. You can write your own component in Go. OCB helps because it produces a complete, buildable Collector project around your component, so you can run and debug it inside the real thing from the very first day.

1

Generate a base distribution

Use OCB with a small manifest to produce a project that contains the standard pieces you need around your future component.

2

Write the component

Create your receiver, processor, exporter, extension or connector in its own module, following the project’s component conventions.

3

Reference it locally

Point the manifest at your component’s folder, using a replacement or a local path, so builds always pick up your latest code.

4

Debug it in your editor

Open the generated project in a Go editor and use ordinary breakpoints and stack traces to watch how the Collector calls your code.

5

Publish and pin

When it is ready, publish the component as a versioned module, replace the local path with a pinned version, and remove the temporary replacement.

i
Think twice before writing

Custom components are code you must maintain through every future release. Before writing one, check the registry carefully and consider whether configuring an existing component, or contributing an improvement upstream, would meet the need.

17Packaging into a Container Image

Most Collectors end up in containers, so the build usually continues beyond OCB.

On container platforms you do not copy a binary onto a server; you package it into an image. A common pattern is the multi-stage build. In the first stage, a temporary image contains Go and OCB, and it runs the builder to create the binary. In the final stage, a clean, minimal image receives only the finished binary and the runtime files it needs. The big build tools never reach production, which keeps the final image small and reduces its attack surface.

flowchart LR
    subgraph S1["Stage 1: build image"]
        GO["Go toolchain"] --> OC["OCB runs with manifest"] --> BIN["Binary produced"]
    end
    BIN --> COPY["Copy only the binary"]
    subgraph S2["Stage 2: runtime image"]
        COPY --> RUN["Minimal image with the Collector binary"]
    end
    RUN --> REG["Image registry"]
        
FIG 2 — A multi-stage build: heavy tools in stage one, a tiny runtime image in stage two
Tip 1

Match the architecture

Build for the processor type of the machines that will run the image, such as Intel-style or ARM. A binary for the wrong type will not start.

Tip 2

Keep names consistent

The binary name and output folder in the manifest must match what the image build copies. Change one, change both.

Tip 3

Pin base images

Use specific versions of the Go and runtime base images, so the same inputs always give the same image.

Tip 4

Run without extra privileges

Configure the final image to run as a normal user and include only what the Collector needs.

!
Common mistake

Building on a laptop of one processor type and deploying to servers of another. The image builds happily and then fails at start-up with an error about an invalid executable format.

18Building for Several Platforms

Real fleets are rarely uniform, so a distribution often has to run on more than one kind of machine.

An organisation may run servers with Intel-style processors, newer machines with ARM processors, developer laptops of both kinds, and perhaps some Windows hosts. A custom distribution therefore needs a build for each target. The Go toolchain supports building for a different platform than the one it runs on, and OCB works with this ability, so one pipeline can produce several binaries from one manifest.

TargetTypical useWhat to watch
Linux, Intel-styleMost servers and cloud virtual machinesThe most common target; test here first
Linux, ARMCost-efficient cloud instances and edge devicesVerify every component works on this architecture
macOSDeveloper laptopsUseful for local testing, rarely for production
WindowsWindows servers and desktopsConfirm that each component supports Windows before promising it

Publish one image for several architectures

Container tooling can combine builds for several processor types behind a single image name, so deployments pick the right one automatically. This keeps deployment configuration simple even when the fleet is mixed.

i
Test what you ship

A binary that compiles for a platform has not necessarily been proven to work there. Run at least a smoke test on each platform you publish, since some components depend on features of a particular operating system.

19Automating the Build in a Pipeline

A build that only works on one person’s laptop is a risk, so move it into an automated pipeline early.

Continuous integration systems run tasks automatically whenever something changes. For a custom Collector, a pipeline gives you repeatable builds, a visible history, and an easy place to add checks. The manifest lives in version control; every change to it triggers the pipeline; and the pipeline produces a tested, labelled image or binary ready for release.

flowchart LR
    A["Change to manifest in version control"] --> B["Review and approval"]
    B --> C["Pipeline starts"]
    C --> D["Install pinned Go and OCB"]
    D --> E["Run OCB build"]
    E --> F["List components and validate configuration"]
    F --> G["Smoke test and security scan"]
    G --> H["Publish versioned image and records"]
        
FIG 3 — A typical build pipeline for a custom Collector distribution
1

Pin the tools

Use fixed versions of Go and OCB inside the pipeline, so a tool update never silently changes your output.

2

Build from the manifest only

The pipeline should need nothing but the manifest and pinned tools. If it needs manual steps, it is not repeatable.

3

Run the verification gates

Check the component list, validate sample configurations, and run a smoke test. A failing gate stops the release.

4

Scan and record

Scan for known vulnerabilities and produce a bill of materials listing every dependency, then store both with the artefact.

5

Publish with a clear version

Label each release with the distribution version and the underlying release family, so it is obvious what is running where.

i
Cache wisely

Downloading hundreds of modules makes builds slow. Caching downloaded modules between pipeline runs speeds things up greatly, provided the cache is keyed to the manifest so that a changed list invalidates it.

20Choosing the Right Components

The quality of your distribution is decided by what you leave out as much as by what you put in.

A useful way to choose is to work backwards from your pipelines. Start from the runtime configuration you intend to run in production. Every receiver, processor, exporter, extension and connector named there goes into the manifest. Then add the supporting actors that keep the Collector healthy, such as memory protection and health checking. Finally, ask whether any component is there just in case. If so, leave it out; you can always rebuild when a real need arrives.

Question to askIf the answer is yesIf the answer is no
Is it named in a production pipeline?Include itLeave it out for now
Does it keep the Collector safe or observable?Include it, even though no pipeline names itReconsider
Is it stable and maintained?Include with confidenceAccept it only with an owner and a plan
Does it pull in many extra dependencies?Weigh the cost in size and riskCheap to include
Could existing configuration do the job?Prefer configuration to a new componentA new component may be justified
Simple Analogy

Choosing components is like packing a first aid kit. You include what you will plausibly need and what keeps people safe, but you do not pack a surgical theatre. Every extra item adds weight, and items nobody understands are items nobody will use correctly in an emergency.

!
Maturity matters

Components have different stability levels, and some are experimental. Check the stability notes in each component’s documentation before including it in a production distribution, and prefer stable ones for the critical path.

21Size, Memory and Start-Up Benefits

A smaller distribution is not only tidier; it brings measurable practical advantages.

A binary that contains hundreds of components is larger on disk than one that contains a dozen. Larger files take longer to download, longer to start in a fresh container, and use more storage in image registries and on nodes. Registered components also consume a little memory at startup, even if they are never used. In a large fleet where containers start and stop constantly, these small costs multiply.

Aspect (illustrative)Large all-in-one distributionFocused custom distribution
Binary sizeLargeA fraction of the size
Image download timeSlower, especially on cold nodesFaster
Start-up timeLongerShorter
Dependencies to patchHundredsOnly those you use
Time to review before releaseLongShort

The table above is intentionally qualitative, because exact numbers vary with versions, components and platforms. The way to know your own numbers is to build both and measure. Many teams find that the largest gain is not raw speed but the reduction in what needs reviewing and patching.

i
Measure, do not assume

Before justifying a custom build on size grounds, build the standard distribution and your custom one and compare file size, image size and start time on your own infrastructure. Numbers from your own system are the only ones that matter for your decision.

Simple Analogy

Compare two backpacks for a day hike. One holds everything for a week in the mountains, and the other holds lunch, water and a jacket. Both can complete the walk, but one tires you out sooner, and when you need to find your keys you must search through a lot more.

22Security and Supply Chain Considerations

Choosing fewer components reduces risk, but owning the build also creates responsibilities.

Every component you include is code that runs inside a program that handles sensitive telemetry and often holds credentials. If a flaw is discovered in a component you do not need, but it is present in your binary, you are exposed anyway. By building only what you use, you shrink the number of places where such flaws can lurk. This is the strongest security argument for a custom distribution.

At the same time, once you build your own Collector, you become the one who must notice security fixes and ship them. Ready-made distributions are maintained by others; yours is maintained by you.

Practice 1

Pin and review versions

Record every component and dependency version. Review changes to the manifest like you would review changes to production code.

Practice 2

Scan for known vulnerabilities

Run automated scans in the pipeline and on a schedule, since new flaws are discovered in old code all the time.

Practice 3

Produce a bill of materials

Keep a list of everything inside each build, so you can answer quickly which releases are affected when a flaw is announced.

Practice 4

Protect the build itself

Limit who can change the manifest and the pipeline, and sign released artefacts so that deployment systems can verify where they came from.

Practice 5

Trust components deliberately

Community components vary in maintenance and review. Prefer well-maintained ones and know who owns each in your organisation.

Practice 6

Run with least privilege

Give the running Collector only the permissions, network access and credentials it needs.

DECISION-01 Recommended
Problem

A platform team wants a custom Collector for its smaller attack surface but has no process for tracking security fixes.

Decision

Adopt the custom distribution only together with an owner, a scheduled vulnerability scan, a bill of materials per build, and an agreed time limit for shipping fixes.

Consequence

The security benefit becomes real, at the cost of ongoing work. If the team cannot commit to that work, a maintained official distribution is the safer choice.

23The Upgrade Lifecycle

A custom distribution is a living thing: it must be rebuilt regularly or it slowly becomes a liability.

The Collector project releases new versions regularly, with new features, fixes and sometimes changes that require attention. A custom distribution does not update itself. Someone must decide when to move to a new release family, update the manifest, rebuild, test and roll out. If this is neglected, the distribution drifts further from upstream, security fixes pile up, and the eventual jump becomes large and risky.

flowchart TD
    A["New release family published"] --> B["Read release notes and deprecations"]
    B --> C["Update builder and all component versions together"]
    C --> D["Rebuild in pipeline"]
    D --> E["Run verification and smoke tests"]
    E --> F["Canary rollout to a small group"]
    F --> G{"Healthy?"}
    G -->|"Yes"| H["Roll out to everyone"]
    G -->|"No"| I["Roll back and investigate"]
        
FIG 4 — A repeatable upgrade loop for a custom distribution

Healthy habits

  • Upgrade on a regular, planned schedule.
  • Read release notes for removed or renamed settings.
  • Upgrade the builder, core and components together.
  • Roll out gradually with a prepared rollback.

Warning signs

  • Running a release family that is many versions old.
  • Several leftover replacements nobody can explain.
  • No one who owns the manifest.
  • Upgrades postponed until an emergency forces them.
i
Small, frequent upgrades

Moving by one release family at a time is far easier than jumping across many. Smaller steps mean fewer changes to understand and an easier path to find the cause when something breaks.

24From Manifest to Production: The Full Flow

Let us follow one change all the way from an idea to a running Collector, noting who does what.

sequenceDiagram
    participant D as Developer
    participant R as Repository
    participant P as Pipeline
    participant G as Image registry
    participant K as Cluster
    D->>R: Propose manifest change
    R->>R: Review and approve
    R->>P: Trigger build
    P->>P: Run OCB, verify, scan
    P->>G: Publish versioned image
    P->>K: Roll out to canary
    K-->>P: Health and metrics look good
    P->>K: Roll out to all
        
FIG 5 — The path of a manifest change through review, build and rollout
1

Propose

A developer wants a new exporter. They add it to the manifest and explain why in the change description.

2

Review

A second person checks the component’s maturity, its version family, its dependencies and its need.

3

Build and verify

The pipeline builds the distribution and runs its gates. A failure stops the change here.

4

Publish

The pipeline stores a uniquely versioned image and its supporting records.

5

Canary

A small group of Collectors receives the new image first, while the team watches their health and queue metrics.

6

Full rollout

If the canary is healthy, the rest of the fleet follows, with rollback ready.

“Every component in production should have a reason, an owner and a version number.”

25Governance: Who Owns the Distribution?

In an organisation, a shared Collector is a shared product, and shared products need owners and rules.

When several teams use the same custom Collector, questions appear quickly. Who decides which components are allowed? Who responds when a component has a security issue? How does a team request a new integration? Without answers, the manifest either grows without control or becomes a bottleneck that frustrates everyone. A light but clear governance model solves both problems.

A platform team owns the manifest

One team is responsible for the distribution, its pipeline and its releases. Other teams request changes through a simple, documented process.

An approved component list

The platform team maintains a short list of vetted components. Requests for components outside the list go through a quick review covering maturity, ownership, dependencies and security.

A clear versioning scheme

The distribution carries its own version, plus a note of the release family it is based on. Teams can see at a glance which version they run and what changed.

Published support expectations

The platform team states how quickly it will ship security fixes and how long older distribution versions remain supported, so that application teams can plan their own upgrades.

i
Keep the door open

Governance should make safe choices easy, not make every change painful. A short review turnaround and a self-service way to test a candidate component keeps teams from working around the process.

26Design Patterns and Anti-Patterns

Patterns capture what usually works and anti-patterns what usually hurts, and both are cheaper to learn from a page than from an incident.

Patterns that work

One distribution per role

Build a small agent distribution and a separate, richer gateway distribution. Each carries only what its role needs, which keeps agents tiny and gateways capable.

Manifest as reviewed code

Keep the manifest in version control with the same review rules as production code, and build only from it.

Verification gates before release

Make component listing, configuration validation and smoke tests automatic checks that every build must pass.

Anti-patterns to avoid

ANTI-PATTERN-01 Avoid
Problem

The team copies a huge list of components into the manifest just in case, recreating the large distribution they were trying to avoid.

Why It’s Harmful

All the costs of a large binary return, along with the extra work of maintaining a custom build.

Correct Approach

Start from the pipelines actually in use and add components only when a real need appears.

ANTI-PATTERN-02 Avoid
Problem

Component versions are mixed across several release families, with the compatibility check switched off to get the build to pass.

Why It’s Harmful

The build may succeed but behave unpredictably in production, and failures are very hard to trace.

Correct Approach

Keep the builder, core and all components within one release family and upgrade them together.

ANTI-PATTERN-03 Avoid
Problem

A build exists only on one engineer’s laptop, produced by manual steps nobody has written down.

Why It’s Harmful

If that engineer is unavailable, nobody can rebuild or patch the Collector, and nobody can prove what is inside it.

Correct Approach

Build only in an automated pipeline from a version-controlled manifest, with pinned tools.

ANTI-PATTERN-04 Avoid
Problem

The distribution is built once and never rebuilt, because it works.

Why It’s Harmful

Known vulnerabilities and bugs accumulate, and the eventual forced upgrade becomes a large, risky project.

Correct Approach

Schedule regular rebuilds and upgrades, scan continuously, and treat the distribution as a product with an owner.

27Best Practices and Common Mistakes

A short checklist is often more useful than a long argument.

Best practices

  • Choose components by working backwards from real pipelines.
  • Keep builder, core and components in one release family.
  • Pin every version and keep the manifest in version control.
  • Build in an automated pipeline with pinned tools.
  • Verify the component list and configuration before every release.
  • Use multi-stage container builds and match target architectures.
  • Scan for vulnerabilities and keep a bill of materials.
  • Upgrade regularly and roll out gradually.

Common mistakes

  • Including components just in case.
  • Forgetting supporting components such as memory protection and health checks.
  • Mixing versions from different release families.
  • Leaving undocumented replacements in the manifest.
  • Hand-editing generated files.
  • Building for the wrong processor architecture.
  • Never rebuilding after the first release.
i
A rule of thumb

For every component in your manifest you should be able to answer in one sentence: which pipeline uses it, who owns it, and which version is pinned.

28Real-World Scenarios

Examples help the ideas settle, so here are five situations where teams reach for OCB.

A regulated company with a strict review process

Every program in production must be reviewed. A distribution of twelve components can be reviewed in days; one of hundreds cannot. The team builds a focused distribution and keeps the bill of materials for auditors.

A company with an internal protocol

Legacy systems emit telemetry in a company-specific format. The team writes a small custom receiver, uses OCB to build it into a distribution, and retires the receiver later when the systems are modernised.

A fleet of small edge devices

Devices have little storage and memory. A minimal agent distribution with one receiver and one exporter fits comfortably, where a large distribution would not.

A platform team serving many product teams

The platform team publishes two supported distributions, one for agents and one for gateways, with a clear process for requesting additions and a published upgrade schedule.

A team experimenting with new components

An engineer wants to try an experimental processor without affecting production. A short-lived custom build lets them test it on a development cluster while production stays on the stable distribution.

“Build the smallest Collector that does the job, and be ready to rebuild it.”

29OCB Compared with the Alternatives

OCB is a good answer to some questions and a poor answer to others, so it helps to compare honestly.

ApproachBest whenMain cost
Use the official contrib distribution as it isYou want the widest choice with the least effort, and size and attack surface are not concernsA large binary with many unused components
Use the official core distributionYour needs are modest and covered by essential componentsMissing integrations that you may later need
Use a vendor distributionYou rely heavily on one vendor and want their supportReliance on the vendor’s choices and release schedule
Build a custom distribution with OCBYou need a focused, controlled, possibly extended CollectorYou own builds, upgrades and security patching
Fork and modify the Collector source directlyYou need deep changes to the core itselfThe highest maintenance burden, rarely justified

Advantages of OCB

  • A smaller binary and a smaller attack surface.
  • Exact control over which components and versions run.
  • A way to add your own components cleanly.
  • Reproducible, reviewable builds from a short manifest.
  • A fast start for developing and debugging components.

Disadvantages and trade-offs

  • You become responsible for upgrades and security fixes.
  • Version compatibility must be managed carefully.
  • A build pipeline and tooling must be maintained.
  • Missing components are discovered at runtime, not build time.
  • Support from others is harder, since your build is unique.
i
An honest default

If you have no concrete reason to build your own, an official distribution is a perfectly good choice. Reach for OCB when you can name the benefit, whether that is size, security review, a custom component or experimentation, and when you have someone to own the result.

30A Worked Example: Designing a Gateway Distribution

Let us design a real distribution on paper, step by step, to see how the reasoning flows.

A company runs a gateway tier that accepts telemetry from many applications using the standard OpenTelemetry protocol, protects itself from overload, adds a label saying which environment the data came from, groups items into efficient batches, and sends everything to a single backend over the same protocol. During testing, engineers also want a debugging output. Operations wants health checks for the container platform and authentication of incoming calls.

1

Write the pipeline in words

Receive by the standard protocol, limit memory, label the environment, batch, send by the standard protocol.

2

Turn each phrase into a component

One receiver, three processors, one exporter. Add a debugging exporter for testing.

3

Add supporting extensions

A health check extension for the platform and an authentication extension for incoming calls.

4

Look up versions in the registry

Choose one release family and pin every entry to it, alongside the matching builder.

5

Name and describe the distribution

Give it a role-based name and description, and choose the output location used by the container build.

Component kindComponentReason it is included
ReceiverStandard protocol receiverAccepts telemetry from applications
ProcessorMemory limiterPrevents crashes during overload
ProcessorResource labellingAdds the environment label
ProcessorBatchImproves efficiency of sending
ExporterStandard protocol exporterSends data to the backend
ExporterDebug exporterHelps engineers during testing; can be removed for production
ExtensionHealth checkLets the platform judge readiness
ExtensionAuthenticationVerifies incoming callers
8
components in this distribution
1
release family for all versions
0
components included just in case
!
Review before building

Notice how easy it would have been to forget the memory limiter or the health check, since no data flows through them. A final review of the manifest against production needs, not just the pipelines, catches such omissions before they become outages.

31Testing a Custom Distribution

A custom build deserves the same testing discipline as any other program you ship.

TestWhat it provesWhen to run it
Component list checkThe binary contains exactly the components you intendedEvery build
Configuration validationSample production configurations are accepted by the binaryEvery build
Smoke testTelemetry flows from input to outputEvery build
Load testThe distribution handles realistic traffic with stable memoryBefore each release family change
Failure testBehaviour under backend outage and restarts matches expectationsBefore major changes
Platform testThe binary works on each operating system and architecture you publishEvery release
Security scanNo known serious vulnerabilities in the dependenciesEvery build and on a schedule
Upgrade testConfigurations still work after moving to a new release familyBefore every upgrade
Simple Analogy

Think of a bakery that makes its own bread recipe. Before selling a new batch, the baker checks the ingredients, tastes a slice, and compares it with last week’s loaf. Testing a custom distribution is the same ritual: check the contents, taste a sample, and compare with the previous release.

i
Keep sample configurations in the repository

Store a few representative runtime configurations next to the manifest and validate them in the pipeline. This catches the situation where a component was removed from the manifest but is still used by a real configuration.

32Troubleshooting Guide

When something goes wrong, a symptom-first table gets you to the right question quickly.

SymptomLikely causeWhat to check first
OCB refuses to start the compile stepGo is missing, too old or not found by the builderInstalled Go version and the configured Go executable
Build fails with version complaintsBuilder and component versions are from different release familiesAlign every version in the manifest with the builder
Build fails while downloading modulesNetwork restrictions, wrong module address or a mistyped versionModule addresses, versions and network access from the build machine
Collector refuses to start: unknown componentA component named in runtime configuration is not in the binaryCompare the compiled-in list with the runtime configuration
Collector refuses to start: unknown configuration sourceA provider is missing from the manifestHow the deployment delivers configuration
Image builds but will not startWrong processor architecture or wrong binary name copiedTarget architecture and the name and path used by the image build
Behaves oddly after an upgradeMixed versions or a leftover replacementReplacement entries and any partly upgraded components
Binary is larger than expectedDebug information included or extra components listedDebug setting and the component list
Edits to generated files disappearThe files were regenerated by a new buildMove the change to the manifest or to a proper component

A calm way to debug a failed build

1

Read the first error, not the last

Later messages are often consequences of the first failure. Fix the earliest one and rebuild.

2

Reduce the manifest

Temporarily remove half of the components and rebuild. If it succeeds, the problem is in the removed half. Repeat until you find the culprit.

3

Ask what changed

A new component, a new version, a new Go release or a new builder usually explains a build that worked yesterday.

33Knowing What You Run: Labels, Metrics and Support

Once a custom Collector is in production, you need to be able to answer a simple question: what exactly is running here?

With many custom builds in circulation, it quickly becomes difficult to remember which one is deployed where. The remedy is to make every build identify itself. Use the version field in the manifest to give each distribution a meaningful version, label container images with the distribution version and the underlying release family, and keep the bill of materials in a place that engineers can find easily. When someone asks whether a vulnerability affects you, the answer should take minutes, not days.

Identity

Distribution version

A number you control that increases whenever the manifest changes in a way that matters.

Identity

Release family

Which Collector release the build is based on, recorded in image labels and release notes.

Records

Bill of materials

A complete list of components and dependencies for every released build.

Runtime

Self-reported metrics

The Collector reports its own internal metrics, which should be collected and labelled with the distribution version, so you can compare behaviour between versions during a rollout.

i
Support expectations

When people ask the wider community for help with a custom build, they will be asked which components and versions it contains. A manifest and a bill of materials make that conversation short and productive.

Simple Analogy

Think of the label on a medicine bottle. It says what is inside, how much, and when it was made. Without the label, even a perfectly good medicine becomes a risk, because nobody can tell whether it is the right one.

34Just Enough Go for OCB Users

You do not need to become a Go programmer, but a few Go ideas explain nearly every message OCB shows you.

Go organises code into modules. A module is a folder of code with a name that looks like a web address and a version number such as a release label. When your distribution needs a component, Go finds that component’s module by its address, downloads the requested version, and stores it in a local cache on the build machine. The next build finds it in the cache and does not download it again. This is why the very first build is slow and later ones are quick.

Idea 1

Module address

The name that tells Go where a component lives. A typo here is the most common reason a download fails.

Idea 2

Version pinning

Go records the exact version of every module, so the same inputs always produce the same build. This is the basis of repeatability.

Idea 3

Dependency graph

Components depend on other modules, which depend on still others. Go works out the full list and picks compatible versions automatically.

Idea 4

Local cache

Downloaded modules are kept on disk. Keeping this cache between pipeline runs makes builds much faster.

Idea 5

Cross-compilation

Go can build a program for a different operating system or processor than the one it runs on, which is how one machine produces several binaries.

Idea 6

Module proxy

Go usually downloads through a proxy service that serves published modules. Organisations may run their own proxy for speed and control.

Simple Analogy

Think of a recipe that lists ingredients by the shop that sells them and the batch number. The first time you cook, you visit each shop and bring the ingredients home. The next time, they are already in your pantry. The shop address is the module address, the batch number is the version, and your pantry is the local cache.

i
Reading build errors

Most build errors fall into three families: a module could not be found, a version could not be resolved, or two modules disagree about a shared dependency. Knowing which family you are in tells you whether to check the address, the version or the compatibility.

35Building in Restricted and Offline Networks

Many organisations do not let build machines reach the open internet, and OCB can still work in those places with some preparation.

OCB needs to download modules, so a build machine that cannot reach the public module services will fail on its first step. Security-conscious organisations solve this in a few well-known ways. All of them move the download from the build machine to a controlled place that your security team can inspect.

An internal module mirror

The organisation runs a mirror service that holds approved copies of public modules. Build machines are configured to download only from the mirror. New modules are added to the mirror after review, and the mirror keeps working even if the original source disappears.

A pre-populated cache

A trusted machine with internet access performs the first build and saves its module cache. That cache is then copied to the offline build machines, which can build without downloading anything.

Keeping a copy of the source

The generated project and all of its dependencies can be stored inside the organisation’s own source repository. Builds then work entirely from local files, at the cost of a large repository.

Private components

Custom components that live in private repositories need credentials during the build. Provide them through the pipeline’s secret handling, never by writing them into the manifest or the image.

ApproachStrengthWeakness
Internal module mirrorCentral control, fast, resilientA service to run and keep current
Pre-populated cacheSimple and quick to set upCache can go stale and must be refreshed deliberately
Source stored in the repositoryCompletely self-containedLarge repository, harder updates
!
Do not leak credentials

Access tokens used to fetch private modules must never end up in the final image or in logs. Use a multi-stage build so that build-time secrets stay in the discarded build stage.

36Moving from a Ready-Made Distribution to a Custom One

Most teams do not start with OCB; they start with an official distribution and migrate when a reason appears.

The safest migration is gradual. You do not need to guess which components you use, because your existing runtime configurations already say so. Every component named in any configuration that runs in production must be in the new manifest. Collect those configurations, list the components they name, and you have the heart of your manifest.

1

Gather every production configuration

Include the ones for agents, gateways and special cases such as batch jobs. Missing even one leads to a surprise later.

2

List the components they use

Write down each receiver, processor, exporter, extension and connector, and any configuration sources used.

3

Add supporting components

Include the helpers that keep the Collector healthy, even if some configurations do not name them explicitly.

4

Build and validate every configuration

Run each real configuration through the new binary’s validation. Any complaint means a component is missing.

5

Run side by side

Deploy the custom build to a small, low-risk part of the fleet and compare its behaviour and metrics with the existing distribution.

6

Expand gradually

Move more of the fleet once the comparison looks good, keeping the old distribution available for rollback until you are confident.

i
Compare, do not assume

During the side-by-side stage, compare data volumes, error counts and resource use between the two distributions. Identical behaviour is the goal of a migration; any difference deserves an explanation before you proceed.

Simple Analogy

Moving house is easiest when you look through every cupboard first and decide what to pack. Moving to a custom Collector is the same: the cupboards are your configurations, and the packing list is your manifest. A room you forgot to check is where the missing item will be.

37Managing Several Distributions Across a Fleet

As an organisation grows, one distribution rarely fits every role, and a small family of distributions becomes the natural answer.

Different places in a telemetry system have different needs. A small agent beside an application needs very few components and as little memory as possible. A gateway needs richer processing, authentication and durable queues. A special collector for a particular technology may need an unusual receiver that nobody else wants. Giving each role its own distribution keeps every one of them as small as it can be.

DistributionRoleTypical contentsMain benefit
AgentRuns beside applications or on each hostStandard receiver, memory protection, batching, one exporterTiny and quick to start
GatewayShared tier receiving from agentsStandard receiver, richer processors, authentication, storage extensions, exportersPowerful and centrally managed
SpecialistServes one technology or teamThe unusual receiver plus the minimum around itIsolates unusual dependencies from everyone else
DevelopmentUsed by engineers for testing and debuggingExtra debugging components and debug symbolsNever shipped to production
flowchart TD
    M["One repository with several manifests"] --> P["Shared build pipeline"]
    P --> A["Agent distribution"]
    P --> G["Gateway distribution"]
    P --> S["Specialist distribution"]
    P --> D["Development distribution"]
    A --> F1["Agents on every host"]
    G --> F2["Gateway tier"]
    S --> F3["Special use"]
        
FIG 6 — One repository and pipeline producing a small family of focused distributions
!
Do not multiply without limit

Each distribution is another thing to build, scan, test and upgrade. Keep the family small, share one pipeline and one release family across all of them, and merge distributions whose contents are almost identical.

38Build Options That Affect the Result

A handful of switches change what the produced binary looks like, and it helps to know what each one trades.

Option

Debug information

Including debugging information makes the binary larger but allows engineers to step through code with a debugger. Use it for development builds only.

Option

Generate only

Producing the source without compiling lets you inspect, review or modify the project, then build it later under controlled conditions.

Option

Compile only

Building from already generated and reviewed source ensures that the reviewed code, not a fresh generation, is what ships.

Option

Strict version checking

By default the builder checks that its version fits the components. Turning the check off removes a safety net and should be reserved for short experiments.

Option

Verbose output

More detailed messages help when a build fails, at the cost of noisier logs. Turn it on while diagnosing a problem.

Option

Target platform

Choosing the operating system and processor type of the result lets one build machine serve the whole fleet.

Good defaults for production

  • Debug information off to keep the binary small.
  • Strict version checking left on.
  • Builds produced only by the pipeline.
  • Reviewed, generated source compiled in a controlled step where review is required.

Risky shortcuts

  • Disabling version checks to get a build to pass.
  • Shipping a development build with debug information.
  • Building on a laptop for a different architecture without testing.
  • Regenerating code during release, so the shipped code is not the reviewed code.
i
Check the current flags

Option names and behaviour can change between builder releases. Run the builder’s help output for the exact version you use before copying options into your pipeline.

39Documenting and Onboarding Your Team

A custom distribution is only as useful as the number of people who understand how to use and change it.

A distribution that only one person understands is a risk. Good documentation turns it into a shared tool. The goal is not long documents; it is a few short, honest pages that answer the questions new people ask most often, and that are updated whenever the distribution changes.

1

A readme that explains the why

Say what the distribution is for, who owns it, and which release family it is based on. A newcomer should understand its purpose in two minutes.

2

A component register

List every component with its reason for inclusion, its owner and its stability level. This also makes cleanup easy during reviews.

3

A how-to for common changes

Explain step by step how to add a component, test it and release it, so contributors can help without asking each time.

4

A change log

Record each release, what changed and why, so that anyone investigating a behaviour change can find its cause quickly.

5

Decision records for unusual choices

Write a short note for every replacement, disabled check or unusual component, explaining the reason and when it can be revisited.

Simple Analogy

Think of the instruction booklet that comes with a piece of furniture. Nobody wants a novel, but everyone is grateful for clear pictures, a parts list and a note about the tricky screw. A short, good booklet saves the whole family from guesswork.

i
Keep documentation close to the manifest

Store the documentation in the same repository as the manifest and review it in the same change. Documents that live elsewhere drift out of date quickly.

40How Components Are Wired Together Inside the Binary

A little knowledge of the wiring explains why a missing component stops the Collector at start-up instead of failing quietly later.

Every component in the Collector is created by a small piece of code called a factory. A factory knows the component’s type name, such as the name you write in a runtime configuration, and it knows how to create an instance of the component when the Collector needs it. The generated components file made by OCB collects the factories of every component you listed into registries, one registry for each kind: receivers, processors, exporters, extensions and connectors.

When the Collector starts, it reads the runtime configuration and looks up each named component in the matching registry. If a name is found, the factory builds the component. If a name is not found, the Collector stops immediately with an error saying that the component type is unknown. This early, loud failure is deliberate. It is much better to learn about a missing component at start-up than to discover hours later that a pipeline has been silently doing nothing.

flowchart LR
    M["Manifest: list of components"] --> G["Generated components file"]
    G --> R["Registries: receivers, processors, exporters, extensions, connectors"]
    C["Runtime configuration names a component"] --> L{"Is it in the registry?"}
    R --> L
    L -->|"Yes"| F["Factory creates the component"]
    L -->|"No"| E["Collector stops: unknown component"]
        
FIG 7 — How the manifest, the registries and the runtime configuration meet at start-up
Simple Analogy

Imagine a theatre with a list of actors who are actually in the building. The director’s script names actors for each scene. If the script names an actor who is not on the list, the show cannot start, and the stage manager says so at once. The manifest is the list of actors in the building, and the runtime configuration is the script.

i
What this means for you

Validating your runtime configuration against the finished binary is a precise test of whether your manifest is complete. Because lookup happens at start-up, the validation step in your pipeline will catch almost every missing-component mistake before production does.

!
A subtle gap

Validation proves that components exist and that their settings parse. It does not prove that a pipeline behaves well under load or that a destination is reachable. Keep smoke tests and load tests in your pipeline as well.

41Deciding Whether OCB Is Worth It for You

A short scoring exercise can turn a vague feeling into a clear decision.

Because a custom distribution brings ongoing work, it deserves a deliberate decision. The table below lists common reasons and the questions that test whether each reason is real. Score each row honestly with a simple yes or no. A single strong yes, with an owner ready to carry the maintenance, is often enough. Several weak yes answers rarely are.

ReasonTest questionStrength of the reason
Smaller attack surface or easier security reviewDoes your organisation require reviewing everything that runs in production?Strong if the answer is yes
Component not available in any official distributionHave you searched the registry and confirmed that no existing component can do the job?Strong if confirmed
Smaller binary or faster startHave you measured the difference on your own infrastructure and does it matter?Strong only with measured benefit
Resource-constrained devicesDo your devices have strict storage or memory limits?Strong if yes
Control over versions and timingDo you need to move to new releases on your own schedule?Moderate
It seems more professionalIs there any measurable benefit at all?Weak, avoid
1

Name the concrete benefit

Write one sentence stating what will be better, such as the review time or the image size, and by roughly how much.

2

Name the owner

Identify the person or team who will upgrade, scan and fix the distribution for as long as it is in use.

3

Estimate the ongoing effort

Think about regular upgrades, security responses and support questions, and judge whether the benefit is worth that effort.

4

Try a small pilot

Build one distribution for one role and measure the real result before committing the whole organisation.

“A custom Collector is a promise to keep rebuilding it.”

42Choosing Community Components Wisely

Many of the components you will want come from the wider community, and their quality and upkeep vary.

The core Collector is maintained by the project’s core team, but the large collection of community components is contributed and maintained by many people and companies. Each has its own pace of development and its own stability level, which the documentation states. When you build a custom distribution, you are choosing which of those components your organisation will rely on, so a little due diligence goes a long way.

Check 1

Stability level

Read the component’s documented stability. Stable components change slowly and carefully; experimental ones may change settings or behaviour between releases.

Check 2

Maintenance activity

Look at how recently the component received fixes and how quickly reported problems are answered. An abandoned component becomes your problem.

Check 3

Who owns it upstream

Components usually list their maintainers. Knowing who they are helps you judge reliability and know whom to ask or help.

Check 4

Dependencies it brings

Some components pull in large supporting libraries. Check whether the extra weight and risk are justified by the benefit.

Check 5

Platform support

Confirm that the component works on every operating system and processor type you publish.

Check 6

Configuration surface

A component with a huge number of settings is harder to review and to use safely. Prefer simpler ones when they meet your need.

DECISION-02 Recommended
Problem

Teams request new community components frequently, and some are experimental or poorly maintained.

Decision

Require each new component to pass a short checklist covering stability, maintenance, ownership, dependencies and platform support, and assign an internal owner who will watch upstream changes.

Consequence

The distribution stays predictable and upgrades stay manageable, at the cost of a small delay when adding a component. Urgent experiments can use a separate development build instead of the shared production one.

i
Contribute back

If you depend on a community component, helping to fix its bugs upstream is often cheaper than carrying your own patched copy through every future upgrade.

43A One-Page Quick Reference

When you only have a minute, this table recaps the whole journey from idea to running Collector.

StageWhat you doWhat to checkWhat can go wrong
DecideName the benefit and the ownerIs there a measurable reason and someone to maintain it?Building a custom Collector for no clear reason
Choose componentsList components from real pipelines plus supporting helpersEach has a pipeline, an owner and a stability levelIncluding things just in case, or forgetting helpers
Write the manifestFill in the dist section and component entries with pinned versionsEvery version is in one release familyMixed versions and mistyped module addresses
BuildRun OCB with pinned tools in a pipelineThe build succeeds from the manifest aloneMissing Go, blocked network, wrong versions
VerifyList components, validate configurations, run a smoke testThe compiled-in list matches the manifestA missing component or provider found too late
PackageUse a multi-stage container build for each target platformThe image starts on the real target architectureWrong architecture or mismatched binary name
SecureScan, produce a bill of materials, sign the artefactsNo serious known vulnerabilities and a record of contentsUnscanned dependencies and unknown contents
ReleaseCanary first, then gradual rollout with rollback readyQueue, error and resource metrics look normalChanging the whole fleet at once
MaintainRebuild and upgrade on a scheduleThe distribution stays close to a supported release familyForgotten builds that slowly become liabilities
i
How to use this page

Print it or pin it next to your pipeline definition. Each time you change the distribution, walk down the rows and confirm that every stage still has an answer in your pipeline, your documentation or your team’s habits.

Simple Analogy

Pilots follow a short checklist before every flight, even though they have flown hundreds of times. The checklist does not make them better pilots; it makes sure that a tired or busy moment never lets an important step slip through. This table plays the same role for your Collector builds.

44Maturity and Ecosystem

A tutorial should be honest about the moving parts, so here is how to stay safe on shifting ground.

The Collector, its builder and its components are actively developed. Names of settings, supported Go versions, installation methods and even the list of official distributions can change between releases. The ideas in this tutorial, choosing components deliberately, keeping versions together, building in a pipeline, verifying before release, and owning upgrades, are lasting. Specific commands and flags are not, so confirm them against the documentation for the exact version you use.

Docs

Builder documentation

Describes installation, the manifest sections, the dist fields, building, and container packaging.

Docs

Distributions page

Lists the official distributions and the community-listed vendor distributions, with a note that vendors are not endorsed by the project.

Catalogue

OpenTelemetry Registry

A searchable list of components with their module addresses and documentation, used when writing a manifest.

Docs

Custom Collector guide

Explains the workflow from installation to a running custom distribution, and how to develop components.

i
Stay current

Follow the project’s release notes, and treat each upgrade as a small project with its own testing. Component stability levels change over time, so re-check them whenever you add or upgrade a component.

45Frequently Asked Questions

Q1What is the OpenTelemetry Collector Builder in one sentence?

It is a command-line tool that reads a short manifest listing the components you want, generates a small Go project around them, and compiles a custom Collector containing exactly those components.

Q2Do I need to know Go to use OCB?

Not for the standard case of assembling existing components, because you only write a manifest. You need Go installed, since OCB uses it to compile, and Go knowledge only becomes necessary when you write your own components.

Q3Why not just use the official contrib distribution?

You can, and many teams do. A custom distribution is attractive when you want a smaller binary, a smaller attack surface, easier reviews, or a component that is not in any official distribution.

Q4What goes into the manifest?

A dist section describing the distribution, lists of receivers, processors, exporters, extensions and connectors with their module addresses and versions, and optionally providers and replacements.

Q5What is the difference between the manifest and the runtime configuration?

The manifest decides which components exist inside the binary. The runtime configuration decides which of them are used and how when the Collector starts. A component missing from the manifest cannot be used.

Q6Why do version mismatches cause so much trouble?

Components are built against a particular release family of the core. Mixing families can cause build failures or subtle runtime misbehaviour. Keep the builder, core and components together.

Q7Can I add my own custom component?

Yes. Write it as a Go module, reference it in the manifest using a local path or replacement during development, and replace that with a pinned published version when it is ready.

Q8How do I put a custom Collector into a container?

Use a multi-stage build: the first stage has Go and OCB and produces the binary, and the final stage is a minimal image that receives only the binary. Match the processor architecture and keep names consistent.

Q9Is a custom Collector more secure?

It can be, because fewer components mean fewer places for flaws. But you must also track and ship security fixes yourself, so the benefit only holds if someone owns that work.

Q10How often should I rebuild?

On a regular schedule tied to upstream releases, and immediately when a serious security issue affects a component you use. Small, frequent upgrades are easier than large, rare ones.

Q11What are replacements and should I use them?

They let you substitute a different module or version for a component. They are useful for development and urgent fixes, but each one is a fork you own, so record why it exists and remove it when possible.

Q12How do I know the build contains what I intended?

Ask the binary to list its compiled-in components and compare them with the manifest, validate sample configurations against it, run a smoke test, and keep a bill of materials with each release.

46Summary and Key Takeaways

We began with a suitcase packed with everything and a small bag packed with only what the trip needs. The OpenTelemetry Collector Builder lets you choose the small bag. You list the receivers, processors, exporters, extensions and connectors you need in a manifest, pin their versions, and let OCB generate and compile a custom Collector. In return you get a smaller binary, a smaller attack surface, easier reviews, and the freedom to add your own components. In exchange you take on the work of keeping versions aligned, building in a pipeline, verifying every release, scanning for vulnerabilities and upgrading regularly. Done with discipline, a custom distribution is a precise, reviewable tool. Done carelessly, it becomes an unmaintained fork. The difference is not in the tool but in the habits around it.

Key Takeaways

  • OCB is a factory, not a Collector — it turns a manifest into a custom Collector binary and is not needed once the binary exists.
  • The manifest decides what exists — runtime configuration only chooses among components that were compiled in.
  • Choose by working backwards — include what real pipelines use, plus supporting components like memory protection and health checks.
  • Keep the family together — builder, core and components should share one release family, and upgrade together.
  • Automate and verify — build only in a pipeline from a version-controlled manifest, and gate releases on component listing, configuration validation and smoke tests.
  • Own the security work — pin versions, scan, keep a bill of materials and ship fixes on schedule, or prefer an official distribution.
  • Treat replacements as debt — every substitution is a fork you own, so document and remove it when possible.