Getting Started
This walks through a collector that receives OTLP, batches it and sends traces to a tracing backend.
1. Install and register the lexicon
Section titled “1. Install and register the lexicon”npm install --save-dev @intentius/chant @intentius/chant-lexicon-otelimport type { ChantConfig } from "@intentius/chant";
export default { lexicons: ["otel"] } satisfies ChantConfig;2. Declare the components
Section titled “2. Declare the components”Each receiver, processor, exporter and extension is an entity. Config keys are the collector’s own, in snake_case, exactly as the collector docs spell them.
import { OtlpReceiver, MemoryLimiterProcessor, BatchProcessor, OtlpExporter, Pipeline } from "@intentius/chant-lexicon-otel";
const protocols = { grpc: { endpoint: "0.0.0.0:4317" } };const otlp = new OtlpReceiver({ protocols });const memoryLimiter = new MemoryLimiterProcessor({ check_interval: "1s", limit_percentage: 80 });const batch = new BatchProcessor({ timeout: "5s" });const tempo = new OtlpExporter({ name: "tempo", endpoint: "tempo.observability.svc:4317" });
const traces = new Pipeline({ signal: "traces", receivers: [otlp], processors: [memoryLimiter, batch], exporters: [tempo],});
export { otlp, memoryLimiter, batch, tempo, traces };name: "tempo" makes the exporter’s id otlp/tempo. Without a name the id is the bare type, otlp.
3. Build
Section titled “3. Build”npx chant build src --lexicon otel -o collector.yamlreceivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317
processors: batch: timeout: 5s memory_limiter: check_interval: 1s limit_percentage: 80
exporters: otlp/tempo: endpoint: tempo.observability.svc:4317
service: pipelines: traces: receivers: [otlp] processors: [memory_limiter, batch] exporters: [otlp/tempo]Run it with otelcol-contrib --config collector.yaml.
4. Lint
Section titled “4. Lint”chant lint src runs the source rules (OTEL001, OTEL002) and the post-synth checks, which chant build runs too. Remove memoryLimiter from the chain but leave it declared, and OTEL103 warns that it is declared and unused. Replace tempo with the string "otlp/tmepo" and OTEL101 fails the build, because no exporter has that id.
Starting from a template
Section titled “Starting from a template”chant init --lexicon otel scaffolds a project with a collector like the one above. Two templates start from a particular kind of collector instead, and each builds clean with the otel lexicon alone:
| Template | What it declares |
|---|---|
| (default) | OTLP in, memory_limiter and batch, traces to an OTLP backend and logs to debug, with health_check |
k8s-agent | A per-node Kubernetes agent from NodeAgent: OTLP, host metrics, container logs and kubelet stats, Kubernetes metadata on all of it, traces and logs on to a gateway, metrics served for Prometheus |
genai | The GenAI pipeline with the conventions’ client metrics derived, content removed and card-number-like values masked, traces to Tempo and metrics served for Prometheus |
npx chant init --lexicon otel --template k8s-agent- Components lists the built-in set and the rules each one checks.
- Custom components adds a component chant doesn’t ship.
- Composites declares a per-node agent with
NodeAgent, and runs a declared config on a platform.