🚀 OpenTelemetry Rednet Client for ComputerCraft

The ultimate telemetry toolkit for your ComputerCraft adventures! This module provides a lightweight, fire-and-forget OpenTelemetry client that sends metrics and logs over Rednet to a central collector. Perfect for monitoring your turtle fleets, tracking mining operations, or debugging complex automation systems! 🐢✨

  • 📊 Real-time Metrics: Counters, gauges, and histograms for all your measurement needs
  • 📝 Structured Logging: From debug traces to fatal errors, with rich attributes
  • 🌐 Rednet Integration: Native ComputerCraft networking - no HTTP required!
  • 🎯 Fire-and-Forget: No local batching, just instant transmission to your collector
  • 🏷️ Rich Metadata: Resource attributes, scopes, and custom tags for everything
  • 🔧 Instrument-Style API: Familiar OpenTelemetry patterns adapted for Lua/TypeScript
  • Turtle Fleet Management: Track mining progress, fuel levels, and inventory across hundreds of turtles
  • Factory Monitoring: Monitor production rates, resource flows, and machine health
  • Base Automation: Track power generation, storage levels, and system performance
  • Debugging Complex Systems: Rich logging with context to troubleshoot distributed automation
  • Performance Analysis: Histogram metrics for operation timing and resource usage
  • Alert Systems: Send critical logs and metrics for real-time monitoring
  • Rednet Required: Make sure you have a modem attached and rednet.open() called
  • Collector Dependency: You need a RednetCollector running somewhere to receive data
  • Network Overhead: Each metric/log is sent immediately - consider your network capacity
  • No Persistence: Data is fire-and-forget - if the collector is down, data is lost
import { RednetClient } from "@cc-ts/helpers/otel";

// Set up your client (collector ID 42 in this example)
const client = new RednetClient(
42, // Collector computer ID
"turtle-miner-001", // Service name
"2.1.0", // Service version
{ // Resource attributes
"turtle.type": "mining",
"location.x": 100,
"location.y": 64,
"location.z": 200
}
);

// Send some metrics
client.sendCounter("blocks_mined", "Blocks mined by turtle", "blocks", 1, {
"block.type": "minecraft:diamond_ore"
});

client.sendGauge("fuel_level", "Current fuel level", "units", turtle.getFuelLevel());

// Send logs with context
client.info("Started mining operation", {
"target.depth": 12,
"expected.duration": "30min"
});
import { RednetClient, RednetInstrumentClient } from "@cc-ts/helpers/otel";

const client = new RednetClient(42, "factory-controller");
const instruments = new RednetInstrumentClient(client);

// Create instruments once, use many times
const itemsProduced = instruments.createCounter(
"items_produced_total",
"Total items produced by factory",
"items"
);

const powerLevel = instruments.createGauge(
"power_level",
"Current power level in RF",
"RF"
);

// Use them in your production loop
while (factoryRunning) {
const produced = produceItems();
itemsProduced.add(produced, { "item.type": "iron_ingot" });

const currentPower = getPowerLevel();
powerLevel.set(currentPower);

if (currentPower < 1000) {
client.warn("Low power warning", { "power.level": currentPower });
}
}
// Track operation timing with histograms
const client = new RednetClient(42, "advanced-turtle");

async function timedMining() {
const startTime = os.epoch("utc");

// Do the mining work
const success = turtle.dig();

const duration = os.epoch("utc") - startTime;

// Send histogram data
client.sendHistogram(
"mining_duration",
"Time taken to mine a block",
"ms",
1, // count
duration, // sum
[ // bucket data
{ bound: 100, count: duration <= 100 ? 1 : 0 },
{ bound: 500, count: duration <= 500 ? 1 : 0 },
{ bound: 1000, count: duration <= 1000 ? 1 : 0 },
{ bound: 5000, count: 1 } // +Inf bucket
],
{ "success": success, "tool.type": "diamond_pickaxe" }
);
}
// Different services for different roles
const miningClient = new RednetClient(42, "mining-service", "1.0.0", {
"service.role": "mining",
"turtle.id": os.getComputerID()
});

const logisticsClient = new RednetClient(42, "logistics-service", "1.0.0", {
"service.role": "logistics",
"base.location": "main"
});

// Each service sends relevant metrics
miningClient.sendCounter("ore_found", "Ore blocks found", "blocks", 1);
logisticsClient.sendGauge("storage_utilization", "Storage usage", "percent", 85);

Classes

RednetClient
RednetCounter
RednetGauge
RednetInstrumentClient

Interfaces

RednetLog
RednetMetric

Type Aliases

RednetTelemetry

Functions

isRednetTelemetry