Skip to content

Getting Started

This walks through a collector that receives OTLP, batches it and sends traces to a tracing backend.

Terminal window
npm install --save-dev @intentius/chant @intentius/chant-lexicon-otel
chant.config.ts
import type { ChantConfig } from "@intentius/chant";
export default { lexicons: ["otel"] } satisfies ChantConfig;

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.

src/collector.ts
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.

Terminal window
npx chant build src --lexicon otel -o collector.yaml
collector.yaml
receivers:
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.

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.

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:

TemplateWhat it declares
(default)OTLP in, memory_limiter and batch, traces to an OTLP backend and logs to debug, with health_check
k8s-agentA 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
genaiThe GenAI pipeline with the conventions’ client metrics derived, content removed and card-number-like values masked, traces to Tempo and metrics served for Prometheus
Terminal window
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.